added clang format C and H files.

This commit is contained in:
Steve Karg
2019-10-24 16:23:10 -05:00
parent da91a11454
commit 710173d6e0
205 changed files with 19377 additions and 25754 deletions
+50 -58
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2016 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2016 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service */
#include <stddef.h>
@@ -54,32 +54,26 @@ static bool Target_Server = true;
/* flag for signalling errors */
static bool Error_Detected = false;
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t abort_reason, bool server)
{
(void) src;
(void) invoke_id;
(void) server;
(void)src;
(void)invoke_id;
(void)server;
printf("BACnet Abort: %s\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t reject_reason)
{
(void) src;
(void) invoke_id;
(void)src;
(void)invoke_id;
printf("BACnet Reject: %s\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(
void)
static void Init_Service_Handlers(void)
{
Device_Init(NULL);
/* 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);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
@@ -101,8 +94,7 @@ static void Init_Service_Handlers(
static void print_usage(char *filename)
{
printf("Usage: %s [abort-reason [invoke-id [server]]]\n",
filename);
printf("Usage: %s [abort-reason [invoke-id [server]]]\n", filename);
printf(" [--dnet][--dadr][--mac]\n");
printf(" [--version][--help]\n");
}
@@ -110,7 +102,8 @@ static void print_usage(char *filename)
static void print_help(char *filename)
{
printf("Send BACnet Abort message to the network.\n");
printf("--mac A\n"
printf(
"--mac A\n"
"Optional destination BACnet mac address."
"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"
@@ -122,12 +115,14 @@ static void print_help(char *filename)
"and 65535 is network broadcast.\n"
"\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"
"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"
"\n");
printf("abort-reason:\n"
printf(
"abort-reason:\n"
" number from 0 to 65535\n"
"invoke-id:\n"
" number from 1 to 255\n"
@@ -138,14 +133,12 @@ static void print_help(char *filename)
filename);
}
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
long dnet = -1;
BACNET_MAC_ADDRESS mac = { 0 };
BACNET_MAC_ADDRESS adr = { 0 };
BACNET_ADDRESS dest = { 0 };
BACNET_MAC_ADDRESS mac = {0};
BACNET_MAC_ADDRESS adr = {0};
BACNET_ADDRESS dest = {0};
bool specific_address = false;
int argi = 0;
unsigned int target_args = 0;
@@ -160,8 +153,10 @@ int main(
}
if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2016 by Steve Karg and others.\n"
"This is free software; see the source for copying conditions.\n"
printf(
"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"
"FITNESS FOR A PARTICULAR PURPOSE.\n");
return 0;
@@ -239,11 +234,8 @@ int main(
dlenv_init();
atexit(datalink_cleanup);
/* send the request */
Send_Abort_To_Network(&Handler_Transmit_Buffer[0],
&dest,
Target_Invoke_ID,
Target_Abort_Reason,
Target_Server);
Send_Abort_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID,
Target_Abort_Reason, Target_Server);
return 0;
}
+66 -76
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool demo for BACnet stack */
#include <stddef.h>
@@ -53,7 +53,7 @@
#include "dlenv.h"
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
static uint8_t Rx_Buf[MAX_MPDU] = {0};
/* global variables used in this file */
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
@@ -65,57 +65,48 @@ static char *Communication_Password = NULL;
static bool Error_Detected = false;
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void)src;
(void)invoke_id;
printf("BACnet Error: %s: %s\n", bactext_error_class_name(error_class),
bactext_error_code_name(error_code));
Error_Detected = true;
}
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t abort_reason, bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
(void)src;
(void)invoke_id;
(void)server;
printf("BACnet Abort: %s\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void)src;
(void)invoke_id;
printf("BACnet Reject: %s\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
void MyDeviceCommunicationControlSimpleAckHandler(
BACNET_ADDRESS * src,
void MyDeviceCommunicationControlSimpleAckHandler(BACNET_ADDRESS *src,
uint8_t invoke_id)
{
(void) src;
(void) invoke_id;
(void)src;
(void)invoke_id;
printf("DeviceCommunicationControl Acknowledged!\n");
}
static void Init_Service_Handlers(
void)
static void Init_Service_Handlers(void)
{
Device_Init(NULL);
/* 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);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
@@ -134,8 +124,8 @@ static void Init_Service_Handlers(
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control);
/* handle the ack coming back */
apdu_set_confirmed_simple_ack_handler
(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
apdu_set_confirmed_simple_ack_handler(
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
MyDeviceCommunicationControlSimpleAckHandler);
/* handle any errors coming back */
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)
{
printf("Send BACnet DeviceCommunicationControl service to device.\n"
"\n" "The device-instance can be 0 to %lu.\n"
"Possible state values:\n" " 0=enable\n" " 1=disable\n"
printf(
"Send BACnet DeviceCommunicationControl service to device.\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"
"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"
"\nExample:\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);
}
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
BACNET_ADDRESS src = {
0
}; /* address where message came from */
BACNET_ADDRESS src = {0}; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
unsigned max_apdu = 0;
@@ -193,8 +184,10 @@ int main(
}
if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2014 by Steve Karg and others.\n"
"This is free software; see the source for copying conditions.\n"
printf(
"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"
"FITNESS FOR A PARTICULAR PURPOSE.\n");
return 0;
@@ -206,10 +199,10 @@ int main(
}
/* decode the command line parameters */
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
Communication_State = (uint16_t) strtol(argv[2], NULL, 0);
Communication_State = (uint16_t)strtol(argv[2], NULL, 0);
/* optional timeout, required if password is included */
if (argc > 3) {
Communication_Timeout_Minutes = (uint16_t) strtol(argv[3], NULL, 0);
Communication_Timeout_Minutes = (uint16_t)strtol(argv[3], NULL, 0);
}
/* optional password */
if (argc > 4) {
@@ -230,8 +223,7 @@ int main(
last_seconds = time(NULL);
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
if (!found) {
Send_WhoIs(Target_Device_Object_Instance,
@@ -251,21 +243,19 @@ int main(
}
/* at least one second has passed */
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;
/* wait until the device is bound, or timeout and quit */
if (!found) {
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
found = address_bind_request(Target_Device_Object_Instance,
&max_apdu, &Target_Address);
}
if (found) {
if (invoke_id == 0) {
invoke_id =
Send_Device_Communication_Control_Request
(Target_Device_Object_Instance,
invoke_id = Send_Device_Communication_Control_Request(
Target_Device_Object_Instance,
Communication_Timeout_Minutes, Communication_State,
Communication_Password);
} else if (tsm_invoke_id_free(invoke_id))
+170 -185
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/** @file epics/main.c Command line tool to build a full VTS3 EPICS file,
* including the heading information. */
@@ -58,7 +58,6 @@
#include "keylist.h"
#include "bacepics.h"
/* (Doxygen note: The next two lines pull all the following Javadoc
* into the BACEPICS module.) */
/** @addtogroup BACEPICS
@@ -72,7 +71,7 @@
*/
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
static uint8_t Rx_Buf[MAX_MPDU] = {0};
/* target information converted from command line */
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
@@ -139,11 +138,9 @@ static struct property_value_list_t Property_Value_List[] = {
{PROP_PROTOCOL_SERVICES_SUPPORTED, NULL},
{PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, NULL},
{PROP_DESCRIPTION, NULL},
{-1, NULL}
};
{-1, NULL}};
static BACNET_APPLICATION_DATA_VALUE *object_property_value(
int32_t property_id)
static BACNET_APPLICATION_DATA_VALUE *object_property_value(int32_t property_id)
{
BACNET_APPLICATION_DATA_VALUE *value = NULL;
int32_t index = 0;
@@ -180,9 +177,7 @@ static bool Optional_Properties = false;
#define PRINT_ERRORS 1
#endif
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
@@ -201,13 +196,10 @@ static void MyErrorHandler(
}
}
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t abort_reason, bool server)
{
(void) server;
(void)server;
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
#if PRINT_ERRORS
@@ -227,9 +219,7 @@ void MyAbortHandler(
}
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t reject_reason)
{
if (address_match(&Target_Address, src) &&
@@ -250,11 +240,9 @@ void MyRejectHandler(
}
}
void MyReadPropertyAckHandler(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
void MyReadPropertyAckHandler(uint8_t *service_request, uint16_t service_len,
BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{
int len = 0;
BACNET_READ_ACCESS_DATA *rp_data;
@@ -263,8 +251,7 @@ void MyReadPropertyAckHandler(
(service_data->invoke_id == Request_Invoke_ID)) {
rp_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
if (rp_data) {
len =
rp_ack_fully_decode_service_request(service_request,
len = rp_ack_fully_decode_service_request(service_request,
service_len, rp_data);
}
if (len > 0) {
@@ -281,10 +268,8 @@ void MyReadPropertyAckHandler(
}
void MyReadPropertyMultipleAckHandler(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{
int len = 0;
BACNET_READ_ACCESS_DATA *rpm_data;
@@ -293,8 +278,7 @@ void MyReadPropertyMultipleAckHandler(
(service_data->invoke_id == Request_Invoke_ID)) {
rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
if (rpm_data) {
len =
rpm_ack_decode_service_request(service_request, service_len,
len = rpm_ack_decode_service_request(service_request, service_len,
rpm_data);
}
if (len > 0) {
@@ -311,8 +295,7 @@ void MyReadPropertyMultipleAckHandler(
}
}
static void Init_Service_Handlers(
void)
static void Init_Service_Handlers(void)
{
Device_Init(NULL);
@@ -332,8 +315,7 @@ static void Init_Service_Handlers(
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_bind);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
@@ -348,7 +330,6 @@ static void Init_Service_Handlers(
apdu_set_reject_handler(MyRejectHandler);
}
/** Determine if this is a writable property, and, if so,
* note that in the EPICS output.
* This function may need a lot of customization for different implementations.
@@ -358,10 +339,9 @@ static void Init_Service_Handlers(
* @param rpm_property [in] Points to structure holding the Property,
* Value, and Error information.
*/
void CheckIsWritableProperty(
BACNET_OBJECT_TYPE object_type,
void CheckIsWritableProperty(BACNET_OBJECT_TYPE object_type,
/* uint32_t object_instance, */
BACNET_PROPERTY_REFERENCE * rpm_property)
BACNET_PROPERTY_REFERENCE *rpm_property)
{
bool bIsWritable = false;
if ((object_type == OBJECT_ANALOG_OUTPUT) ||
@@ -439,9 +419,7 @@ void CheckIsWritableProperty(
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;
size_t text_index = 0;
@@ -475,9 +453,8 @@ static const char *protocol_services_supported_text(
* @return True if success. Or otherwise.
*/
bool PrettyPrintPropertyValue(
FILE * stream,
BACNET_OBJECT_PROPERTY_VALUE * object_value)
bool PrettyPrintPropertyValue(FILE *stream,
BACNET_OBJECT_PROPERTY_VALUE *object_value)
{
BACNET_APPLICATION_DATA_VALUE *value = NULL;
bool status = true; /*return value */
@@ -493,18 +470,20 @@ bool PrettyPrintPropertyValue(
len = bitstring_bits_used(&value->type.Bit_String);
fprintf(stream, "( \n ");
for (i = 0; i < len; i++) {
fprintf(stream, "%s", bitstring_bit(&value->type.Bit_String,
(uint8_t) i) ? "T" : "F");
fprintf(
stream, "%s",
bitstring_bit(&value->type.Bit_String, (uint8_t)i) ? "T" : "F");
if (i < len - 1)
fprintf(stream, ",");
else
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 */
fprintf(stream, " -- "); /* EPICS comments begin with "--" */
/* Now rerun the same 4 bits, but print labels for true ones */
for (j = i - (i % 4); j <= i; j++) {
if (bitstring_bit(&value->type.Bit_String, (uint8_t) j)) {
if (bitstring_bit(&value->type.Bit_String, (uint8_t)j)) {
if (property == PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED) {
fprintf(stream, " %s,",
bactext_object_type_name(j));
@@ -526,9 +505,9 @@ bool PrettyPrintPropertyValue(
* clearer, international form. */
strncpy(short_month, bactext_month_name(value->type.Date.month), 3);
short_month[3] = 0;
fprintf(stream, "(%u-%3s-%u, %u)", (unsigned) value->type.Date.day,
short_month, (unsigned) value->type.Date.year,
(unsigned) value->type.Date.wday);
fprintf(stream, "(%u-%3s-%u, %u)", (unsigned)value->type.Date.day,
short_month, (unsigned)value->type.Date.year,
(unsigned)value->type.Date.wday);
} else if (value != NULL) {
assert(false); /* How did I get here? Fix your code. */
/* Meanwhile, a fallback plan */
@@ -539,7 +518,6 @@ bool PrettyPrintPropertyValue(
return status;
}
/** Print out the value(s) for one Property.
* 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
@@ -550,10 +528,9 @@ bool PrettyPrintPropertyValue(
* @param rpm_property [in] Points to structure holding the Property,
* Value, and Error information.
*/
void PrintReadPropertyData(
BACNET_OBJECT_TYPE object_type,
void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_PROPERTY_REFERENCE * rpm_property)
BACNET_PROPERTY_REFERENCE *rpm_property)
{
BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
BACNET_APPLICATION_DATA_VALUE *value, *old_value;
@@ -569,15 +546,16 @@ void PrintReadPropertyData(
if (value == NULL) {
/* Then we print the error information */
fprintf(stdout, "? -- BACnet Error: %s: %s\n",
bactext_error_class_name((int) rpm_property->error.error_class),
bactext_error_code_name((int) rpm_property->error.error_code));
bactext_error_class_name((int)rpm_property->error.error_class),
bactext_error_code_name((int)rpm_property->error.error_code));
return;
}
object_value.object_type = object_type;
object_value.object_instance = object_instance;
if ((value != NULL) && (value->next != NULL)) {
/* 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) {
/* Screen the Properties that can be arrays or Sequences */
case PROP_PRESENT_VALUE:
@@ -620,25 +598,28 @@ void PrintReadPropertyData(
if (Using_Walked_List) {
if ((rpm_property->propertyArrayIndex == 0) &&
(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;
if (rpm_property->propertyIdentifier ==
PROP_OBJECT_LIST)
Object_List_Length = value->type.Unsigned_Int;
break;
} else
assert(Walked_List_Index == (uint32_t)
rpm_property->propertyArrayIndex);
assert(Walked_List_Index ==
(uint32_t)rpm_property->propertyArrayIndex);
} else {
Walked_List_Index++;
/* If we got the whole Object List array in one RP call, keep
* the Index and List_Length in sync as we cycle through. */
/* If we got the whole Object List array in one RP call,
* keep the Index and List_Length in sync as we cycle
* through. */
if (rpm_property->propertyIdentifier == PROP_OBJECT_LIST)
Object_List_Length = ++Object_List_Index;
}
if (Walked_List_Index == 1) {
/* 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) {
fprintf(stdout, "?\n ");
break;
@@ -655,7 +636,10 @@ void PrintReadPropertyData(
if (rpm_property->propertyIdentifier == PROP_OBJECT_LIST) {
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;
}
/* 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
* yet, so just leave it null. The key is Key here. */
Keylist_Data_Add(Object_List, object_list_element, NULL);
} else if (rpm_property->propertyIdentifier == PROP_STATE_TEXT) {
/* Make sure it fits within 31 chars for original VTS3 limitation.
* If longer, take first 15 dash, and last 15 chars. */
} else if (rpm_property->propertyIdentifier ==
PROP_STATE_TEXT) {
/* 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) {
int iLast15idx =
value->type.Character_String.length - 15;
@@ -682,14 +668,18 @@ void PrintReadPropertyData(
} else if (rpm_property->propertyIdentifier ==
PROP_SUBORDINATE_LIST) {
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;
}
/* TODO: handle Sequence of { Device ObjID, Object ID }, */
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)
fprintf(stdout, "{");
bacapp_print_value(stdout, &object_value);
@@ -773,15 +763,13 @@ void PrintReadPropertyData(
value = value->next; /* next or NULL */
free(old_value);
} /* End while loop */
}
/** Print the property identifier name to stdout,
* handling the proprietary property numbers.
* @param propertyIdentifier [in] The property identifier number.
*/
static void Print_Property_Identifier(
unsigned propertyIdentifier)
static void Print_Property_Identifier(unsigned propertyIdentifier)
{
if (propertyIdentifier < 512) {
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. */
static void BuildPropRequest(
BACNET_READ_ACCESS_DATA * rpm_object)
static void BuildPropRequest(BACNET_READ_ACCESS_DATA *rpm_object)
{
int i;
/* To start with, StartNextObject() has prepopulated one propEntry,
@@ -824,9 +811,8 @@ static void BuildPropRequest(
* @return The invokeID of the message sent, or 0 if reached the end
* of the property list.
*/
static uint8_t Read_Properties(
uint32_t device_instance,
BACNET_OBJECT_ID * pMyObject)
static uint8_t Read_Properties(uint32_t device_instance,
BACNET_OBJECT_ID *pMyObject)
{
uint8_t invoke_id = 0;
struct special_property_list_t PropertyListStruct;
@@ -841,8 +827,7 @@ static uint8_t Read_Properties(
*/
property_list_special(pMyObject->type, &PropertyListStruct);
if (Optional_Properties) {
Property_List_Length =
PropertyListStruct.Required.count +
Property_List_Length = PropertyListStruct.Required.count +
PropertyListStruct.Optional.count;
} else {
Property_List_Length = PropertyListStruct.Required.count;
@@ -879,7 +864,8 @@ static uint8_t Read_Properties(
array_index = BACNET_ARRAY_ALL;
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_STATE_TEXT:
case PROP_STRUCTURED_OBJECT_LIST:
@@ -892,7 +878,6 @@ static uint8_t Read_Properties(
invoke_id =
Send_Read_Property_Request(device_instance, pMyObject->type,
pMyObject->instance, prop, array_index);
}
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
* singly process the list of Properties.
*/
EPICS_STATES ProcessRPMData(
BACNET_READ_ACCESS_DATA * rpm_data,
EPICS_STATES ProcessRPMData(BACNET_READ_ACCESS_DATA *rpm_data,
EPICS_STATES myState)
{
BACNET_READ_ACCESS_DATA *old_rpm_data;
@@ -1003,15 +987,18 @@ EPICS_STATES ProcessRPMData(
static void print_usage(char *filename)
{
printf("Usage: %s [-v] [-d] [-p sport] [-t target_mac [-n dnet]]"
" device-instance\n", filename);
printf(
"Usage: %s [-v] [-d] [-p sport] [-t target_mac [-n dnet]]"
" device-instance\n",
filename);
printf(" [--version][--help]\n");
}
static void print_help(char *filename)
{
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"
"trying to communicate to. This number will be used\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");
}
int CheckCommandLineArgs(
int argc,
char *argv[])
int CheckCommandLineArgs(int argc, char *argv[])
{
int i;
bool bFoundTarget = false;
@@ -1049,8 +1034,10 @@ int CheckCommandLineArgs(
}
if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2014 by Steve Karg and others.\n"
"This is free software; see the source for copying conditions.\n"
printf(
"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"
"FITNESS FOR A PARTICULAR PURPOSE.\n");
exit(0);
@@ -1076,7 +1063,7 @@ int CheckCommandLineArgs(
case 'p':
if (++i < argc) {
#if defined(BACDL_BIP)
My_BIP_Port = (uint16_t) strtol(argv[i], NULL, 0);
My_BIP_Port = (uint16_t)strtol(argv[i], NULL, 0);
/* Used strtol so sport can be either 0xBAC0 or 47808 */
#endif
}
@@ -1087,8 +1074,7 @@ int CheckCommandLineArgs(
fprintf(stderr,
"Must provide a Target MAC before DNET \n");
if (++i < argc)
Target_Address.net =
(uint16_t) strtol(argv[i], NULL, 0);
Target_Address.net = (uint16_t)strtol(argv[i], NULL, 0);
/* Used strtol so dest.net can be either 0x1234 or 4660 */
break;
case 't':
@@ -1105,15 +1091,14 @@ int CheckCommandLineArgs(
if (count == 6) { /* success */
Target_Address.mac_len = count;
for (j = 0; j < 6; j++) {
Target_Address.mac[j] = (uint8_t) mac[j];
Target_Address.mac[j] = (uint8_t)mac[j];
}
Target_Address.net = 0;
Target_Address.len = 0; /* No src address */
Provided_Targ_MAC = true;
break;
} else
printf("ERROR: invalid Target MAC %s \n",
argv[i]);
printf("ERROR: invalid Target MAC %s \n", argv[i]);
/* And fall through to print_usage */
}
/* Either break or fall through, as above */
@@ -1145,8 +1130,7 @@ int CheckCommandLineArgs(
return 0; /* All OK if we reach here */
}
void PrintHeading(
)
void PrintHeading()
{
BACNET_APPLICATION_DATA_VALUE *value = NULL;
BACNET_OBJECT_PROPERTY_VALUE property_value;
@@ -1187,7 +1171,8 @@ void PrintHeading(
printf("Product Description: \"%s\"\n\n",
characterstring_value(&value->type.Character_String));
} else {
printf("Product Description: "
printf(
"Product Description: "
"\"your product description here\"\n\n");
}
printf("BIBBs Supported:\n");
@@ -1217,14 +1202,14 @@ void PrintHeading(
printf("BACnet Standard Application Services Supported:\n");
printf("{\n");
value = object_property_value(PROP_PROTOCOL_SERVICES_SUPPORTED);
/* We have to process this bit string and determine which Object Types we have,
* and show them
/* We have to process this bit string and determine which Object Types we
* have, and show them
*/
if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING)) {
int i, len = bitstring_bits_used(&value->type.Bit_String);
printf("-- services reported by this device\n");
for (i = 0; i < len; i++) {
if (bitstring_bit(&value->type.Bit_String, (uint8_t) i))
if (bitstring_bit(&value->type.Bit_String, (uint8_t)i))
printf(" %s\n", protocol_services_supported_text(i));
}
} else {
@@ -1251,8 +1236,7 @@ void PrintHeading(
printf("-- SubscribeCOVProperty Initiate Execute\n");
#ifdef BAC_ROUTING
if (Target_Address.net == 0) {
printf
("-- Note: The following Routing Services are Supported:\n");
printf("-- Note: The following Routing Services are Supported:\n");
printf("-- Who-Is-Router-To-Network Initiate Execute\n");
printf("-- I-Am-Router-To-Network Initiate Execute\n");
printf("-- Initialize-Routing-Table Execute\n");
@@ -1265,14 +1249,14 @@ void PrintHeading(
printf("Standard Object-Types Supported:\n");
printf("{\n");
value = object_property_value(PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED);
/* We have to process this bit string and determine which Object Types we have,
* and show them
/* We have to process this bit string and determine which Object Types we
* have, and show them
*/
if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING)) {
int i, len = bitstring_bits_used(&value->type.Bit_String);
printf("-- objects reported by this device\n");
for (i = 0; i < len; i++) {
if (bitstring_bit(&value->type.Bit_String, (uint8_t) i))
if (bitstring_bit(&value->type.Bit_String, (uint8_t)i))
printf(" %s\n", bactext_object_type_name(i));
}
} else {
@@ -1360,8 +1344,12 @@ void PrintHeading(
printf("{\n");
printf(" unsigned-integer: <minimum: 0; maximum: 4294967295>\n");
printf(" signed-integer: <minimum: -2147483647; maximum: 2147483647>\n");
printf(" 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(
" 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(" octet-string: <maximum length string: 122>\n");
printf(" character-string: <maximum length string: 122>\n");
@@ -1389,11 +1377,9 @@ void Print_Device_Heading(void)
printf(" {\n"); /* And opening brace for the first object */
}
/* Initialize fields for a new Object */
void StartNextObject(
BACNET_READ_ACCESS_DATA * rpm_object,
BACNET_OBJECT_ID * pNewObject)
void StartNextObject(BACNET_READ_ACCESS_DATA *rpm_object,
BACNET_OBJECT_ID *pNewObject)
{
BACNET_PROPERTY_REFERENCE *rpm_property;
Error_Detected = false;
@@ -1417,12 +1403,11 @@ void StartNextObject(
*
*
* @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.
*/
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
BACNET_ADDRESS src; /* address where message came from */
uint16_t pdu_len = 0;
@@ -1434,7 +1419,7 @@ int main(
time_t timeout_seconds = 0;
bool found = false;
BACNET_OBJECT_ID myObject;
uint8_t buffer[MAX_PDU] = { 0 };
uint8_t buffer[MAX_PDU] = {0};
BACNET_READ_ACCESS_DATA *rpm_object = NULL;
KEY nextKey;
@@ -1468,8 +1453,7 @@ int main(
}
#endif
/* try to bind with the target device */
found =
address_bind_request(Target_Device_Object_Instance, &max_apdu,
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
if (!found) {
if (Provided_Targ_MAC) {
@@ -1501,24 +1485,22 @@ int main(
current_seconds = time(NULL);
/* Has at least one second passed ? */
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));
}
/* OK to proceed; see what we are up to now */
switch (myState) {
case INITIAL_BINDING:
/* returns 0 bytes on timeout */
pdu_len =
datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process; normally is some initial error */
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
/* will wait until the device is bound, or timeout and quit */
found =
address_bind_request(Target_Device_Object_Instance,
found = address_bind_request(Target_Device_Object_Instance,
&max_apdu, &Target_Address);
if (!found) {
/* increment timer - exit if timed out */
@@ -1528,7 +1510,7 @@ int main(
"\rError: Unable to bind to %u"
" after waiting %ld seconds.\n",
Target_Device_Object_Instance,
(long int) elapsed_seconds);
(long int)elapsed_seconds);
break;
}
/* else, loop back and try again */
@@ -1545,9 +1527,8 @@ int main(
last_seconds = current_seconds;
StartNextObject(rpm_object, &myObject);
BuildPropRequest(rpm_object);
Request_Invoke_ID =
Send_Read_Property_Multiple_Request(buffer, MAX_PDU,
Target_Device_Object_Instance, rpm_object);
Request_Invoke_ID = Send_Read_Property_Multiple_Request(
buffer, MAX_PDU, Target_Device_Object_Instance, rpm_object);
if (Request_Invoke_ID > 0) {
elapsed_seconds = 0;
} else {
@@ -1575,9 +1556,8 @@ int main(
last_seconds = current_seconds;
StartNextObject(rpm_object, &myObject);
Request_Invoke_ID =
Send_Read_Property_Multiple_Request(buffer, MAX_PDU,
Target_Device_Object_Instance, rpm_object);
Request_Invoke_ID = Send_Read_Property_Multiple_Request(
buffer, MAX_PDU, Target_Device_Object_Instance, rpm_object);
if (Request_Invoke_ID > 0) {
elapsed_seconds = 0;
if (myState == GET_LIST_OF_ALL_REQUEST)
@@ -1591,8 +1571,7 @@ int main(
case GET_ALL_RESPONSE:
case GET_LIST_OF_ALL_RESPONSE:
/* returns 0 bytes on timeout */
pdu_len =
datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */
if (pdu_len) {
@@ -1603,9 +1582,8 @@ int main(
(Request_Invoke_ID ==
Read_Property_Multiple_Data.service_data.invoke_id)) {
Read_Property_Multiple_Data.new_data = false;
myState =
ProcessRPMData(Read_Property_Multiple_Data.rpm_data,
myState);
myState = ProcessRPMData(
Read_Property_Multiple_Data.rpm_data, myState);
if (tsm_invoke_id_free(Request_Invoke_ID)) {
Request_Invoke_ID = 0;
} else {
@@ -1626,7 +1604,8 @@ int main(
/* Was it because the Device can't do RPM? */
Has_RPM = false;
myState = GET_PROPERTY_REQUEST;
} else if (Last_Error_Code ==
} else if (
Last_Error_Code ==
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED) {
myState = GET_PROPERTY_REQUEST;
StartNextObject(rpm_object, &myObject);
@@ -1660,7 +1639,8 @@ int main(
myState = PRINT_HEADING;
/* just press ahead without the data */
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++;
}
break;
@@ -1683,8 +1663,7 @@ int main(
case GET_PROPERTY_RESPONSE:
/* returns 0 bytes on timeout */
pdu_len =
datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */
if (pdu_len) {
@@ -1695,11 +1674,10 @@ int main(
(Request_Invoke_ID ==
Read_Property_Multiple_Data.service_data.invoke_id)) {
Read_Property_Multiple_Data.new_data = false;
PrintReadPropertyData(Read_Property_Multiple_Data.
rpm_data->object_type,
PrintReadPropertyData(
Read_Property_Multiple_Data.rpm_data->object_type,
Read_Property_Multiple_Data.rpm_data->object_instance,
Read_Property_Multiple_Data.rpm_data->
listOfProperties);
Read_Property_Multiple_Data.rpm_data->listOfProperties);
if (tsm_invoke_id_free(Request_Invoke_ID)) {
Request_Invoke_ID = 0;
} else {
@@ -1727,14 +1705,16 @@ int main(
if ((Last_Error_Class != ERROR_CLASS_PROPERTY) &&
(Last_Error_Code != ERROR_CODE_UNKNOWN_PROPERTY)) {
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;
Walked_List_Index = Walked_List_Length = 0;
} else {
/* OK, skip this one and try the next property. */
/* OK, skip this one and try the next property.
*/
fprintf(stdout, " -- Failed to get ");
Print_Property_Identifier(Property_List
[Property_List_Index]);
Print_Property_Identifier(
Property_List[Property_List_Index]);
fprintf(stdout, " \n");
Error_Count++;
Property_List_Index++;
@@ -1764,7 +1744,8 @@ int main(
/* Don't think we'll ever actually reach this point. */
elapsed_seconds = 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++;
}
break;
@@ -1777,12 +1758,14 @@ int main(
if (ShowDeviceObjectOnly) {
/* Closing brace for the Device Object */
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;
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 {
Object_List_Index++;
if (Object_List_Index < Keylist_Count(Object_List)) {
@@ -1798,12 +1781,14 @@ int main(
printf(" { \n");
/* Test code:
if ( myObject.type == OBJECT_STRUCTURED_VIEW )
printf( " -- Structured View %d \n", myObject.instance );
printf( " -- Structured View %d \n",
myObject.instance );
*/
} else {
/* Closing brace for the last Object */
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;
}
if (Has_RPM)
@@ -1814,7 +1799,8 @@ int main(
}
} 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;
default:
@@ -1828,7 +1814,7 @@ int main(
elapsed_seconds += (current_seconds - last_seconds);
if (elapsed_seconds > timeout_seconds) {
fprintf(stderr, "\rError: APDU Timeout! (%lds)\n",
(long int) elapsed_seconds);
(long int)elapsed_seconds);
break;
}
}
@@ -1841,8 +1827,7 @@ int main(
/* Closing brace for all Objects, if we got any, and closing footer */
if (myState != INITIAL_BINDING) {
printf("} \n");
printf
("End of BACnet Protocol Implementation Conformance Statement\n");
printf("End of BACnet Protocol Implementation Conformance Statement\n");
printf("\n");
}
+49 -56
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2016 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2016 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service */
#include <stddef.h>
@@ -55,32 +55,26 @@ static uint16_t Target_Service = SERVICE_CONFIRMED_READ_PROPERTY;
/* flag for signalling errors */
static bool Error_Detected = false;
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t abort_reason, bool server)
{
(void) src;
(void) invoke_id;
(void) server;
(void)src;
(void)invoke_id;
(void)server;
printf("BACnet Abort: %s\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t reject_reason)
{
(void) src;
(void) invoke_id;
(void)src;
(void)invoke_id;
printf("BACnet Reject: %s\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(
void)
static void Init_Service_Handlers(void)
{
Device_Init(NULL);
/* 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);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
@@ -111,7 +104,8 @@ static void print_usage(char *filename)
static void print_help(char *filename)
{
printf("Send BACnet Error message to the network.\n");
printf("--mac A\n"
printf(
"--mac A\n"
"Optional destination BACnet mac address."
"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"
@@ -123,12 +117,14 @@ static void print_help(char *filename)
"and 65535 is network broadcast.\n"
"\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"
"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"
"\n");
printf("error-class:\n"
printf(
"error-class:\n"
" number from 0 to 65535\n"
"error-code:\n"
" number from 0 to 65535\n"
@@ -141,14 +137,12 @@ static void print_help(char *filename)
filename);
}
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
long dnet = -1;
BACNET_MAC_ADDRESS mac = { 0 };
BACNET_MAC_ADDRESS adr = { 0 };
BACNET_ADDRESS dest = { 0 };
BACNET_MAC_ADDRESS mac = {0};
BACNET_MAC_ADDRESS adr = {0};
BACNET_ADDRESS dest = {0};
bool specific_address = false;
int argi = 0;
unsigned int target_args = 0;
@@ -163,8 +157,10 @@ int main(
}
if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2016 by Steve Karg and others.\n"
"This is free software; see the source for copying conditions.\n"
printf(
"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"
"FITNESS FOR A PARTICULAR PURPOSE.\n");
return 0;
@@ -245,11 +241,8 @@ int main(
dlenv_init();
atexit(datalink_cleanup);
/* send the request */
Send_Error_To_Network(&Handler_Transmit_Buffer[0],
&dest,
Target_Invoke_ID,
Target_Service,
Target_Error_Class,
Send_Error_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID,
Target_Service, Target_Error_Class,
Target_Error_Code);
return 0;
+40 -50
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/**
* Code for this project began with code from the demo/server project and
* Paul Chapman's vmac project.
@@ -60,7 +60,8 @@
#include "vmac.h"
#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 */
@@ -70,7 +71,7 @@
/*@{*/
/** Buffer used for receiving */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
static uint8_t Rx_Buf[MAX_MPDU] = {0};
/** The list of DNETs that our router can reach.
* Only one entry since we don't support downstream routers.
@@ -79,14 +80,11 @@ int DNET_list[2] = {
VIRTUAL_DNET, -1 /* Need -1 terminator */
};
/** Initialize the Device Objects and each of the child Object instances.
* @param first_object_instance Set the first (gateway) Device to this
instance number, and subsequent devices to incremented values.
*/
static void Devices_Init(
uint32_t first_object_instance)
static void Devices_Init(uint32_t first_object_instance)
{
int i;
char nameText[MAX_DEV_NAME_LEN];
@@ -95,8 +93,7 @@ static void Devices_Init(
/* Gateway Device has already been initialized.
* But give it a better Description. */
Routed_Device_Set_Description(DEV_DESCR_GATEWAY,
strlen(DEV_DESCR_GATEWAY));
Routed_Device_Set_Description(DEV_DESCR_GATEWAY, strlen(DEV_DESCR_GATEWAY));
/* Now initialize the remote Device objects. */
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);
}
}
/** Initialize the handlers we will utilize.
* @see Device_Init, apdu_set_unconfirmed_handler, apdu_set_confirmed_handler
*/
static void Init_Service_Handlers(
uint32_t first_object_instance)
static void Init_Service_Handlers(uint32_t first_object_instance)
{
Device_Init(NULL);
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);
/* set the handler for all the services we don't implement */
/* It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
/* Set the handlers for any confirmed services that we support. */
/* We must implement read property - it's required! */
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.
* - 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 */
uint32_t virtual_mac = 0;
@@ -209,7 +201,7 @@ static void Initialize_Device_Addresses(
continue;
#if defined(BACDL_BIP)
virtual_mac = i;
netPtr = (struct in_addr *) pDev->bacDevAddr.mac;
netPtr = (struct in_addr *)pDev->bacDevAddr.mac;
#if (MAX_NUM_DEVICES > 0xFFFFFF)
pDev->bacDevAddr.mac[0] = ((virtual_mac & 0xff000000) >> 24);
#else
@@ -239,7 +231,6 @@ static void Initialize_Device_Addresses(
#endif
/* broadcast an I-Am for each routed Device now */
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 #.
* @return 0 on success.
*/
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
BACNET_ADDRESS src = {
0
}; /* address where message came from */
BACNET_ADDRESS src = {0}; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 1000; /* milliseconds */
time_t last_seconds = 0;
@@ -286,9 +273,12 @@ int main(
exit(1);
}
}
printf("BACnet Router Demo\n" "BACnet Stack Version %s\n"
"BACnet Device ID: %u\n" "Max APDU: %d\n", BACnet_Version,
first_object_instance, MAX_APDU);
printf(
"BACnet Router Demo\n"
"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);
dlenv_init();
atexit(datalink_cleanup);
+67 -66
View File
@@ -1,26 +1,26 @@
/*************************************************************************
* Copyright (C) 2015 B Weitsch
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
* Copyright (C) 2015 B Weitsch
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
@@ -73,45 +73,38 @@ static bool Recieved_Ack = false;
static bool More_Events = false;
static BACNET_OBJECT_ID LastReceivedObjectIdentifier;
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\r\n",
bactext_error_class_name((int) error_class),
bactext_error_code_name((int) error_code));
bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code));
Error_Detected = true;
}
}
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t abort_reason, bool server)
{
(void) server;
(void)server;
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Abort: %s\r\n",
bactext_abort_reason_name((int) abort_reason));
bactext_abort_reason_name((int)abort_reason));
Error_Detected = true;
}
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t reject_reason)
{
if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\r\n",
bactext_reject_reason_name((int) reject_reason));
bactext_reject_reason_name((int)reject_reason));
Error_Detected = true;
}
}
@@ -126,31 +119,30 @@ void MyRejectHandler(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message.
*/
void My_Get_Event_Ack_Handler(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
void My_Get_Event_Ack_Handler(uint8_t *service_request, uint16_t service_len,
BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{
int len = 0;
int i;
BACNET_GET_EVENT_INFORMATION_DATA data[MAX_OBJ_IDS_IN_GE_ACK];
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) {
len = getevent_ack_decode_service_request(service_request,
service_len,
&data[0],
&More_Events);
printf("Decode of Ack returned length %i. MoreEvents flag was %i \n", len, More_Events);
len = getevent_ack_decode_service_request(service_request, service_len,
&data[0], &More_Events);
printf("Decode of Ack returned length %i. MoreEvents flag was %i \n",
len, More_Events);
if (len > 0) {
ge_ack_print_data(&(data[0]), Target_Device_Object_Instance);
if (More_Events) {
BACNET_GET_EVENT_INFORMATION_DATA * lastData = &(data[0]);
while (lastData->next) lastData = lastData->next;
BACNET_GET_EVENT_INFORMATION_DATA *lastData = &(data[0]);
while (lastData->next)
lastData = lastData->next;
LastReceivedObjectIdentifier = lastData->objectIdentifier;
}
}
@@ -181,10 +173,17 @@ static void Init_Service_Handlers(void)
apdu_set_reject_handler(MyRejectHandler);
}
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"
" for responses.\n\n", 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"
" for responses.\n\n",
exe_name);
return 1;
}
@@ -205,7 +204,7 @@ int main(int argc, char *argv[])
if (argc <= 1) {
printf("Usage: %s device-instance\r\n", filename_remove_path(argv[0]));
return 0;
} else if(strcmp(argv[1], "--help") == 0) {
} else if (strcmp(argv[1], "--help") == 0) {
print_help(filename_remove_path(argv[0]));
return 0;
}
@@ -221,11 +220,11 @@ int main(int argc, char *argv[])
last_seconds = time(NULL);
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */
found = address_bind_request(Target_Device_Object_Instance,
&max_apdu,
found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address);
if (!found) {
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
}
/* loop forever */
for (;;) {
@@ -234,14 +233,16 @@ int main(int argc, char *argv[])
/* at least one second has passed */
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 */
if (!found) {
found = address_bind_request(Target_Device_Object_Instance,
&max_apdu,
&Target_Address);
&max_apdu, &Target_Address);
}
if (found) {
if (Request_Invoke_ID == 0) {
@@ -249,8 +250,8 @@ int main(int argc, char *argv[])
Request_Invoke_ID = Send_GetEvent(&Target_Address, NULL);
} else if (More_Events) {
printf("\nSending another GetEventInformation request ...\n");
Request_Invoke_ID = Send_GetEvent(&Target_Address,
&LastReceivedObjectIdentifier);
Request_Invoke_ID = Send_GetEvent(
&Target_Address, &LastReceivedObjectIdentifier);
More_Events = false;
} else if (tsm_invoke_id_free(Request_Invoke_ID)) {
if (Recieved_Ack) {
+52 -62
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* environment variables used for the command line tools */
#include <stddef.h>
@@ -52,7 +52,6 @@ static long bbmd_mask = 0xFFFFFFFF;
static int bbmd_result = 0;
static BBMD_TABLE_ENTRY BBMD_Table_Entry;
/* Simple setters for BBMD registration variables. */
/** 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,
* in network byte order.
*/
void dlenv_bbmd_address_set(
long address)
void dlenv_bbmd_address_set(long address)
{
bbmd_address = address;
}
@@ -71,8 +69,7 @@ void dlenv_bbmd_address_set(
* Default if not set is 0xBAC0.
* @param port - The port number (provided in network byte order).
*/
void dlenv_bbmd_port_set(
int port)
void dlenv_bbmd_port_set(int port)
{
bbmd_port = port;
}
@@ -81,8 +78,7 @@ void dlenv_bbmd_port_set(
* Default if not set is 60000 (1000 minutes).
* @param ttl_secs - The Lease Time, in seconds.
*/
void dlenv_bbmd_ttl_set(
int ttl_secs)
void dlenv_bbmd_ttl_set(int ttl_secs)
{
bbmd_timetolive_seconds = ttl_secs;
}
@@ -95,8 +91,7 @@ void dlenv_bbmd_ttl_set(
* 0 if no registration request was made, or
* -1 if registration attempt failed.
*/
int dlenv_bbmd_result(
void)
int dlenv_bbmd_result(void)
{
if ((bbmd_result > 0) &&
(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
* -1 if registration fails.
*/
int dlenv_register_as_foreign_device(
void)
int dlenv_register_as_foreign_device(void)
{
int retval = 0;
#if defined(BACDL_BIP)
@@ -155,15 +149,15 @@ int dlenv_register_as_foreign_device(
fprintf(stderr, "Registering with BBMD at %s:%ld for %ld seconds\n",
inet_ntoa(addr), bbmd_port, bbmd_timetolive_seconds);
retval =
bvlc_register_with_bbmd(bbmd_address, htons((uint16_t) bbmd_port),
(uint16_t) bbmd_timetolive_seconds);
bvlc_register_with_bbmd(bbmd_address, htons((uint16_t)bbmd_port),
(uint16_t)bbmd_timetolive_seconds);
if (retval < 0)
fprintf(stderr, "FAILED to Register with BBMD at %s \n",
inet_ntoa(addr));
BBMD_Timer_Seconds = (uint16_t) bbmd_timetolive_seconds;
BBMD_Timer_Seconds = (uint16_t)bbmd_timetolive_seconds;
} else {
for (entry_number = 1; entry_number <= 128; entry_number++) {
sprintf(bbmd_env,"BACNET_BDT_ADDR_%u", entry_number);
sprintf(bbmd_env, "BACNET_BDT_ADDR_%u", entry_number);
pEnv = getenv(bbmd_env);
if (pEnv) {
bbmd_address = bip_getaddrbyname(pEnv);
@@ -173,7 +167,7 @@ int dlenv_register_as_foreign_device(
}
if (bbmd_address) {
bbmd_port = 0xBAC0;
sprintf(bbmd_env,"BACNET_BDT_PORT_%u", entry_number);
sprintf(bbmd_env, "BACNET_BDT_PORT_%u", entry_number);
pEnv = getenv(bbmd_env);
if (pEnv) {
bbmd_port = strtol(pEnv, NULL, 0);
@@ -185,15 +179,15 @@ int dlenv_register_as_foreign_device(
bbmd_port = bip_get_port();
}
bbmd_mask = 0xFFFFFFFF;
sprintf(bbmd_env,"BACNET_BDT_MASK_%u", entry_number);
sprintf(bbmd_env, "BACNET_BDT_MASK_%u", entry_number);
pEnv = getenv(bbmd_env);
if (pEnv) {
c = sscanf(pEnv, "%3u.%3u.%3u.%3u",
&a[0],&a[1],&a[2],&a[3]);
c = sscanf(pEnv, "%3u.%3u.%3u.%3u", &a[0], &a[1], &a[2],
&a[3]);
if (c == 4) {
bbmd_mask =
((a[0]&0xFF)<<24)|((a[1]&0xFF)<<16)|
((a[2]&0xFF)<<8)|(a[3]&0xFF);
bbmd_mask = ((a[0] & 0xFF) << 24) |
((a[1] & 0xFF) << 16) |
((a[2] & 0xFF) << 8) | (a[3] & 0xFF);
}
}
BBMD_Table_Entry.valid = true;
@@ -222,7 +216,7 @@ static void dlenv_network_port_init(void)
uint32_t test_broadcast = 0;
uint32_t mask = 0;
uint16_t port = 0;
uint8_t mac[4+2] = {0};
uint8_t mac[4 + 2] = {0};
uint8_t prefix = 0;
Network_Port_Object_Instance_Number_Set(0, instance);
@@ -331,8 +325,7 @@ static void dlenv_network_port_init(void)
* Call this function to renew our Foreign Device Registration
* @param elapsed_seconds Number of seconds that have elapsed since last called.
*/
void dlenv_maintenance_timer(
uint16_t elapsed_seconds)
void dlenv_maintenance_timer(uint16_t elapsed_seconds)
{
#if defined(BACDL_BIP)
if (BBMD_Timer_Seconds) {
@@ -342,11 +335,11 @@ void dlenv_maintenance_timer(
BBMD_Timer_Seconds -= elapsed_seconds;
}
if (BBMD_Timer_Seconds == 0) {
(void) dlenv_register_as_foreign_device();
(void)dlenv_register_as_foreign_device();
/* If that failed (negative), maybe just a network issue.
* If nothing happened (0), may be un/misconfigured.
* Set up to try again later in all cases. */
BBMD_Timer_Seconds = (uint16_t) bbmd_timetolive_seconds;
BBMD_Timer_Seconds = (uint16_t)bbmd_timetolive_seconds;
}
}
#endif
@@ -402,8 +395,7 @@ void dlenv_maintenance_timer(
* communications. Default is 47808 (0xBAC0).
* - BACNET_BIP6_BROADCAST - FF05::BAC0 or FF02::BAC0 or ...
*/
void dlenv_init(
void)
void dlenv_init(void)
{
char *pEnv = NULL;
@@ -419,19 +411,17 @@ void dlenv_init(
BACNET_IP6_ADDRESS addr;
pEnv = getenv("BACNET_BIP6_BROADCAST");
if (pEnv) {
bvlc6_address_set(&addr,
(uint16_t) strtol(pEnv, NULL, 0), 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_GROUP_ID);
bvlc6_address_set(&addr, (uint16_t)strtol(pEnv, NULL, 0), 0, 0, 0, 0, 0,
0, BIP6_MULTICAST_GROUP_ID);
bip6_set_broadcast_addr(&addr);
} else {
bvlc6_address_set(&addr,
BIP6_MULTICAST_SITE_LOCAL, 0, 0, 0, 0, 0, 0,
bvlc6_address_set(&addr, BIP6_MULTICAST_SITE_LOCAL, 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_GROUP_ID);
bip6_set_broadcast_addr(&addr);
}
pEnv = getenv("BACNET_BIP6_PORT");
if (pEnv) {
bip6_set_port((uint16_t) strtol(pEnv, NULL, 0));
bip6_set_port((uint16_t)strtol(pEnv, NULL, 0));
} else {
bip6_set_port(0xBAC0);
}
@@ -442,7 +432,7 @@ void dlenv_init(
#endif
pEnv = getenv("BACNET_IP_PORT");
if (pEnv) {
bip_set_port(htons((uint16_t) strtol(pEnv, NULL, 0)));
bip_set_port(htons((uint16_t)strtol(pEnv, NULL, 0)));
} else {
/* BIP_Port is statically initialized to 0xBAC0,
* so if it is different, then it was programmatically altered,
@@ -489,7 +479,7 @@ void dlenv_init(
#endif
pEnv = getenv("BACNET_APDU_TIMEOUT");
if (pEnv) {
apdu_timeout_set((uint16_t) strtol(pEnv, NULL, 0));
apdu_timeout_set((uint16_t)strtol(pEnv, NULL, 0));
} else {
#if defined(BACDL_MSTP)
apdu_timeout_set(60000);
@@ -497,7 +487,7 @@ void dlenv_init(
}
pEnv = getenv("BACNET_APDU_RETRIES");
if (pEnv) {
apdu_retries_set((uint8_t) strtol(pEnv, NULL, 0));
apdu_retries_set((uint8_t)strtol(pEnv, NULL, 0));
}
/* === Initialize the Datalink Here === */
if (!datalink_init(getenv("BACNET_IFACE"))) {
@@ -506,7 +496,7 @@ void dlenv_init(
#if (MAX_TSM_TRANSACTIONS)
pEnv = getenv("BACNET_INVOKE_ID");
if (pEnv) {
tsm_invokeID_set((uint8_t) strtol(pEnv, NULL, 0));
tsm_invokeID_set((uint8_t)strtol(pEnv, NULL, 0));
}
#endif
dlenv_network_port_init();
+70 -78
View File
@@ -1,28 +1,28 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -42,13 +42,11 @@
#include "handlers.h"
#include "device.h"
/** @file h_alarm_ack.c Handles Alarm Acknowledgment. */
static alarm_ack_function Alarm_Ack[MAX_BACNET_OBJECT_TYPE];
void handler_alarm_ack_set(
BACNET_OBJECT_TYPE object_type,
void handler_alarm_ack_set(BACNET_OBJECT_TYPE object_type,
alarm_ack_function pFunction)
{
if (object_type < MAX_BACNET_OBJECT_TYPE) {
@@ -72,11 +70,9 @@ void handler_alarm_ack_set(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message.
*/
void handler_alarm_ack(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_alarm_ack(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data)
{
int len = 0;
int pdu_len = 0;
@@ -90,32 +86,29 @@ void handler_alarm_ack(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr, "Alarm Ack: Segmented message. Sending Abort!\n");
#endif
goto AA_ABORT;
}
len =
alarm_ack_decode_service_request(service_request, service_len, &data);
len = alarm_ack_decode_service_request(service_request, service_len, &data);
#if PRINT_ENABLED
if (len <= 0)
fprintf(stderr, "Alarm Ack: Unable to decode Request!\n");
#endif
if (len < 0) {
/* bad decoding - send an abort */
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER,
true);
#if PRINT_ENABLED
fprintf(stderr, "Alarm Ack: Bad Encoding. Sending Abort!\n");
#endif
@@ -123,46 +116,45 @@ void handler_alarm_ack(
}
#if PRINT_ENABLED
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,
(unsigned long) data.eventObjectIdentifier.instance,
data.ackSource.value, (unsigned long) data.ackProcessIdentifier);
(unsigned long)data.eventObjectIdentifier.instance,
data.ackSource.value, (unsigned long)data.ackProcessIdentifier);
#endif
/* BACnet Testing Observed Incident oi00105
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 )
BC 135.1: 9.1.3.3-A
Any discussions can be directed to edward@bac-test.com */
if (!Device_Valid_Object_Id(data.eventObjectIdentifier.type, data.eventObjectIdentifier.instance))
{
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, ERROR_CLASS_OBJECT, ERROR_CODE_UNKNOWN_OBJECT);
}
else if (Alarm_Ack[data.eventObjectIdentifier.type]) {
Revealed by BACnet Test Client v1.8.16 (
www.bac-test.com/bacnet-test-client-download ) BC 135.1: 9.1.3.3-A Any
discussions can be directed to edward@bac-test.com */
if (!Device_Valid_Object_Id(data.eventObjectIdentifier.type,
data.eventObjectIdentifier.instance)) {
len = bacerror_encode_apdu(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, ERROR_CLASS_OBJECT,
ERROR_CODE_UNKNOWN_OBJECT);
} else if (Alarm_Ack[data.eventObjectIdentifier.type]) {
ack_result =
Alarm_Ack[data.eventObjectIdentifier.type] (&data, &error_code);
Alarm_Ack[data.eventObjectIdentifier.type](&data, &error_code);
switch (ack_result) {
case 1:
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM);
#if PRINT_ENABLED
fprintf(stderr, "Alarm Acknowledge: " "Sending Simple Ack!\n");
fprintf(stderr,
"Alarm Acknowledge: "
"Sending Simple Ack!\n");
#endif
break;
case -1:
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, ERROR_CLASS_OBJECT,
error_code);
SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM,
ERROR_CLASS_OBJECT, error_code);
#if PRINT_ENABLED
fprintf(stderr, "Alarm Acknowledge: error %s!\n",
bactext_error_code_name(error_code));
@@ -170,34 +162,34 @@ void handler_alarm_ack(
break;
default:
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_OTHER, true);
#if PRINT_ENABLED
fprintf(stderr, "Alarm Acknowledge: abort other!\n");
#endif
break;
}
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM,
ERROR_CLASS_OBJECT, ERROR_CODE_NO_ALARM_CONFIGURED);
len = bacerror_encode_apdu(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, ERROR_CLASS_OBJECT,
ERROR_CODE_NO_ALARM_CONFIGURED);
#if PRINT_ENABLED
fprintf(stderr, "Alarm Acknowledge: error %s!\n",
bactext_error_code_name(ERROR_CODE_NO_ALARM_CONFIGURED));
#endif
}
AA_ABORT:
AA_ABORT:
pdu_len += len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
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));
#endif
+42 -51
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -96,11 +96,9 @@ shall be TRUE, otherwise FALSE.
*/
#if defined(BACFILE)
void handler_atomic_read_file(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_atomic_read_file(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data)
{
BACNET_ATOMIC_READ_FILE_DATA data;
int len = 0;
@@ -118,14 +116,12 @@ void handler_atomic_read_file(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
if (service_data->segmented_message) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr, "ARF: Segmented Message. Sending Abort!\n");
#endif
@@ -134,9 +130,9 @@ void handler_atomic_read_file(
len = arf_decode_service_request(service_request, service_len, &data);
/* bad decoding - send an abort */
if (len < 0) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER,
true);
#if PRINT_ENABLED
fprintf(stderr, "Bad Encoding. Sending Abort!\n");
#endif
@@ -154,13 +150,11 @@ void handler_atomic_read_file(
data.type.stream.fileStartPosition,
data.type.stream.requestedOctetCount);
#endif
len =
arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
len = arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data);
} else {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
len = abort_encode_apdu(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
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.RecordCount);
#endif
len =
arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
len = arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data);
} else {
error = true;
@@ -202,15 +195,13 @@ void handler_atomic_read_file(
error_code = ERROR_CODE_INCONSISTENT_OBJECT_TYPE;
}
if (error) {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_ATOMIC_READ_FILE,
error_class, error_code);
len = bacerror_encode_apdu(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
SERVICE_CONFIRMED_ATOMIC_READ_FILE, error_class, error_code);
}
ARF_ABORT:
ARF_ABORT:
pdu_len += len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0) {
+26 -28
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include "config.h"
@@ -51,16 +51,14 @@
/* use the description as the file name. */
#if defined(BACFILE)
void handler_atomic_read_file_ack(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
uint8_t* service_request, uint16_t service_len, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_ACK_DATA* service_data)
{
int len = 0;
BACNET_ATOMIC_READ_FILE_DATA data;
uint32_t instance = 0;
(void) src;
(void)src;
/* get the file instance from the tsm data before freeing it */
instance = bacfile_instance_from_tsm(service_data->invoke_id);
len = arf_ack_decode_service_request(service_request, service_len, &data);
+40 -48
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -76,11 +76,9 @@ standard.
*/
#if defined(BACFILE)
void handler_atomic_write_file(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_atomic_write_file(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data)
{
BACNET_ATOMIC_WRITE_FILE_DATA data;
int len = 0;
@@ -98,14 +96,12 @@ void handler_atomic_write_file(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
if (service_data->segmented_message) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr, "Segmented Message. Sending Abort!\n");
#endif
@@ -114,9 +110,9 @@ void handler_atomic_write_file(
len = awf_decode_service_request(service_request, service_len, &data);
/* bad decoding - send an abort */
if (len < 0) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER,
true);
#if PRINT_ENABLED
fprintf(stderr, "Bad Encoding. Sending Abort!\n");
#endif
@@ -132,8 +128,7 @@ void handler_atomic_write_file(
data.type.stream.fileStartPosition,
(int)octetstring_length(&data.fileData[0]));
#endif
len =
awf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
len = awf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data);
} else {
error = true;
@@ -147,8 +142,7 @@ void handler_atomic_write_file(
data.type.record.fileStartRecord,
data.type.record.returnedRecordCount);
#endif
len =
awf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
len = awf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data);
} else {
error = true;
@@ -169,15 +163,13 @@ void handler_atomic_write_file(
error_code = ERROR_CODE_INCONSISTENT_OBJECT_TYPE;
}
if (error) {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_ATOMIC_WRITE_FILE,
error_class, error_code);
len = bacerror_encode_apdu(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, error_class, error_code);
}
AWF_ABORT:
AWF_ABORT:
pdu_len += len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0) {
+99 -173
View File
@@ -61,7 +61,8 @@ static uint16_t BVLC6_Buffer_Len;
#ifndef MAX_BBMD6_ENTRIES
#define MAX_BBMD6_ENTRIES 128
#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 */
#ifndef MAX_FD6_ENTRIES
#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
*/
void bbmd6_maintenance_timer(
time_t seconds)
void bbmd6_maintenance_timer(time_t seconds)
{
unsigned i = 0;
@@ -104,8 +104,7 @@ void bbmd6_maintenance_timer(
*
* @return true if the address was set
*/
static bool bbmd6_address_from_vmac(
BACNET_IP6_ADDRESS *addr,
static bool bbmd6_address_from_vmac(BACNET_IP6_ADDRESS *addr,
struct vmac_data *vmac)
{
bool status = false;
@@ -130,8 +129,7 @@ static bool bbmd6_address_from_vmac(
*
* @return true if the address was set
*/
static bool bbmd6_address_to_vmac(
struct vmac_data *vmac,
static bool bbmd6_address_to_vmac(struct vmac_data *vmac,
BACNET_IP6_ADDRESS *addr)
{
bool status = false;
@@ -157,9 +155,7 @@ static bool bbmd6_address_to_vmac(
*
* @return true if the VMAC address was added
*/
static bool bbmd6_add_vmac(
uint32_t device_id,
BACNET_IP6_ADDRESS *addr)
static bool bbmd6_add_vmac(uint32_t device_id, BACNET_IP6_ADDRESS *addr)
{
bool status = false;
struct vmac_data *vmac;
@@ -186,8 +182,7 @@ static bool bbmd6_add_vmac(
*
* @return true if the IPv6 from sin match me
*/
static bool bbmd6_address_match_self(
BACNET_IP6_ADDRESS *addr)
static bool bbmd6_address_match_self(BACNET_IP6_ADDRESS *addr)
{
BACNET_IP6_ADDRESS my_addr = {{0}};
bool status = false;
@@ -211,10 +206,9 @@ static bool bbmd6_address_match_self(
*
* @return true if the address was in the VMAC table
*/
static bool bbmd6_address_from_bacnet_address(
BACNET_IP6_ADDRESS * addr,
uint32_t * vmac_src,
BACNET_ADDRESS * baddr)
static bool bbmd6_address_from_bacnet_address(BACNET_IP6_ADDRESS *addr,
uint32_t *vmac_src,
BACNET_ADDRESS *baddr)
{
struct vmac_data *vmac;
bool status = false;
@@ -226,8 +220,7 @@ static bool bbmd6_address_from_bacnet_address(
vmac = VMAC_Find_By_Key(device_id);
if (vmac) {
debug_printf("BVLC6: Found VMAC %lu (len=%u).\n",
(unsigned long)device_id,
(unsigned)vmac->mac_len);
(unsigned long)device_id, (unsigned)vmac->mac_len);
status = bbmd6_address_from_vmac(addr, vmac);
if (vmac_src) {
*vmac_src = device_id;
@@ -239,8 +232,6 @@ static bool bbmd6_address_from_bacnet_address(
return status;
}
/**
* The common send function for BACnet/IPv6 application layer
*
@@ -253,20 +244,17 @@ static bool bbmd6_address_from_bacnet_address(
* @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error.
*/
int bip6_send_pdu(
BACNET_ADDRESS * dest,
BACNET_NPDU_DATA * npdu_data,
uint8_t * pdu,
unsigned pdu_len)
int bip6_send_pdu(BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data,
uint8_t *pdu, unsigned pdu_len)
{
BACNET_IP6_ADDRESS bvlc_dest = {{0}};
uint8_t mtu[MAX_MPDU] = { 0 };
uint8_t mtu[MAX_MPDU] = {0};
uint16_t mtu_len = 0;
uint32_t vmac_src = 0;
uint32_t vmac_dst = 0;
/* this datalink doesn't need to know the npdu data */
(void) npdu_data;
(void)npdu_data;
/* handle various broadcasts: */
if ((dest->net == BACNET_BROADCAST_NETWORK) || (dest->mac_len == 0)) {
/* mac_len = 0 is a broadcast address */
@@ -281,8 +269,8 @@ int bip6_send_pdu(
} else {
bip6_get_broadcast_addr(&bvlc_dest);
vmac_src = Device_Object_Instance_Number();
mtu_len = bvlc6_encode_original_broadcast(
mtu, sizeof(mtu), vmac_src, pdu, pdu_len);
mtu_len = bvlc6_encode_original_broadcast(mtu, sizeof(mtu),
vmac_src, pdu, pdu_len);
debug_printf("BVLC6: Sent Original-Broadcast-NPDU.\n");
}
} else if ((dest->net > 0) && (dest->len == 0)) {
@@ -294,16 +282,16 @@ int bip6_send_pdu(
bip6_get_broadcast_addr(&bvlc_dest);
}
vmac_src = Device_Object_Instance_Number();
mtu_len = bvlc6_encode_original_broadcast(
mtu, sizeof(mtu), vmac_src, pdu, pdu_len);
mtu_len = bvlc6_encode_original_broadcast(mtu, sizeof(mtu), vmac_src,
pdu, pdu_len);
debug_printf("BVLC6: Sent Original-Broadcast-NPDU.\n");
} else if (dest->mac_len == 3) {
/* valid unicast */
bbmd6_address_from_bacnet_address(&bvlc_dest, &vmac_dst, dest);
debug_printf("BVLC6: Sending to VMAC %lu.\n", (unsigned long)vmac_dst);
vmac_src = Device_Object_Instance_Number();
mtu_len = bvlc6_encode_original_unicast(
mtu, sizeof(mtu), vmac_src, vmac_dst, pdu, pdu_len);
mtu_len = bvlc6_encode_original_unicast(mtu, sizeof(mtu), vmac_src,
vmac_dst, pdu, pdu_len);
debug_printf("BVLC6: Sent Original-Unicast-NPDU.\n");
} else {
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_len - the number of bytes of NPDU+APDU data to send
*/
static void bbmd6_send_pdu_bdt(
uint8_t * mtu,
unsigned int mtu_len)
static void bbmd6_send_pdu_bdt(uint8_t *mtu, unsigned int mtu_len)
{
BACNET_IP6_ADDRESS my_addr = {{0}};
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_len - the number of bytes of NPDU+APDU data to send
*/
static void bbmd6_send_pdu_fdt(
uint8_t * mtu,
unsigned int mtu_len)
static void bbmd6_send_pdu_fdt(uint8_t *mtu, unsigned int mtu_len)
{
BACNET_IP6_ADDRESS my_addr = {{0}};
unsigned i = 0; /* loop counter */
@@ -381,13 +365,11 @@ static void bbmd6_send_pdu_fdt(
* @param npdu - the 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(
BACNET_IP6_ADDRESS *address,
uint32_t vmac_src,
uint8_t * npdu,
static void bbmd6_send_forward_npdu(BACNET_IP6_ADDRESS *address,
uint32_t vmac_src, uint8_t *npdu,
unsigned int npdu_len)
{
uint8_t mtu[MAX_MPDU] = { 0 };
uint8_t mtu[MAX_MPDU] = {0};
uint16_t mtu_len = 0;
unsigned i = 0; /* loop counter */
@@ -424,12 +406,10 @@ static void bbmd6_send_forward_npdu(
* @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error.
*/
static int bvlc6_send_result(
BACNET_IP6_ADDRESS *dest_addr,
uint32_t vmac_src,
static int bvlc6_send_result(BACNET_IP6_ADDRESS *dest_addr, uint32_t vmac_src,
uint16_t result_code)
{
uint8_t mtu[MAX_MPDU] = { 0 };
uint8_t mtu[MAX_MPDU] = {0};
uint16_t mtu_len = 0;
mtu_len = bvlc6_encode_result(&mtu[0], sizeof(mtu), vmac_src, result_code);
@@ -448,16 +428,14 @@ static int bvlc6_send_result(
* @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error.
*/
static int bvlc6_send_address_resolution_ack(
BACNET_IP6_ADDRESS *dest_addr,
static int bvlc6_send_address_resolution_ack(BACNET_IP6_ADDRESS *dest_addr,
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;
mtu_len = bvlc6_encode_address_resolution_ack(
&mtu[0], sizeof(mtu),
mtu_len = bvlc6_encode_address_resolution_ack(&mtu[0], sizeof(mtu),
vmac_src, vmac_dst);
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.
*/
static int bvlc6_send_virtual_address_resolution_ack(
BACNET_IP6_ADDRESS *dest_addr,
uint32_t vmac_src,
uint32_t vmac_dst)
BACNET_IP6_ADDRESS *dest_addr, 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;
mtu_len = bvlc6_encode_virtual_address_resolution_ack(
&mtu[0], sizeof(mtu),
mtu_len = bvlc6_encode_virtual_address_resolution_ack(&mtu[0], sizeof(mtu),
vmac_src, vmac_dst);
return bip6_send_mpdu(dest_addr, mtu, mtu_len);
@@ -497,9 +472,8 @@ static int bvlc6_send_virtual_address_resolution_ack(
* @param pdu - The received NPDU+APDU buffer.
* @param pdu_len - How many bytes in NPDU+APDU buffer.
*/
static void bbmd6_virtual_address_resolution_handler(
BACNET_IP6_ADDRESS *addr,
uint8_t * pdu,
static void bbmd6_virtual_address_resolution_handler(BACNET_IP6_ADDRESS *addr,
uint8_t *pdu,
uint16_t pdu_len)
{
int function_len = 0;
@@ -511,8 +485,7 @@ static void bbmd6_virtual_address_resolution_handler(
if (bbmd6_address_match_self(addr)) {
/* ignore messages from my IPv6 address */
} else {
function_len = bvlc6_decode_virtual_address_resolution(
pdu, pdu_len,
function_len = bvlc6_decode_virtual_address_resolution(pdu, pdu_len,
&vmac_src);
if (function_len) {
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
the Address-Resolution message. */
vmac_me = Device_Object_Instance_Number();
bvlc6_send_virtual_address_resolution_ack(
addr, vmac_me, vmac_src);
bvlc6_send_virtual_address_resolution_ack(addr, vmac_me,
vmac_src);
}
}
}
@@ -535,9 +508,7 @@ static void bbmd6_virtual_address_resolution_handler(
* @param pdu_len - How many bytes in NPDU+APDU buffer.
*/
static void bbmd6_virtual_address_resolution_ack_handler(
BACNET_IP6_ADDRESS *addr,
uint8_t * pdu,
uint16_t pdu_len)
BACNET_IP6_ADDRESS *addr, uint8_t *pdu, uint16_t pdu_len)
{
int function_len = 0;
uint32_t vmac_src = 0;
@@ -549,8 +520,7 @@ static void bbmd6_virtual_address_resolution_ack_handler(
/* ignore messages from my IPv6 address */
} else {
function_len = bvlc6_decode_virtual_address_resolution_ack(
pdu, pdu_len,
&vmac_src, &vmac_dst);
pdu, pdu_len, &vmac_src, &vmac_dst);
if (function_len) {
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_len - How many bytes in NPDU+APDU buffer.
*/
static void bbmd6_address_resolution_handler(
BACNET_IP6_ADDRESS *addr,
uint8_t * pdu,
uint16_t pdu_len)
static void bbmd6_address_resolution_handler(BACNET_IP6_ADDRESS *addr,
uint8_t *pdu, uint16_t pdu_len)
{
int function_len = 0;
uint32_t vmac_src = 0;
@@ -581,8 +549,7 @@ static void bbmd6_address_resolution_handler(
/* ignore messages from my IPv6 address */
} else {
function_len = bvlc6_decode_address_resolution(
pdu, pdu_len,
&vmac_src, &vmac_target);
pdu, pdu_len, &vmac_src, &vmac_target);
if (function_len) {
bbmd6_add_vmac(vmac_src, addr);
vmac_me = Device_Object_Instance_Number();
@@ -590,8 +557,7 @@ static void bbmd6_address_resolution_handler(
/* The Address-Resolution-ACK message is unicast
to the B/IPv6 node that originally initiated
the Address-Resolution message. */
bvlc6_send_address_resolution_ack(
addr, vmac_me, vmac_src);
bvlc6_send_address_resolution_ack(addr, vmac_me, vmac_src);
}
}
}
@@ -605,10 +571,8 @@ static void bbmd6_address_resolution_handler(
* @param pdu - The received NPDU+APDU buffer.
* @param pdu_len - How many bytes in NPDU+APDU buffer.
*/
static void bbmd6_address_resolution_ack_handler(
BACNET_IP6_ADDRESS *addr,
uint8_t * pdu,
uint16_t pdu_len)
static void bbmd6_address_resolution_ack_handler(BACNET_IP6_ADDRESS *addr,
uint8_t *pdu, uint16_t pdu_len)
{
int function_len = 0;
uint32_t vmac_src = 0;
@@ -620,8 +584,7 @@ static void bbmd6_address_resolution_ack_handler(
/* ignore messages from my IPv6 address */
} else {
function_len = bvlc6_decode_address_resolution_ack(
pdu, pdu_len,
&vmac_src, &vmac_dst);
pdu, pdu_len, &vmac_src, &vmac_dst);
if (function_len) {
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
*/
static int handler_bbmd6_for_non_bbmd(
BACNET_IP6_ADDRESS *addr,
BACNET_ADDRESS * src,
uint8_t * mtu,
static int handler_bbmd6_for_non_bbmd(BACNET_IP6_ADDRESS *addr,
BACNET_ADDRESS *src, uint8_t *mtu,
uint16_t mtu_len)
{
uint16_t result_code = BVLC6_RESULT_SUCCESSFUL_COMPLETION;
@@ -653,23 +614,23 @@ static int handler_bbmd6_for_non_bbmd(
uint16_t message_length = 0;
int header_len = 0;
int function_len = 0;
uint8_t * pdu = NULL;
uint8_t *pdu = NULL;
uint16_t pdu_len = 0;
uint16_t npdu_len = 0;
bool send_result = false;
uint16_t offset = 0;
BACNET_IP6_ADDRESS fwd_address = {{0}};
header_len = bvlc6_decode_header(mtu, mtu_len, &message_type,
&message_length);
header_len =
bvlc6_decode_header(mtu, mtu_len, &message_type, &message_length);
if (header_len == 4) {
BVLC6_Function_Code = message_type;
pdu = &mtu[header_len];
pdu_len = mtu_len - header_len;
switch (BVLC6_Function_Code) {
case BVLC6_RESULT:
function_len = bvlc6_decode_result(pdu, pdu_len, &vmac_src,
&result_code);
function_len =
bvlc6_decode_result(pdu, pdu_len, &vmac_src, &result_code);
if (function_len) {
BVLC6_Result_Code = result_code;
/* 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");
} else {
function_len = bvlc6_decode_original_unicast(
pdu, pdu_len,
&vmac_src, &vmac_dst,
NULL, 0, &npdu_len);
pdu, pdu_len, &vmac_src, &vmac_dst, NULL, 0, &npdu_len);
if (function_len) {
if (vmac_dst == Device_Object_Instance_Number()) {
/* 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");
} else {
function_len = bvlc6_decode_original_broadcast(
pdu, pdu_len,
&vmac_src,
NULL, 0, &npdu_len);
pdu, pdu_len, &vmac_src, NULL, 0, &npdu_len);
if (function_len) {
/* The Virtual MAC address table shall be updated
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);
} else {
debug_printf(
"BIP6: Original-Broadcast-NPDU: Unable to decode!\n");
"BIP6: Original-Broadcast-NPDU: Unable to "
"decode!\n");
}
}
break;
@@ -754,9 +712,8 @@ static int handler_bbmd6_for_non_bbmd(
debug_printf("BIP6: Forwarded-NPDU is me!\n");
} else {
function_len = bvlc6_decode_forwarded_npdu(
pdu, pdu_len,
&vmac_src, &fwd_address,
NULL, 0, &npdu_len);
pdu, pdu_len, &vmac_src, &fwd_address, NULL, 0,
&npdu_len);
if (function_len) {
/* The Virtual MAC address table shall be updated
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);
break;
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;
case BVLC6_SECURE_BVLL:
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
*/
static int handler_bbmd6_for_bbmd(
BACNET_IP6_ADDRESS *addr,
BACNET_ADDRESS * src,
uint8_t * mtu,
uint16_t mtu_len)
static int handler_bbmd6_for_bbmd(BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src,
uint8_t *mtu, uint16_t mtu_len)
{
uint16_t result_code = BVLC6_RESULT_SUCCESSFUL_COMPLETION;
uint32_t vmac_me = 0;
@@ -829,24 +784,24 @@ static int handler_bbmd6_for_bbmd(
uint16_t message_length = 0;
int header_len = 0;
int function_len = 0;
uint8_t * pdu = NULL;
uint8_t *pdu = NULL;
uint16_t pdu_len = 0;
uint8_t * npdu = NULL;
uint8_t *npdu = NULL;
uint16_t npdu_len = 0;
bool send_result = false;
uint16_t offset = 0;
BACNET_IP6_ADDRESS fwd_address = {{0}};
header_len = bvlc6_decode_header(mtu, mtu_len, &message_type,
&message_length);
header_len =
bvlc6_decode_header(mtu, mtu_len, &message_type, &message_length);
if (header_len == 4) {
BVLC6_Function_Code = message_type;
pdu = &mtu[header_len];
pdu_len = mtu_len - header_len;
switch (BVLC6_Function_Code) {
case BVLC6_RESULT:
function_len = bvlc6_decode_result(pdu, pdu_len, &vmac_src,
&result_code);
function_len =
bvlc6_decode_result(pdu, pdu_len, &vmac_src, &result_code);
if (function_len) {
BVLC6_Result_Code = result_code;
/* The Virtual MAC address table shall be updated
@@ -880,9 +835,7 @@ static int handler_bbmd6_for_bbmd(
offset = 0;
} else {
function_len = bvlc6_decode_original_unicast(
pdu, pdu_len,
&vmac_src, &vmac_dst,
NULL, 0, &npdu_len);
pdu, pdu_len, &vmac_src, &vmac_dst, NULL, 0, &npdu_len);
if (function_len) {
if (vmac_dst == Device_Object_Instance_Number()) {
/* The Virtual MAC address table shall be updated
@@ -898,9 +851,7 @@ static int handler_bbmd6_for_bbmd(
case BVLC6_ORIGINAL_BROADCAST_NPDU:
debug_printf("BIP6: Received Original-Broadcast-NPDU.\n");
function_len = bvlc6_decode_original_broadcast(
pdu, pdu_len,
&vmac_src,
NULL, 0, &npdu_len);
pdu, pdu_len, &vmac_src, NULL, 0, &npdu_len);
if (function_len) {
offset = header_len + (function_len - npdu_len);
npdu = &mtu[offset];
@@ -912,8 +863,7 @@ static int handler_bbmd6_for_bbmd(
be unicast to each foreign device currently in
the BBMD's FDT */
BVLC6_Buffer_Len = bvlc6_encode_forwarded_npdu(
&BVLC6_Buffer[0], sizeof(BVLC6_Buffer),
vmac_src, addr,
&BVLC6_Buffer[0], sizeof(BVLC6_Buffer), vmac_src, addr,
npdu, npdu_len);
bbmd6_send_pdu_bdt(&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:
debug_printf("BIP6: Received Forwarded-NPDU.\n");
function_len = bvlc6_decode_forwarded_npdu(
pdu, pdu_len,
&vmac_src, &fwd_address,
NULL, 0, &npdu_len);
pdu, pdu_len, &vmac_src, &fwd_address, NULL, 0, &npdu_len);
if (function_len) {
offset = header_len + (function_len - npdu_len);
npdu = &mtu[offset];
@@ -941,11 +889,11 @@ static int handler_bbmd6_for_bbmd(
transmit it via multicast to B/IPv6 devices in the
local multicast domain. */
BVLC6_Buffer_Len = bvlc6_encode_forwarded_npdu(
&BVLC6_Buffer[0], sizeof(BVLC6_Buffer),
vmac_src, addr,
&BVLC6_Buffer[0], sizeof(BVLC6_Buffer), vmac_src, addr,
npdu, npdu_len);
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
message shall be unicast to each foreign device in
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);
break;
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;
case BVLC6_SECURE_BVLL:
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
*/
int bvlc6_handler(
BACNET_IP6_ADDRESS *addr,
BACNET_ADDRESS * src,
uint8_t * npdu,
int bvlc6_handler(BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src, uint8_t *npdu,
uint16_t npdu_len)
{
#if defined(BACDL_BIP6) && BBMD6_ENABLED
@@ -1027,12 +973,10 @@ int bvlc6_handler(
* 0 if no registration request is sent, or
* -1 if registration fails.
*/
int bvlc6_register_with_bbmd(
BACNET_IP6_ADDRESS *bbmd_addr,
uint32_t vmac_src,
int bvlc6_register_with_bbmd(BACNET_IP6_ADDRESS *bbmd_addr, uint32_t vmac_src,
uint16_t time_to_live_seconds)
{
uint8_t mtu[MAX_MPDU] = { 0 };
uint8_t mtu[MAX_MPDU] = {0};
uint16_t mtu_len = 0;
mtu_len = bvlc6_encode_register_foreign_device(
@@ -1049,8 +993,7 @@ int bvlc6_register_with_bbmd(
* BVLC6_RESULT_REGISTER_FOREIGN_DEVICE_NAK if registration failed,
* or one of the other codes (if we are a BBMD).
*/
uint16_t bvlc6_get_last_result(
void)
uint16_t bvlc6_get_last_result(void)
{
return BVLC6_Result_Code;
}
@@ -1062,8 +1005,7 @@ uint16_t bvlc6_get_last_result(
*
* @return A BVLC6_ code, such as BVLC6_ORIGINAL_UNICAST_NPDU.
*/
uint8_t bvlc6_get_function_code(
void)
uint8_t bvlc6_get_function_code(void)
{
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.
*/
uint16_t bip6_receive(
BACNET_ADDRESS * src,
uint8_t * npdu,
uint16_t max_npdu,
uint16_t bip6_receive(BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu,
unsigned timeout)
{
return 0;
@@ -1115,10 +1054,7 @@ uint16_t bip6_receive(
* @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error.
*/
int bip6_send_mpdu(
BACNET_IP6_ADDRESS *dest,
uint8_t * mtu,
uint16_t mtu_len)
int bip6_send_mpdu(BACNET_IP6_ADDRESS *dest, uint8_t *mtu, uint16_t mtu_len)
{
return 0;
}
@@ -1129,8 +1065,7 @@ int bip6_send_mpdu(
*
* @return The Instance number used in the BACNET_OBJECT_ID for the Device.
*/
uint32_t Device_Object_Instance_Number(
void)
uint32_t Device_Object_Instance_Number(void)
{
return Device_ID;
}
@@ -1140,8 +1075,7 @@ uint32_t Device_Object_Instance_Number(
*
* @return BACnet/IP address
*/
bool bip6_get_addr(
BACNET_IP6_ADDRESS *addr)
bool bip6_get_addr(BACNET_IP6_ADDRESS *addr)
{
return bvlc6_address_copy(addr, &BIP6_Addr);
}
@@ -1151,14 +1085,12 @@ bool bip6_get_addr(
*
* @return BACnet/IP address
*/
bool bip6_get_broadcast_addr(
BACNET_IP6_ADDRESS *addr)
bool bip6_get_broadcast_addr(BACNET_IP6_ADDRESS *addr)
{
return bvlc6_address_copy(addr, &BIP6_Broadcast_Addr);
}
static void test_BBMD_Result(
Test * pTest)
static void test_BBMD_Result(Test *pTest)
{
int result = 0;
uint32_t vmac_src = 0x1234;
@@ -1168,24 +1100,22 @@ static void test_BBMD_Result(
BVLC6_RESULT_VIRTUAL_ADDRESS_RESOLUTION_NAK,
BVLC6_RESULT_REGISTER_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;
uint8_t test_function_code = 0;
BACNET_IP6_ADDRESS addr;
BACNET_ADDRESS src;
unsigned int i = 0;
uint8_t mtu[MAX_MPDU] = { 0 };
uint8_t mtu[MAX_MPDU] = {0};
uint16_t mtu_len = 0;
bvlc6_address_set(&addr,
BIP6_MULTICAST_LINK_LOCAL, 0, 0, 0, 0, 0, 0,
bvlc6_address_set(&addr, BIP6_MULTICAST_LINK_LOCAL, 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_GROUP_ID);
addr.port = 0xBAC0;
bvlc6_vmac_address_set(&src, vmac_src);
for (i = 0; i < 6; i++) {
mtu_len = bvlc6_encode_result(&mtu[0], sizeof(mtu),
vmac_src, result_code[i]);
mtu_len =
bvlc6_encode_result(&mtu[0], sizeof(mtu), vmac_src, result_code[i]);
result = handler_bbmd6_for_non_bbmd(&addr, &src, &mtu[0], mtu_len);
/* validate that the result is handled (0) */
ct_test(pTest, result == 0);
@@ -1196,8 +1126,7 @@ static void test_BBMD_Result(
}
}
static void test_BBMD6(
Test * pTest)
static void test_BBMD6(Test *pTest)
{
bool rc;
@@ -1207,8 +1136,7 @@ static void test_BBMD6(
}
#ifdef TEST_BBMD6
int main(
void)
int main(void)
{
Test *pTest;
@@ -1217,12 +1145,10 @@ int main(
/* configure output */
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
}
#endif
#endif
+44 -49
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -59,11 +59,9 @@
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message.
*/
void handler_ccov_notification(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_ccov_notification(uint8_t *service_request, uint16_t service_len,
BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA *service_data)
{
BACNET_NPDU_DATA npdu_data;
BACNET_COV_DATA cov_data;
@@ -81,31 +79,29 @@ void handler_ccov_notification(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
#if PRINT_ENABLED
fprintf(stderr, "CCOV: Received Notification!\n");
#endif
if (service_data->segmented_message) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr, "CCOV: Segmented message. Sending Abort!\n");
#endif
goto CCOV_ABORT;
}
/* decode the service request only */
len =
cov_notify_decode_service_request(service_request, service_len,
len = cov_notify_decode_service_request(service_request, service_len,
&cov_data);
#if PRINT_ENABLED
if (len > 0) {
fprintf(stderr, "CCOV: PID=%u ", cov_data.subscriberProcessIdentifier);
fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier);
fprintf(stderr, "%s %u ",
fprintf(
stderr, "%s %u ",
bactext_object_type_name(cov_data.monitoredObjectIdentifier.type),
cov_data.monitoredObjectIdentifier.instance);
fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining);
@@ -114,9 +110,9 @@ void handler_ccov_notification(
while (pProperty_value) {
fprintf(stderr, "CCOV: ");
if (pProperty_value->propertyIdentifier < 512) {
fprintf(stderr, "%s ",
bactext_property_name
(pProperty_value->propertyIdentifier));
fprintf(
stderr, "%s ",
bactext_property_name(pProperty_value->propertyIdentifier));
} else {
fprintf(stderr, "proprietary %u ",
pProperty_value->propertyIdentifier);
@@ -131,25 +127,24 @@ void handler_ccov_notification(
#endif
/* bad decoding or something we didn't understand - send an abort */
if (len <= 0) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER,
true);
#if PRINT_ENABLED
fprintf(stderr, "CCOV: Bad Encoding. Sending Abort!\n");
#endif
goto CCOV_ABORT;
} else {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_COV_NOTIFICATION);
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_COV_NOTIFICATION);
#if PRINT_ENABLED
fprintf(stderr, "CCOV: Sending Simple Ack!\n");
#endif
}
CCOV_ABORT:
CCOV_ABORT:
pdu_len += len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0) {
+129 -164
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2007-2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2007-2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -54,16 +54,16 @@
/** @file h_cov.c Handles Change of Value (COV) services. */
typedef struct BACnet_COV_Address {
bool valid:1;
bool valid : 1;
BACNET_ADDRESS dest;
} BACNET_COV_ADDRESS;
/* note: This COV service only monitors the properties
of an object that have been specified in the standard. */
typedef struct BACnet_COV_Subscription_Flags {
bool valid:1;
bool issueConfirmedNotifications:1; /* optional */
bool send_requested:1;
bool valid : 1;
bool issueConfirmedNotifications : 1; /* optional */
bool send_requested : 1;
} BACNET_COV_SUBSCRIPTION_FLAGS;
typedef struct BACnet_COV_Subscription {
@@ -85,15 +85,14 @@ static BACNET_COV_SUBSCRIPTION COV_Subscriptions[MAX_COV_SUBCRIPTIONS];
static BACNET_COV_ADDRESS COV_Addresses[MAX_COV_ADDRESSES];
/**
* Gets the address from the list of COV addresses
*
* @param index - offset into COV address list where address is stored
* @param dest - address to be filled when found
*
* @return true if valid address, false if not valid or not found
*/
static BACNET_ADDRESS *cov_address_get(
int index)
* Gets the address from the list of COV addresses
*
* @param index - offset into COV address list where address is stored
* @param dest - address to be filled when found
*
* @return true if valid address, false if not valid or not found
*/
static BACNET_ADDRESS *cov_address_get(int index)
{
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
* used by other COV subscriptions
*/
static void cov_address_remove_unused(
void)
static void cov_address_remove_unused(void)
{
unsigned index = 0;
unsigned cov_index = 0;
@@ -135,14 +133,13 @@ static void cov_address_remove_unused(
}
/**
* Adds the address to the list of COV addresses
*
* @param dest - address to be added if there is room in the list
*
* @return index number 0..N, or -1 if unable to add
*/
static int cov_address_add(
BACNET_ADDRESS * dest)
* Adds the address to the list of COV addresses
*
* @param dest - address to be added if there is room in the list
*
* @return index number 0..N, or -1 if unable to add
*/
static int cov_address_add(BACNET_ADDRESS *dest)
{
int index = -1;
unsigned i = 0;
@@ -207,17 +204,14 @@ TimeRemaining [3] Unsigned,
COVIncrement [4] REAL OPTIONAL
*/
static int cov_encode_subscription(
uint8_t * apdu,
int max_apdu,
BACNET_COV_SUBSCRIPTION * cov_subscription)
static int cov_encode_subscription(uint8_t *apdu, int max_apdu,
BACNET_COV_SUBSCRIPTION *cov_subscription)
{
int len = 0;
int apdu_len = 0;
BACNET_OCTET_STRING octet_string;
BACNET_ADDRESS *dest = NULL;
/* FIXME: unused parameter */
max_apdu = max_apdu;
if (!cov_subscription) {
@@ -256,9 +250,8 @@ static int cov_encode_subscription(
len = encode_closing_tag(&apdu[apdu_len], 0);
apdu_len += len;
/* processIdentifier [1] Unsigned32 */
len =
encode_context_unsigned(&apdu[apdu_len], 1,
cov_subscription->subscriberProcessIdentifier);
len = encode_context_unsigned(
&apdu[apdu_len], 1, cov_subscription->subscriberProcessIdentifier);
apdu_len += len;
/* Recipient [0] BACnetRecipientProcess - closing */
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);
apdu_len += len;
/* objectIdentifier [0] */
len =
encode_context_object_id(&apdu[apdu_len], 0,
cov_subscription->monitoredObjectIdentifier.type,
len = encode_context_object_id(
&apdu[apdu_len], 0, cov_subscription->monitoredObjectIdentifier.type,
cov_subscription->monitoredObjectIdentifier.instance);
apdu_len += len;
/* propertyIdentifier [1] */
@@ -280,14 +272,12 @@ static int cov_encode_subscription(
len = encode_closing_tag(&apdu[apdu_len], 1);
apdu_len += len;
/* IssueConfirmedNotifications [2] BOOLEAN, */
len =
encode_context_boolean(&apdu[apdu_len], 2,
cov_subscription->flag.issueConfirmedNotifications);
len = encode_context_boolean(
&apdu[apdu_len], 2, cov_subscription->flag.issueConfirmedNotifications);
apdu_len += len;
/* TimeRemaining [3] Unsigned, */
len =
encode_context_unsigned(&apdu[apdu_len], 3,
cov_subscription->lifetime);
encode_context_unsigned(&apdu[apdu_len], 3, cov_subscription->lifetime);
apdu_len += len;
return apdu_len;
@@ -295,18 +285,16 @@ static int cov_encode_subscription(
/** Handle a request to list all the COV subscriptions.
* @ingroup DSCOV
* Invoked by a request to read the Device object's PROP_ACTIVE_COV_SUBSCRIPTIONS.
* Loops through the list of COV Subscriptions, and, for each valid one,
* adds its description to the APDU.
* Invoked by a request to read the Device object's
* PROP_ACTIVE_COV_SUBSCRIPTIONS. Loops through the list of COV Subscriptions,
* and, for each valid one, adds its description to the APDU.
* @note This function needs some work to better handle buffer overruns.
* @param apdu [out] Buffer in which the APDU contents are built.
* @param max_apdu [in] Max length of the APDU buffer.
* @return How many bytes were encoded in the buffer, or -2 if the response
* would not fit within the buffer.
*/
int handler_cov_encode_subscriptions(
uint8_t * apdu,
int max_apdu)
int handler_cov_encode_subscriptions(uint8_t *apdu, int max_apdu)
{
int len = 0;
int apdu_len = 0;
@@ -315,9 +303,9 @@ int handler_cov_encode_subscriptions(
if (apdu) {
for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
if (COV_Subscriptions[index].flag.valid) {
len =
cov_encode_subscription(&apdu[apdu_len],
max_apdu - apdu_len, &COV_Subscriptions[index]);
len = cov_encode_subscription(&apdu[apdu_len],
max_apdu - apdu_len,
&COV_Subscriptions[index]);
apdu_len += len;
/* TODO: too late here to notice that we overran the buffer */
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.
* @ingroup DSCOV
*/
void handler_cov_init(
void)
void handler_cov_init(void)
{
unsigned index = 0;
@@ -355,11 +342,10 @@ void handler_cov_init(
}
}
static bool cov_list_subscribe(
BACNET_ADDRESS * src,
BACNET_SUBSCRIBE_COV_DATA * cov_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
static bool cov_list_subscribe(BACNET_ADDRESS *src,
BACNET_SUBSCRIBE_COV_DATA *cov_data,
BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code)
{
bool existing_entry = false;
int index;
@@ -386,7 +372,8 @@ static bool cov_list_subscribe(
(COV_Subscriptions[index].monitoredObjectIdentifier.instance ==
cov_data->monitoredObjectIdentifier.instance) &&
(COV_Subscriptions[index].subscriberProcessIdentifier ==
cov_data->subscriberProcessIdentifier) && address_match) {
cov_data->subscriberProcessIdentifier) &&
address_match) {
existing_entry = true;
if (cov_data->cancellationRequest) {
COV_Subscriptions[index].flag.valid = false;
@@ -447,9 +434,8 @@ static bool cov_list_subscribe(
return found;
}
static bool cov_send_request(
BACNET_COV_SUBSCRIPTION * cov_subscription,
BACNET_PROPERTY_VALUE * value_list)
static bool cov_send_request(BACNET_COV_SUBSCRIPTION *cov_subscription,
BACNET_PROPERTY_VALUE *value_list)
{
int len = 0;
int pdu_len = 0;
@@ -479,8 +465,7 @@ static bool cov_send_request(
}
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
&npdu_data);
/* load the COV data structure for outgoing message */
cov_data.subscriberProcessIdentifier =
@@ -497,25 +482,26 @@ static bool cov_send_request(
invoke_id = tsm_next_free_invokeID();
if (invoke_id) {
cov_subscription->invokeID = invoke_id;
len =
ccov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer) - pdu_len, invoke_id, &cov_data);
len = ccov_notify_encode_apdu(
&Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer) - pdu_len, invoke_id,
&cov_data);
} else {
goto COV_FAILED;
}
} else {
len =
ucov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer) - pdu_len, &cov_data);
len = ucov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer) - pdu_len,
&cov_data);
}
pdu_len += len;
if (cov_subscription->flag.issueConfirmedNotifications) {
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 =
datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
bytes_sent = datalink_send_pdu(dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if (bytes_sent > 0) {
status = true;
#if PRINT_ENABLED
@@ -523,13 +509,12 @@ static bool cov_send_request(
#endif
}
COV_FAILED:
COV_FAILED:
return status;
}
static void cov_lifetime_expiration_handler(
unsigned index,
static void cov_lifetime_expiration_handler(unsigned index,
uint32_t elapsed_seconds,
uint32_t lifetime_seconds)
{
@@ -549,9 +534,10 @@ static void cov_lifetime_expiration_handler(
#if PRINT_ENABLED
fprintf(stderr, "COVtimer: PID=%u ",
COV_Subscriptions[index].subscriberProcessIdentifier);
fprintf(stderr, "%s %u ",
bactext_object_type_name(COV_Subscriptions[index].
monitoredObjectIdentifier.type),
fprintf(
stderr, "%s %u ",
bactext_object_type_name(
COV_Subscriptions[index].monitoredObjectIdentifier.type),
COV_Subscriptions[index].monitoredObjectIdentifier.instance);
fprintf(stderr, "time remaining=%u seconds ",
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.
*/
void handler_cov_timer_seconds(
uint32_t elapsed_seconds)
void handler_cov_timer_seconds(uint32_t elapsed_seconds)
{
unsigned index = 0;
uint32_t lifetime_seconds = 0;
@@ -612,8 +597,7 @@ void handler_cov_timer_seconds(
}
}
bool handler_cov_fsm(
void)
bool handler_cov_fsm(void)
{
static int index = 0;
BACNET_OBJECT_TYPE object_type = MAX_BACNET_OBJECT_TYPE;
@@ -638,11 +622,10 @@ bool handler_cov_fsm(
case COV_STATE_MARK:
/* mark any subscriptions where the value has changed */
if (COV_Subscriptions[index].flag.valid) {
object_type = (BACNET_OBJECT_TYPE)
COV_Subscriptions[index].monitoredObjectIdentifier.type;
object_type = (BACNET_OBJECT_TYPE)COV_Subscriptions[index]
.monitoredObjectIdentifier.type;
object_instance =
COV_Subscriptions[index].
monitoredObjectIdentifier.instance;
COV_Subscriptions[index].monitoredObjectIdentifier.instance;
status = Device_COV(object_type, object_instance);
if (status) {
COV_Subscriptions[index].flag.send_requested = true;
@@ -661,11 +644,10 @@ bool handler_cov_fsm(
/* clear the COV flag after checking all subscriptions */
if ((COV_Subscriptions[index].flag.valid) &&
(COV_Subscriptions[index].flag.send_requested)) {
object_type = (BACNET_OBJECT_TYPE)
COV_Subscriptions[index].monitoredObjectIdentifier.type;
object_type = (BACNET_OBJECT_TYPE)COV_Subscriptions[index]
.monitoredObjectIdentifier.type;
object_instance =
COV_Subscriptions[index].
monitoredObjectIdentifier.instance;
COV_Subscriptions[index].monitoredObjectIdentifier.instance;
Device_COV_Clear(object_type, object_instance);
}
index++;
@@ -681,9 +663,8 @@ bool handler_cov_fsm(
(COV_Subscriptions[index].invokeID)) {
if (tsm_invoke_id_free(COV_Subscriptions[index].invokeID)) {
COV_Subscriptions[index].invokeID = 0;
} else
if (tsm_invoke_id_failed(COV_Subscriptions
[index].invokeID)) {
} else if (tsm_invoke_id_failed(
COV_Subscriptions[index].invokeID)) {
tsm_free_invoke_id(COV_Subscriptions[index].invokeID);
COV_Subscriptions[index].invokeID = 0;
}
@@ -710,23 +691,20 @@ bool handler_cov_fsm(
}
}
if (send) {
object_type = (BACNET_OBJECT_TYPE)
COV_Subscriptions[index].
monitoredObjectIdentifier.type;
object_instance =
COV_Subscriptions[index].
monitoredObjectIdentifier.instance;
object_type = (BACNET_OBJECT_TYPE)COV_Subscriptions[index]
.monitoredObjectIdentifier.type;
object_instance = COV_Subscriptions[index]
.monitoredObjectIdentifier.instance;
#if PRINT_ENABLED
fprintf(stderr, "COVtask: Sending...\n");
#endif
/* configure the linked list for the two properties */
bacapp_property_value_list_init(&value_list[0],
MAX_COV_PROPERTIES);
status = Device_Encode_Value_List(object_type,
object_instance, &value_list[0]);
status = Device_Encode_Value_List(
object_type, object_instance, &value_list[0]);
if (status) {
status =
cov_send_request(&COV_Subscriptions[index],
status = cov_send_request(&COV_Subscriptions[index],
&value_list[0]);
}
if (status) {
@@ -748,31 +726,27 @@ bool handler_cov_fsm(
return (cov_task_state == COV_STATE_IDLE);
}
void handler_cov_task(
void)
void handler_cov_task(void)
{
handler_cov_fsm();
}
static bool cov_subscribe(
BACNET_ADDRESS * src,
BACNET_SUBSCRIBE_COV_DATA * cov_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
static bool cov_subscribe(BACNET_ADDRESS *src,
BACNET_SUBSCRIBE_COV_DATA *cov_data,
BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code)
{
bool status = false; /* return value */
BACNET_OBJECT_TYPE object_type = MAX_BACNET_OBJECT_TYPE;
uint32_t object_instance = 0;
object_type =
(BACNET_OBJECT_TYPE) cov_data->monitoredObjectIdentifier.type;
object_type = (BACNET_OBJECT_TYPE)cov_data->monitoredObjectIdentifier.type;
object_instance = cov_data->monitoredObjectIdentifier.instance;
status = Device_Valid_Object_Id(object_type, object_instance);
if (status) {
status = Device_Value_List_Supported(object_type);
if (status) {
status =
cov_list_subscribe(src, cov_data, error_class, error_code);
status = cov_list_subscribe(src, cov_data, error_class, error_code);
} else {
*error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED;
@@ -802,11 +776,9 @@ static bool cov_subscribe(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message.
*/
void handler_cov_subscribe(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_cov_subscribe(uint8_t *service_request, uint16_t service_len,
BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA *service_data)
{
BACNET_SUBSCRIBE_COV_DATA cov_data;
int len = 0;
@@ -824,8 +796,7 @@ void handler_cov_subscribe(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
npdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */
@@ -836,8 +807,7 @@ void handler_cov_subscribe(
error = true;
goto COV_ABORT;
}
len =
cov_subscribe_decode_service_request(service_request, service_len,
len = cov_subscribe_decode_service_request(service_request, service_len,
&cov_data);
#if PRINT_ENABLED
if (len <= 0)
@@ -849,13 +819,12 @@ void handler_cov_subscribe(
}
cov_data.error_class = ERROR_CLASS_OBJECT;
cov_data.error_code = ERROR_CODE_UNKNOWN_OBJECT;
success =
cov_subscribe(src, &cov_data, &cov_data.error_class,
success = cov_subscribe(src, &cov_data, &cov_data.error_class,
&cov_data.error_code);
if (success) {
apdu_len =
encode_simple_ack(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_SUBSCRIBE_COV);
apdu_len = encode_simple_ack(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_SUBSCRIBE_COV);
#if PRINT_ENABLED
fprintf(stderr, "SubscribeCOV: Sending Simple Ack!\n");
#endif
@@ -866,28 +835,26 @@ void handler_cov_subscribe(
fprintf(stderr, "SubscribeCOV: Sending Error!\n");
#endif
}
COV_ABORT:
COV_ABORT:
if (error) {
if (len == BACNET_STATUS_ABORT) {
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
abort_convert_error_code(cov_data.error_code), true);
#if PRINT_ENABLED
fprintf(stderr, "SubscribeCOV: Sending Abort!\n");
#endif
} else if (len == BACNET_STATUS_ERROR) {
apdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_SUBSCRIBE_COV,
cov_data.error_class, cov_data.error_code);
apdu_len = bacerror_encode_apdu(
&Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
SERVICE_CONFIRMED_SUBSCRIBE_COV, cov_data.error_class,
cov_data.error_code);
#if PRINT_ENABLED
fprintf(stderr, "SubscribeCOV: Sending Error!\n");
#endif
} else if (len == BACNET_STATUS_REJECT) {
apdu_len =
reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
apdu_len = reject_encode_apdu(
&Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
reject_convert_error_code(cov_data.error_code));
#if PRINT_ENABLED
fprintf(stderr, "SubscribeCOV: Sending Reject!\n");
@@ -895,8 +862,7 @@ void handler_cov_subscribe(
}
}
pdu_len = npdu_len + apdu_len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
if (bytes_sent <= 0) {
#if PRINT_ENABLED
@@ -905,6 +871,5 @@ void handler_cov_subscribe(
#endif
}
return;
}
+53 -60
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -47,8 +47,7 @@ static char My_Password[32] = "filister";
/** 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.
*/
void handler_dcc_password_set(
char *new_password)
void handler_dcc_password_set(char *new_password)
{
size_t i = 0; /* loop counter */
@@ -95,10 +94,8 @@ char *handler_dcc_password(void)
* decoded from the APDU header of this message.
*/
void handler_device_communication_control(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA *service_data)
{
uint16_t timeDuration = 0;
BACNET_COMMUNICATION_ENABLE_DISABLE state = COMMUNICATION_ENABLE;
@@ -111,17 +108,15 @@ void handler_device_communication_control(
/* encode the NPDU portion of the reply packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
#if PRINT_ENABLED
fprintf(stderr, "DeviceCommunicationControl!\n");
#endif
if (service_data->segmented_message) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr,
"DeviceCommunicationControl: "
@@ -130,21 +125,21 @@ void handler_device_communication_control(
goto DCC_ABORT;
}
/* decode the service request only */
len =
dcc_decode_service_request(service_request, service_len, &timeDuration,
&state, &password);
len = dcc_decode_service_request(service_request, service_len,
&timeDuration, &state, &password);
#if PRINT_ENABLED
if (len > 0)
fprintf(stderr,
"DeviceCommunicationControl: " "timeout=%u state=%u password=%s\n",
(unsigned) timeDuration, (unsigned) state,
"DeviceCommunicationControl: "
"timeout=%u state=%u password=%s\n",
(unsigned)timeDuration, (unsigned)state,
characterstring_value(&password));
#endif
/* bad decoding or something we didn't understand - send an abort */
if (len < 0) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER,
true);
#if PRINT_ENABLED
fprintf(stderr,
"DeviceCommunicationControl: "
@@ -153,9 +148,9 @@ void handler_device_communication_control(
goto DCC_ABORT;
}
if (state >= MAX_BACNET_COMMUNICATION_ENABLE_DISABLE) {
len =
reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION);
len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
REJECT_REASON_UNDEFINED_ENUMERATION);
#if PRINT_ENABLED
fprintf(stderr,
"DeviceCommunicationControl: "
@@ -164,28 +159,26 @@ void handler_device_communication_control(
} else {
#if BAC_ROUTING
/* Check to see if the current Device supports this service. */
len =
Routed_Device_Service_Approval
(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, (int) state,
len = Routed_Device_Service_Approval(
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, (int)state,
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id);
if (len > 0)
goto DCC_ABORT;
#endif
if (characterstring_ansi_same(&password, My_Password)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
len = encode_simple_ack(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL);
#if PRINT_ENABLED
fprintf(stderr,
"DeviceCommunicationControl: " "Sending Simple Ack!\n");
"DeviceCommunicationControl: "
"Sending Simple Ack!\n");
#endif
dcc_set_status_duration(state, timeDuration);
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
len = bacerror_encode_apdu(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
ERROR_CLASS_SECURITY, ERROR_CODE_PASSWORD_FAILURE);
#if PRINT_ENABLED
@@ -195,15 +188,15 @@ void handler_device_communication_control(
#endif
}
}
DCC_ABORT:
DCC_ABORT:
pdu_len += len;
len =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
len = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
if (len <= 0) {
#if PRINT_ENABLED
fprintf(stderr,
"DeviceCommunicationControl: " "Failed to send PDU (%s)!\n",
"DeviceCommunicationControl: "
"Failed to send PDU (%s)!\n",
strerror(errno));
#endif
}
+39 -43
View File
@@ -1,39 +1,39 @@
/**
* @file
* @author Daniel Blazevic <daniel.blazevic@gmail.com>
* @date 2013
* @brief GetAlarmSummary ACK service handling
*
* @section LICENSE
*
* Copyright (C) 2013 Daniel Blazevic <daniel.blazevic@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @section DESCRIPTION
*
* The GetAlarmSummary ACK service handler is used by a client BACnet-user to
* obtain a summary of "active alarms." The term "active alarm" refers to
* BACnet standard objects that have an Event_State property whose value is
* not equal to NORMAL and a Notify_Type property whose value is ALARM.
*/
* @file
* @author Daniel Blazevic <daniel.blazevic@gmail.com>
* @date 2013
* @brief GetAlarmSummary ACK service handling
*
* @section LICENSE
*
* Copyright (C) 2013 Daniel Blazevic <daniel.blazevic@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @section DESCRIPTION
*
* The GetAlarmSummary ACK service handler is used by a client BACnet-user to
* obtain a summary of "active alarms." The term "active alarm" refers to
* BACnet standard objects that have an Event_State property whose value is
* not equal to NORMAL and a Notify_Type property whose value is ALARM.
*/
#include <assert.h>
#include "config.h"
#include "txbuf.h"
@@ -46,7 +46,6 @@
#include "handlers.h"
#include "get_alarm_sum.h"
/** Example function to handle a GetAlarmSummary ACK.
*
* @param service_request [in] The contents of the service request.
@@ -56,19 +55,16 @@
* decoded from the APDU header of this message.
*/
void get_alarm_summary_ack_handler(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
uint8_t* service_request, uint16_t service_len, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_ACK_DATA* service_data)
{
uint16_t apdu_len = 0;
uint16_t len = 0;
BACNET_GET_ALARM_SUMMARY_DATA data;
while (service_len - len) {
apdu_len =
get_alarm_summary_ack_decode_apdu_data(&service_request[len],
service_len - len, &data);
apdu_len = get_alarm_summary_ack_decode_apdu_data(
&service_request[len], service_len - len, &data);
len += apdu_len;
+46 -61
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -41,8 +41,7 @@
static get_alarm_summary_function Get_Alarm_Summary[MAX_BACNET_OBJECT_TYPE];
void handler_get_alarm_summary_set(
BACNET_OBJECT_TYPE object_type,
void handler_get_alarm_summary_set(BACNET_OBJECT_TYPE object_type,
get_alarm_summary_function pFunction)
{
if (object_type < MAX_BACNET_OBJECT_TYPE) {
@@ -50,11 +49,9 @@ void handler_get_alarm_summary_set(
}
}
void handler_get_alarm_summary(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_get_alarm_summary(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data)
{
int len = 0;
int pdu_len = 0;
@@ -68,41 +65,33 @@ void handler_get_alarm_summary(
BACNET_NPDU_DATA npdu_data;
BACNET_GET_ALARM_SUMMARY_DATA getalarm_data;
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr,
"GetAlarmSummary: Segmented message. Sending Abort!\n");
fprintf(stderr, "GetAlarmSummary: Segmented message. Sending Abort!\n");
#endif
goto GET_ALARM_SUMMARY_ABORT;
}
/* init header */
apdu_len =
get_alarm_summary_ack_encode_apdu_init(&Handler_Transmit_Buffer
[pdu_len], service_data->invoke_id);
apdu_len = get_alarm_summary_ack_encode_apdu_init(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id);
for (i = 0; i < MAX_BACNET_OBJECT_TYPE; i++) {
if (Get_Alarm_Summary[i]) {
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) {
len =
get_alarm_summary_ack_encode_apdu_data
(&Handler_Transmit_Buffer[pdu_len + apdu_len],
len = get_alarm_summary_ack_encode_apdu_data(
&Handler_Transmit_Buffer[pdu_len + apdu_len],
service_data->max_resp - apdu_len, &getalarm_data);
if (len <= 0) {
error = true;
@@ -116,39 +105,35 @@ void handler_get_alarm_summary(
}
}
#if PRINT_ENABLED
fprintf(stderr, "GetAlarmSummary: Sending response!\n");
#endif
GET_ALARM_SUMMARY_ERROR:
GET_ALARM_SUMMARY_ERROR:
if (error) {
if (len == BACNET_STATUS_ABORT) {
/* BACnet APDU too small to fit data, so proper response is Abort */
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr,
"GetAlarmSummary: Reply too big to fit into APDU!\n");
#endif
} else {
apdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_GET_ALARM_SUMMARY,
ERROR_CLASS_PROPERTY, ERROR_CODE_OTHER);
apdu_len = bacerror_encode_apdu(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
SERVICE_CONFIRMED_GET_ALARM_SUMMARY, ERROR_CLASS_PROPERTY,
ERROR_CODE_OTHER);
#if PRINT_ENABLED
fprintf(stderr, "GetAlarmSummary: Sending Error!\n");
#endif
}
}
GET_ALARM_SUMMARY_ABORT:
GET_ALARM_SUMMARY_ABORT:
pdu_len += apdu_len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0) {
+65 -78
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -43,33 +43,27 @@
static get_event_info_function Get_Event_Info[MAX_BACNET_OBJECT_TYPE];
/** print eventState
*/
void ge_ack_print_data(
BACNET_GET_EVENT_INFORMATION_DATA * data,
void ge_ack_print_data(BACNET_GET_EVENT_INFORMATION_DATA* data,
uint32_t device_id)
{
BACNET_GET_EVENT_INFORMATION_DATA *act_data = data;
BACNET_GET_EVENT_INFORMATION_DATA* act_data = data;
const char* state_strs[] = {"NO", "FA", "ON", "HL", "LL"};
printf("DeviceID\tType\tInstance\teventState\n");
printf("--------------- ------- --------------- ---------------\n");
int count = 0;
while (act_data) {
printf("%u\t\t%u\t%u\t\t%s\n",
device_id,
act_data->objectIdentifier.type,
act_data->objectIdentifier.instance,
state_strs[data->eventState]
);
printf(
"%u\t\t%u\t%u\t\t%s\n", device_id, act_data->objectIdentifier.type,
act_data->objectIdentifier.instance, state_strs[data->eventState]);
act_data = act_data->next;
count++;
}
printf("\n%u\t Total\n",count);
printf("\n%u\t Total\n", count);
}
void handler_get_event_information_set(
BACNET_OBJECT_TYPE object_type,
void handler_get_event_information_set(BACNET_OBJECT_TYPE object_type,
get_event_info_function pFunction)
{
if (object_type < MAX_BACNET_OBJECT_TYPE) {
@@ -77,11 +71,9 @@ void handler_get_event_information_set(
}
}
void handler_get_event_information(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_get_event_information(uint8_t* service_request,
uint16_t service_len, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data)
{
int len = 0;
int pdu_len = 0;
@@ -104,38 +96,35 @@ void handler_get_event_information(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr,
"GetEventInformation: " "Segmented message. Sending Abort!\n");
"GetEventInformation: "
"Segmented message. Sending Abort!\n");
#endif
goto GET_EVENT_ABORT;
}
len =
getevent_decode_service_request(service_request, service_len,
len = getevent_decode_service_request(service_request, service_len,
&object_id);
if (len < 0) {
/* bad decoding - send an abort */
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER,
true);
#if PRINT_ENABLED
fprintf(stderr,
"GetEventInformation: Bad Encoding. Sending Abort!\n");
fprintf(stderr, "GetEventInformation: Bad Encoding. Sending Abort!\n");
#endif
goto GET_EVENT_ABORT;
}
len =
getevent_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len],
len = getevent_ack_encode_apdu_init(
&Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer) - pdu_len, service_data->invoke_id);
if (len <= 0) {
error = true;
@@ -146,9 +135,10 @@ void handler_get_event_information(
for (i = 0; i < MAX_BACNET_OBJECT_TYPE; i++) {
if (Get_Event_Info[i]) {
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) {
/* 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 ==
getevent_data.objectIdentifier.type) &&
@@ -162,9 +152,9 @@ void handler_get_event_information(
}
getevent_data.next = NULL;
len =
getevent_ack_encode_apdu_data(&Handler_Transmit_Buffer
[pdu_len], sizeof(Handler_Transmit_Buffer) - pdu_len,
len = getevent_ack_encode_apdu_data(
&Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer) - pdu_len,
&getevent_data);
if (len <= 0) {
error = true;
@@ -195,8 +185,8 @@ void handler_get_event_information(
}
}
}
len =
getevent_ack_encode_apdu_end(&Handler_Transmit_Buffer[pdu_len],
len = getevent_ack_encode_apdu_end(
&Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer) - pdu_len, more_events);
if (len <= 0) {
error = true;
@@ -205,36 +195,33 @@ void handler_get_event_information(
#if PRINT_ENABLED
fprintf(stderr, "Got a GetEventInformation request: Sending Ack!\n");
#endif
GET_EVENT_ERROR:
GET_EVENT_ERROR:
if (error) {
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
if (len == -2) {
/* BACnet APDU too small to fit data, so proper response is Abort */
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
len = abort_encode_apdu(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr,
"GetEventInformation: " "Reply too big to fit into APDU!\n");
"GetEventInformation: "
"Reply too big to fit into APDU!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
error_class, error_code);
len = bacerror_encode_apdu(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "GetEventInformation: Sending Error!\n");
#endif
}
}
GET_EVENT_ABORT:
GET_EVENT_ABORT:
pdu_len += len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
+3 -6
View File
@@ -59,9 +59,7 @@
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_ACK_DATA information
* decoded from the APDU header of this message.
*/
void get_event_ack_handler(
uint8_t *service_request,
uint16_t service_len,
void get_event_ack_handler(uint8_t *service_request, uint16_t service_len,
BACNET_ADDRESS *src,
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];
}
apdu_len =
getevent_ack_decode_service_request(&service_request[0],
service_len, &get_event_data[0], &more_events);
apdu_len = getevent_ack_decode_service_request(
&service_request[0], service_len, &get_event_data[0], &more_events);
if (apdu_len > 0) {
/* FIXME: Add code to process get_event_data */
+32 -38
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -42,10 +42,8 @@
* @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source.
*/
void handler_i_am_add(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
void handler_i_am_add(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src)
{
int len = 0;
uint32_t device_id = 0;
@@ -53,9 +51,8 @@ void handler_i_am_add(
int segmentation = 0;
uint16_t vendor_id = 0;
(void) service_len;
len =
iam_decode_service_request(service_request, &device_id, &max_apdu,
(void)service_len;
len = iam_decode_service_request(service_request, &device_id, &max_apdu,
&segmentation, &vendor_id);
#if PRINT_ENABLED
fprintf(stderr, "Received I-Am Request");
@@ -63,7 +60,7 @@ void handler_i_am_add(
if (len != -1) {
#if PRINT_ENABLED
fprintf(stderr, " from %lu, MAC = %d.%d.%d.%d.%d.%d\n",
(unsigned long) device_id, src->mac[0], src->mac[1], src->mac[2],
(unsigned long)device_id, src->mac[0], src->mac[1], src->mac[2],
src->mac[3], src->mac[4], src->mac[5]);
#endif
address_add(device_id, max_apdu, src);
@@ -84,10 +81,8 @@ void handler_i_am_add(
* @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source.
*/
void handler_i_am_bind(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
void handler_i_am_bind(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src)
{
int len = 0;
uint32_t device_id = 0;
@@ -95,9 +90,8 @@ void handler_i_am_bind(
int segmentation = 0;
uint16_t vendor_id = 0;
(void) service_len;
len =
iam_decode_service_request(service_request, &device_id, &max_apdu,
(void)service_len;
len = iam_decode_service_request(service_request, &device_id, &max_apdu,
&segmentation, &vendor_id);
if (len > 0) {
/* only add address if requested to bind */
+29 -31
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -41,24 +41,22 @@
* @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source.
*/
void handler_i_have(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
void handler_i_have(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src)
{
int len = 0;
BACNET_I_HAVE_DATA data;
(void) service_len;
(void) src;
(void)service_len;
(void)src;
len = ihave_decode_service_request(service_request, service_len, &data);
if (len != -1) {
#if PRINT_ENABLED
fprintf(stderr, "I-Have: %s %lu from %s %lu!\r\n",
bactext_object_type_name(data.object_id.type),
(unsigned long) data.object_id.instance,
(unsigned long)data.object_id.instance,
bactext_object_type_name(data.device_id.type),
(unsigned long) data.device_id.instance);
(unsigned long)data.device_id.instance);
#endif
} else {
#if PRINT_ENABLED
+48 -48
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -40,11 +40,9 @@
/** @file h_lso.c Handles BACnet Life Safey Operation messages. */
void handler_lso(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_lso(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data)
{
BACNET_LSO_DATA data;
int len = 0;
@@ -56,15 +54,13 @@ void handler_lso(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr, "LSO: Segmented message. Sending Abort!\n");
#endif
@@ -78,9 +74,9 @@ void handler_lso(
#endif
if (len < 0) {
/* bad decoding - send an abort */
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER,
true);
#if PRINT_ENABLED
fprintf(stderr, "LSO: Bad Encoding. Sending Abort!\n");
#endif
@@ -92,26 +88,30 @@ void handler_lso(
*/
#if PRINT_ENABLED
fprintf(stderr,
"Life Safety Operation: Received operation %d from process id %lu for object %lu\n",
data.operation, (unsigned long) data.processId,
(unsigned long) data.targetObject.instance);
"Life Safety Operation: Received operation %d from process id %lu "
"for object %lu\n",
data.operation, (unsigned long)data.processId,
(unsigned long)data.targetObject.instance);
#endif
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION);
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION);
#if PRINT_ENABLED
fprintf(stderr, "Life Safety Operation: " "Sending Simple Ack!\n");
fprintf(stderr,
"Life Safety Operation: "
"Sending Simple Ack!\n");
#endif
LSO_ABORT:
LSO_ABORT:
pdu_len += len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
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));
#endif
+30 -31
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include "bacdef.h"
@@ -63,14 +63,13 @@
* @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.
*/
void npdu_handler(
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
void npdu_handler(BACNET_ADDRESS* src, /* source address */
uint8_t* pdu, /* PDU data */
uint16_t pdu_len)
{ /* length PDU */
int apdu_offset = 0;
BACNET_ADDRESS dest = { 0 };
BACNET_NPDU_DATA npdu_data = { 0 };
BACNET_ADDRESS dest = {0};
BACNET_NPDU_DATA npdu_data = {0};
/* only handle the version that we know how to handle */
if (pdu[0] == BACNET_PROTOCOL_VERSION) {
@@ -93,18 +92,18 @@ void npdu_handler(
/* then enter IDLE - ignore the PDU */
} else {
apdu_handler(src, &pdu[apdu_offset],
(uint16_t) (pdu_len - apdu_offset));
(uint16_t)(pdu_len - apdu_offset));
}
} else {
#if PRINT_ENABLED
printf("NPDU: DNET=%u. Discarded!\n", (unsigned) dest.net);
printf("NPDU: DNET=%u. Discarded!\n", (unsigned)dest.net);
#endif
}
}
} else {
#if PRINT_ENABLED
printf("NPDU: BACnet Protocol Version=%u. Discarded!\n",
(unsigned) pdu[0]);
(unsigned)pdu[0]);
#endif
}
+71 -93
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -52,8 +52,7 @@ DATABLOCK MyData[MYMAXBLOCK];
uint8_t IOBufferPT[MAX_APDU]; /* Buffer for building response in */
static void ProcessPT(
BACNET_PRIVATE_TRANSFER_DATA * data)
static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
{
int iLen; /* Index to current location in data */
char cBlockNumber;
@@ -66,8 +65,7 @@ static void ProcessPT(
iLen = 0;
/* Decode the block number */
tag_len =
decode_tag_number_and_value(&data->serviceParameters[iLen],
tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen],
&tag_number, &len_value_type);
iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
@@ -77,10 +75,9 @@ static void ProcessPT(
return;
}
iLen +=
decode_unsigned(&data->serviceParameters[iLen], len_value_type,
iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type,
&ulTemp);
cBlockNumber = (char) ulTemp;
cBlockNumber = (char)ulTemp;
if (cBlockNumber < MY_MAX_BLOCK) {
if (data->serviceNumber == MY_SVC_READ) {
/* Read Response is an unsigned int with
@@ -101,20 +98,16 @@ static void ProcessPT(
iLen +=
encode_application_unsigned(&IOBufferPT[iLen], cBlockNumber);
/* 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 +=
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 +=
encode_application_character_string(&IOBufferPT[iLen],
&bsTemp);
encode_application_character_string(&IOBufferPT[iLen], &bsTemp);
} else {
/* Write operation */
/* Write block consists of the block number
@@ -124,47 +117,40 @@ static void ProcessPT(
response which is 0 for success and
a non 0 error code otherwise. */
tag_len =
decode_tag_number_and_value(&data->serviceParameters[iLen],
&tag_number, &len_value_type);
tag_len = decode_tag_number_and_value(
&data->serviceParameters[iLen], &tag_number, &len_value_type);
iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
data->serviceParametersLen = 0;
return;
}
iLen +=
decode_unsigned(&data->serviceParameters[iLen], len_value_type,
&ulTemp);
MyData[(int8_t) cBlockNumber].cMyByte1 = (char) ulTemp;
iLen += decode_unsigned(&data->serviceParameters[iLen],
len_value_type, &ulTemp);
MyData[(int8_t)cBlockNumber].cMyByte1 = (char)ulTemp;
tag_len =
decode_tag_number_and_value(&data->serviceParameters[iLen],
&tag_number, &len_value_type);
tag_len = decode_tag_number_and_value(
&data->serviceParameters[iLen], &tag_number, &len_value_type);
iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
data->serviceParametersLen = 0;
return;
}
iLen +=
decode_unsigned(&data->serviceParameters[iLen], len_value_type,
&ulTemp);
MyData[(int8_t) cBlockNumber].cMyByte2 = (char) ulTemp;
iLen += decode_unsigned(&data->serviceParameters[iLen],
len_value_type, &ulTemp);
MyData[(int8_t)cBlockNumber].cMyByte2 = (char)ulTemp;
tag_len =
decode_tag_number_and_value(&data->serviceParameters[iLen],
&tag_number, &len_value_type);
tag_len = decode_tag_number_and_value(
&data->serviceParameters[iLen], &tag_number, &len_value_type);
iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_REAL) {
data->serviceParametersLen = 0;
return;
}
iLen +=
decode_real(&data->serviceParameters[iLen],
&MyData[(int8_t) cBlockNumber].fMyReal);
iLen += decode_real(&data->serviceParameters[iLen],
&MyData[(int8_t)cBlockNumber].fMyReal);
tag_len =
decode_tag_number_and_value(&data->serviceParameters[iLen],
&tag_number, &len_value_type);
tag_len = decode_tag_number_and_value(
&data->serviceParameters[iLen], &tag_number, &len_value_type);
iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_CHARACTER_STRING) {
data->serviceParametersLen = 0;
@@ -173,10 +159,10 @@ static void ProcessPT(
decode_character_string(&data->serviceParameters[iLen],
len_value_type, &bsTemp);
/* Only copy as much as we can accept */
strncpy((char *) MyData[(int8_t) cBlockNumber].sMyString,
strncpy((char *)MyData[(int8_t)cBlockNumber].sMyString,
characterstring_value(&bsTemp), MY_MAX_STR);
/* Make sure it is nul terminated */
MyData[(int8_t) cBlockNumber].sMyString[MY_MAX_STR] = '\0';
MyData[(int8_t)cBlockNumber].sMyString[MY_MAX_STR] = '\0';
/* Signal success */
iLen = encode_application_unsigned(&IOBufferPT[0], MY_ERR_OK);
}
@@ -198,12 +184,9 @@ static void ProcessPT(
*
*/
void handler_conf_private_trans(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_conf_private_trans(uint8_t *service_request, uint16_t service_len,
BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA *service_data)
{
BACNET_PRIVATE_TRANSFER_DATA data;
int len;
@@ -230,28 +213,25 @@ void handler_conf_private_trans(
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
if (service_data->segmented_message) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr, "CPT: Segmented Message. Sending Abort!\n");
#endif
goto CPT_ABORT;
}
len =
ptransfer_decode_service_request(service_request, service_len, &data);
len = ptransfer_decode_service_request(service_request, service_len, &data);
/* bad decoding - send an abort */
if (len < 0) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER,
true);
#if PRINT_ENABLED
fprintf(stderr, "CPT: Bad Encoding. Sending Abort!\n");
#endif
@@ -278,8 +258,7 @@ void handler_conf_private_trans(
fprintf(stderr, "CPT: Error servicing request!\n");
#endif
}
len =
ptransfer_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
len = ptransfer_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data);
} else { /* Not our vendor ID or bad service parameter */
@@ -292,14 +271,13 @@ void handler_conf_private_trans(
}
if (error) {
len =
ptransfer_error_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, error_class, error_code, &data);
len = ptransfer_error_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, error_class,
error_code, &data);
}
CPT_ABORT:
CPT_ABORT:
pdu_len += len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
+57 -70
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -45,11 +45,10 @@
/** @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(
char cBlockNum,
uint8_t * pData)
static void DecodeBlock(char cBlockNum, uint8_t *pData)
{
int iLen;
uint32_t ulTemp;
@@ -65,28 +64,25 @@ static void DecodeBlock(
return;
tag_len =
decode_tag_number_and_value(&pData[iLen], &tag_number,
&len_value_type);
decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT)
return;
iLen += decode_unsigned(&pData[iLen], len_value_type, &ulTemp);
Response.cMyByte1 = (char) ulTemp;
Response.cMyByte1 = (char)ulTemp;
tag_len =
decode_tag_number_and_value(&pData[iLen], &tag_number,
&len_value_type);
decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT)
return;
iLen += decode_unsigned(&pData[iLen], len_value_type, &ulTemp);
Response.cMyByte2 = (char) ulTemp;
Response.cMyByte2 = (char)ulTemp;
tag_len =
decode_tag_number_and_value(&pData[iLen], &tag_number,
&len_value_type);
decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_REAL)
return;
@@ -94,27 +90,25 @@ static void DecodeBlock(
iLen += decode_real(&pData[iLen], &Response.fMyReal);
tag_len =
decode_tag_number_and_value(&pData[iLen], &tag_number,
&len_value_type);
decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_CHARACTER_STRING)
return;
iLen += decode_character_string(&pData[iLen], len_value_type, &bsName);
strncpy((char *) Response.sMyString, characterstring_value(&bsName),
strncpy((char *)Response.sMyString, characterstring_value(&bsName),
MY_MAX_STR);
Response.sMyString[MY_MAX_STR] = '\0'; /* Make sure it is nul terminated */
printf("Private Transfer Read Block Response\n");
printf("Data Block: %d\n", (int) cBlockNum);
printf(" First Byte : %d\n", (int) Response.cMyByte1);
printf(" Second Byte : %d\n", (int) Response.cMyByte2);
printf("Data Block: %d\n", (int)cBlockNum);
printf(" First Byte : %d\n", (int)Response.cMyByte1);
printf(" Second Byte : %d\n", (int)Response.cMyByte2);
printf(" Real : %f\n", Response.fMyReal);
printf(" String : %s\n\n", Response.sMyString);
}
static void ProcessPTA(
BACNET_PRIVATE_TRANSFER_DATA * data)
static void ProcessPTA(BACNET_PRIVATE_TRANSFER_DATA *data)
{
int iLen; /* Index to current location in data */
uint32_t uiErrorCode;
@@ -128,8 +122,7 @@ static void ProcessPTA(
/* Error code is returned for read and write operations */
tag_len =
decode_tag_number_and_value(&data->serviceParameters[iLen],
tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen],
&tag_number, &len_value_type);
iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
@@ -138,18 +131,18 @@ static void ProcessPTA(
#endif
return;
}
iLen +=
decode_unsigned(&data->serviceParameters[iLen], len_value_type,
iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type,
&uiErrorCode);
if (data->serviceNumber == MY_SVC_READ) { /* Read I/O block so should be full block of data or error */
/* Decode the error type and if necessary block number and then fetch the info */
if (data->serviceNumber == MY_SVC_READ) { /* Read I/O block so should be
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) {
/* Block Number */
tag_len =
decode_tag_number_and_value(&data->serviceParameters[iLen],
&tag_number, &len_value_type);
tag_len = decode_tag_number_and_value(
&data->serviceParameters[iLen], &tag_number, &len_value_type);
iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
#if PRINT_ENABLED
@@ -158,25 +151,21 @@ static void ProcessPTA(
return;
}
iLen +=
decode_unsigned(&data->serviceParameters[iLen], len_value_type,
&ulTemp);
cBlockNumber = (char) ulTemp;
iLen += decode_unsigned(&data->serviceParameters[iLen],
len_value_type, &ulTemp);
cBlockNumber = (char)ulTemp;
DecodeBlock(cBlockNumber, &data->serviceParameters[iLen]);
} else { /* Read error */
printf
("Private Transfer read operation returned error code: %lu\n",
(unsigned long) uiErrorCode);
printf("Private Transfer read operation returned error code: %lu\n",
(unsigned long)uiErrorCode);
return;
}
} else { /* Write I/O block - should just be an OK type message */
printf("Private Transfer write operation returned error code: %lu\n",
(unsigned long) uiErrorCode);
(unsigned long)uiErrorCode);
}
}
/*
* This is called when we receive a private transfer packet ack.
* We parse the response which the remote application generated
@@ -184,15 +173,13 @@ static void ProcessPTA(
*/
void handler_conf_private_trans_ack(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{
BACNET_PRIVATE_TRANSFER_DATA data;
int len;
/*
/*
* Note:
* We currently don't look at the source address and service data
* but we probably should to verify that the ack is oneit is what
@@ -204,13 +191,13 @@ void handler_conf_private_trans_ack(
len = 0;
#if PRINT_ENABLED
printf("Received Confirmed Private Transfer Ack!\n");
#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 PRINT_ENABLED
printf("cpta: Bad Encoding!\n");
+47 -55
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -63,11 +63,9 @@
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message.
*/
void handler_reinitialize_device(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_reinitialize_device(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data)
{
BACNET_REINITIALIZE_DEVICE_DATA rd_data;
int len = 0;
@@ -78,17 +76,15 @@ void handler_reinitialize_device(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
#if PRINT_ENABLED
fprintf(stderr, "ReinitializeDevice!\n");
#endif
if (service_data->segmented_message) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr,
"ReinitializeDevice: Sending Abort - segmented message.\n");
@@ -96,13 +92,12 @@ void handler_reinitialize_device(
goto RD_ABORT;
}
/* decode the service request only */
len =
rd_decode_service_request(service_request, service_len, &rd_data.state,
&rd_data.password);
len = rd_decode_service_request(service_request, service_len,
&rd_data.state, &rd_data.password);
#if PRINT_ENABLED
if (len > 0) {
fprintf(stderr, "ReinitializeDevice: state=%u password=%s\n",
(unsigned) rd_data.state,
(unsigned)rd_data.state,
characterstring_value(&rd_data.password));
} else {
fprintf(stderr, "ReinitializeDevice: Unable to decode request!\n");
@@ -110,9 +105,9 @@ void handler_reinitialize_device(
#endif
/* bad decoding or something we didn't understand - send an abort */
if (len < 0) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER,
true);
#if PRINT_ENABLED
fprintf(stderr,
"ReinitializeDevice: Sending Abort - could not decode.\n");
@@ -121,9 +116,9 @@ void handler_reinitialize_device(
}
/* check the data from the request */
if (rd_data.state >= BACNET_REINIT_MAX) {
len =
reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION);
len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
REJECT_REASON_UNDEFINED_ENUMERATION);
#if PRINT_ENABLED
fprintf(stderr,
"ReinitializeDevice: Sending Reject - undefined enumeration\n");
@@ -131,36 +126,33 @@ void handler_reinitialize_device(
} else {
#if BAC_ROUTING
/* Check to see if the current Device supports this service. */
len =
Routed_Device_Service_Approval
(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, (int) rd_data.state,
len = Routed_Device_Service_Approval(
SERVICE_CONFIRMED_REINITIALIZE_DEVICE, (int)rd_data.state,
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id);
if (len > 0)
goto RD_ABORT;
#endif
if (Device_Reinitialize(&rd_data)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_REINITIALIZE_DEVICE);
#if PRINT_ENABLED
fprintf(stderr, "ReinitializeDevice: Sending Simple Ack!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
rd_data.error_class, rd_data.error_code);
#if PRINT_ENABLED
fprintf(stderr, "ReinitializeDevice: Sending Error.\n");
#endif
}
}
RD_ABORT:
RD_ABORT:
pdu_len += len;
len =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
len = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
if (len <= 0) {
#if PRINT_ENABLED
+52 -61
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Acknowledging the contribution of code and ideas used here that
* came from Paul Chapman's vmac demo project. */
@@ -47,10 +47,8 @@
#include "bvlc.h"
#endif
/** @file h_routed_npdu.c Handles messages at the NPDU level of the BACnet stack,
* including routing and network control messages. */
/** @file h_routed_npdu.c Handles messages at the NPDU level of the BACnet
* stack, including routing and network control messages. */
/** 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
@@ -61,19 +59,17 @@
* @param src [in] The routing source information, if any.
* If src->net and src->len are 0, there is no
* routing source information.
* @param DNET_list [in] List of our reachable downstream BACnet Network numbers.
* Normally just one valid entry; terminated with a -1 value.
* @param DNET_list [in] List of our reachable downstream BACnet Network
* numbers. Normally just one valid entry; terminated with a -1 value.
* @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
* bytes that have already been decoded.
* @param npdu_len [in] The length of the remaining NPDU message in npdu[].
*/
static void network_control_handler(
BACNET_ADDRESS * src,
int *DNET_list,
BACNET_NPDU_DATA * npdu_data,
uint8_t * npdu,
static void network_control_handler(BACNET_ADDRESS *src, int *DNET_list,
BACNET_NPDU_DATA *npdu_data, uint8_t *npdu,
uint16_t npdu_len)
{
uint16_t npdu_offset = 0;
@@ -109,8 +105,8 @@ static void network_control_handler(
* later for congestion control - then it could matter.
*/
debug_printf("%s for Networks: ",
bactext_network_layer_msg_name
(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK));
bactext_network_layer_msg_name(
NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK));
while (npdu_len >= 2) {
len = decode_unsigned16(&npdu[npdu_offset], &dnet);
debug_printf("%hu", dnet);
@@ -129,8 +125,8 @@ static void network_control_handler(
if (npdu_len >= 3) {
decode_unsigned16(&npdu[1], &dnet);
debug_printf("Received %s for Network: ",
bactext_network_layer_msg_name
(NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK));
bactext_network_layer_msg_name(
NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK));
debug_printf("%hu, Reason code: %d \n", dnet, npdu[0]);
}
break;
@@ -168,8 +164,8 @@ static void network_control_handler(
break;
default:
/* An unrecognized message is bad; send an error response. */
Send_Reject_Message_To_Network(src,
NETWORK_REJECT_UNKNOWN_MESSAGE_TYPE, DNET_list[0]);
Send_Reject_Message_To_Network(
src, NETWORK_REJECT_UNKNOWN_MESSAGE_TYPE, DNET_list[0]);
/* Sending our DNET doesn't make a lot of sense, does it? */
break;
}
@@ -186,16 +182,13 @@ static void network_control_handler(
*
* @param src [in] The BACNET_ADDRESS of the message's source.
* @param dest [in] The BACNET_ADDRESS of the message's destination.
* @param DNET_list [in] List of our reachable downstream BACnet Network numbers.
* Normally just one valid entry; terminated with a -1 value.
* @param DNET_list [in] List of our reachable downstream BACnet Network
* 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_len [in] The total (remaining) length of the apdu.
*/
static void routed_apdu_handler(
BACNET_ADDRESS * src,
BACNET_ADDRESS * dest,
int *DNET_list,
uint8_t * apdu,
static void routed_apdu_handler(BACNET_ADDRESS *src, BACNET_ADDRESS *dest,
int *DNET_list, uint8_t *apdu,
uint16_t apdu_len)
{
int cursor = 0; /* Starting hint */
@@ -260,20 +253,17 @@ static void routed_apdu_handler(
* think this project's code has any use for the src info
* on return from this handler, since the response has
* already been sent via the apdu_handler.
* @param DNET_list [in] List of our reachable downstream BACnet Network numbers.
* Normally just one valid entry; terminated with a -1 value.
* @param DNET_list [in] List of our reachable downstream BACnet Network
* 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_len [in] The size of the received message in the pdu[] buffer.
*/
void routing_npdu_handler(
BACNET_ADDRESS * src,
int *DNET_list,
uint8_t * pdu,
void routing_npdu_handler(BACNET_ADDRESS *src, int *DNET_list, uint8_t *pdu,
uint16_t pdu_len)
{
int apdu_offset = 0;
BACNET_ADDRESS dest = { 0 };
BACNET_NPDU_DATA npdu_data = { 0 };
BACNET_ADDRESS dest = {0};
BACNET_NPDU_DATA npdu_data = {0};
/* only handle the version that we know how to handle */
if (pdu[0] == BACNET_PROTOCOL_VERSION) {
@@ -283,7 +273,8 @@ void routing_npdu_handler(
} else if (npdu_data.network_layer_message) {
if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) {
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 {
/* The DNET is set, but we don't support downstream routers,
* so we just silently drop this network layer message,
@@ -292,14 +283,14 @@ void routing_npdu_handler(
} else if (apdu_offset <= pdu_len) {
if ((dest.net == 0) || (npdu_data.hop_count > 1))
routed_apdu_handler(src, &dest, DNET_list, &pdu[apdu_offset],
(uint16_t) (pdu_len - apdu_offset));
(uint16_t)(pdu_len - apdu_offset));
/* Else, hop_count bottomed out and we discard this one. */
}
} else {
/* Should we send NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK? */
debug_printf
("NPDU: Unsupported BACnet Protocol Version=%u. Discarded!\n",
(unsigned) pdu[0]);
debug_printf(
"NPDU: Unsupported BACnet Protocol Version=%u. Discarded!\n",
(unsigned)pdu[0]);
}
return;
+40 -49
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -44,7 +44,6 @@
/** @file h_rp.c Handles Read Property requests. */
/** Handler for a ReadProperty Service request.
* @ingroup DSRP
* This handler will be invoked by apdu_handler() if it has been enabled
@@ -64,11 +63,9 @@
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message.
*/
void handler_read_property(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_read_property(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data)
{
BACNET_READ_PROPERTY_DATA rpdata;
int len = 0;
@@ -85,8 +82,7 @@ void handler_read_property(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
npdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */
@@ -116,8 +112,7 @@ void handler_read_property(
rpdata.object_instance = Device_Object_Instance_Number();
}
apdu_len =
rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
apdu_len = rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id, &rpdata);
/* configure our storage */
rpdata.application_data = &Handler_Transmit_Buffer[npdu_len + apdu_len];
@@ -126,9 +121,8 @@ void handler_read_property(
len = Device_Read_Property(&rpdata);
if (len >= 0) {
apdu_len += len;
len =
rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer
[npdu_len + apdu_len]);
len = rp_ack_encode_apdu_object_property_end(
&Handler_Transmit_Buffer[npdu_len + apdu_len]);
apdu_len += len;
if (apdu_len > service_data->max_resp) {
/* too big for the sender - send an abort
@@ -160,28 +154,26 @@ void handler_read_property(
#endif
}
RP_FAILURE:
RP_FAILURE:
if (error) {
if (len == BACNET_STATUS_ABORT) {
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
abort_convert_error_code(rpdata.error_code), true);
#if PRINT_ENABLED
fprintf(stderr, "RP: Sending Abort!\n");
#endif
} else if (len == BACNET_STATUS_ERROR) {
apdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
rpdata.error_class, rpdata.error_code);
apdu_len = bacerror_encode_apdu(
&Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
SERVICE_CONFIRMED_READ_PROPERTY, rpdata.error_class,
rpdata.error_code);
#if PRINT_ENABLED
fprintf(stderr, "RP: Sending Error!\n");
#endif
} else if (len == BACNET_STATUS_REJECT) {
apdu_len =
reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
apdu_len = reject_encode_apdu(
&Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
reject_convert_error_code(rpdata.error_code));
#if PRINT_ENABLED
fprintf(stderr, "RP: Sending Reject!\n");
@@ -190,8 +182,7 @@ void handler_read_property(
}
pdu_len = npdu_len + apdu_len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
if (bytes_sent <= 0) {
#if PRINT_ENABLED
+36 -43
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
@@ -46,8 +46,7 @@
/** For debugging...
* @param [in] data portion of the ACK
*/
void rp_ack_print_data(
BACNET_READ_PROPERTY_DATA * data)
void rp_ack_print_data(BACNET_READ_PROPERTY_DATA *data)
{
BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
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? */
/* value? need to loop until all of the len is gone... */
for (;;) {
len =
bacapp_decode_application_data(application_data,
(uint8_t) application_data_len, &value);
len = bacapp_decode_application_data(
application_data, (uint8_t)application_data_len, &value);
if (first_value && (len < application_data_len)) {
first_value = false;
#if PRINT_ENABLED
@@ -102,7 +100,6 @@ void rp_ack_print_data(
}
}
/** Handler for a ReadProperty ACK.
* @ingroup DSRP
* Doesn't actually do anything, except, for debugging, to
@@ -114,17 +111,15 @@ void rp_ack_print_data(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message.
*/
void handler_read_property_ack(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
void handler_read_property_ack(uint8_t *service_request, uint16_t service_len,
BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{
int len = 0;
BACNET_READ_PROPERTY_DATA data;
(void) src;
(void) service_data; /* we could use these... */
(void)src;
(void)service_data; /* we could use these... */
len = rp_ack_decode_service_request(service_request, service_len, &data);
#if 0
fprintf(stderr, "Received Read-Property Ack!\n");
@@ -148,9 +143,7 @@ void handler_read_property_ack(
* or -1 on decoding error.
*/
int rp_ack_fully_decode_service_request(
uint8_t * apdu,
int apdu_len,
BACNET_READ_ACCESS_DATA * read_access_data)
uint8_t *apdu, int apdu_len, BACNET_READ_ACCESS_DATA *read_access_data)
{
int decoded_len = 0; /* return value */
BACNET_READ_PROPERTY_DATA rp1data;
@@ -174,7 +167,8 @@ int rp_ack_fully_decode_service_request(
}
rp1_property->propertyIdentifier = rp1data.object_property;
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 = ?? */
/* rp_ack_decode_service_request() processing already removed the
* Opening and Closing '3' Tags.
@@ -187,9 +181,8 @@ int rp_ack_fully_decode_service_request(
old_value = value;
while (value && vdata && (vlen > 0)) {
if (IS_CONTEXT_SPECIFIC(*vdata)) {
len =
bacapp_decode_context_data(vdata, vlen, value,
rp1_property->propertyIdentifier);
len = bacapp_decode_context_data(
vdata, vlen, value, rp1_property->propertyIdentifier);
} else {
len = bacapp_decode_application_data(vdata, vlen, value);
}
+77 -99
View File
@@ -1,28 +1,28 @@
/**************************************************************************
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
* Inspired by John Stachler <John.Stachler@lennoxind.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
* Inspired by John Stachler <John.Stachler@lennoxind.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
@@ -46,12 +46,11 @@
/** @file h_rpm.c Handles Read Property Multiple requests. */
static uint8_t Temp_Buf[MAX_APDU] = { 0 };
static uint8_t Temp_Buf[MAX_APDU] = {0};
static BACNET_PROPERTY_ID RPM_Object_Property(
struct special_property_list_t *pPropertyList,
BACNET_PROPERTY_ID special_property,
unsigned index)
BACNET_PROPERTY_ID special_property, unsigned index)
{
int property = -1; /* return value */
unsigned required, optional, proprietary;
@@ -79,7 +78,7 @@ static BACNET_PROPERTY_ID RPM_Object_Property(
}
}
return (BACNET_PROPERTY_ID) property;
return (BACNET_PROPERTY_ID)property;
}
static unsigned RPM_Object_Property_Count(
@@ -89,8 +88,7 @@ static unsigned RPM_Object_Property_Count(
unsigned count = 0; /* return value */
if (special_property == PROP_ALL) {
count =
pPropertyList->Required.count + pPropertyList->Optional.count +
count = pPropertyList->Required.count + pPropertyList->Optional.count +
pPropertyList->Proprietary.count;
} else if (special_property == PROP_REQUIRED) {
count = pPropertyList->Required.count;
@@ -103,20 +101,16 @@ static unsigned RPM_Object_Property_Count(
/** Encode the RPM property returning the length of the encoding,
or 0 if there is no room to fit the encoding. */
static int RPM_Encode_Property(
uint8_t * apdu,
uint16_t offset,
uint16_t max_apdu,
BACNET_RPM_DATA * rpmdata)
static int RPM_Encode_Property(uint8_t *apdu, uint16_t offset,
uint16_t max_apdu, BACNET_RPM_DATA *rpmdata)
{
int len = 0;
size_t copy_len = 0;
int apdu_len = 0;
BACNET_READ_PROPERTY_DATA rpdata;
len =
rpm_ack_encode_apdu_object_property(&Temp_Buf[0],
rpmdata->object_property, rpmdata->array_index);
len = rpm_ack_encode_apdu_object_property(
&Temp_Buf[0], rpmdata->object_property, rpmdata->array_index);
copy_len = memcopy(&apdu[0], &Temp_Buf[0], offset, len, max_apdu);
if (copy_len == 0) {
rpmdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
@@ -140,9 +134,8 @@ static int RPM_Encode_Property(
return len; /* Ie, Abort */
}
/* error was returned - encode that for the response */
len =
rpm_ack_encode_apdu_object_property_error(&Temp_Buf[0],
rpdata.error_class, rpdata.error_code);
len = rpm_ack_encode_apdu_object_property_error(
&Temp_Buf[0], rpdata.error_class, rpdata.error_code);
copy_len =
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) {
/* enough room to fit the property value and tags */
len =
rpm_ack_encode_apdu_object_property_value(&apdu[offset + apdu_len],
&Temp_Buf[0], len);
len = rpm_ack_encode_apdu_object_property_value(
&apdu[offset + apdu_len], &Temp_Buf[0], len);
} else {
/* not enough room - abort! */
rpmdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
@@ -175,8 +167,8 @@ static int RPM_Encode_Property(
* - if decoding fails
* - if the response would be too large
* - the result from each included read request, if it succeeds
* - an Error if processing fails for all, or individual errors if only some fail,
* or there isn't enough room in the APDU to fit the data.
* - an Error if processing fails for all, or individual errors if only some
* 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_len [in] The length of the service_request.
@@ -184,11 +176,9 @@ static int RPM_Encode_Property(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message.
*/
void handler_read_property_multiple(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_read_property_multiple(uint8_t *service_request,
uint16_t service_len, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA *service_data)
{
int len = 0;
uint16_t copy_len = 0;
@@ -203,12 +193,12 @@ void handler_read_property_multiple(
int error = 0;
/* jps_debug - see if we are utilizing all the buffer */
/* memset(&Handler_Transmit_Buffer[0], 0xff, sizeof(Handler_Transmit_Buffer)); */
/* memset(&Handler_Transmit_Buffer[0], 0xff,
* sizeof(Handler_Transmit_Buffer)); */
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
npdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
if (service_data->segmented_message) {
rpmdata.error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
@@ -220,13 +210,11 @@ void handler_read_property_multiple(
}
/* decode apdu request & encode apdu reply
encode complex ack, invoke id, service choice */
apdu_len =
rpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
apdu_len = rpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id);
for (;;) {
/* Start by looking for an object ID */
len =
rpm_decode_object_id(&service_request[decode_len],
len = rpm_decode_object_id(&service_request[decode_len],
service_len - decode_len, &rpmdata);
if (len >= 0) {
/* 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 */
len = rpm_ack_encode_apdu_object_begin(&Temp_Buf[0], &rpmdata);
copy_len =
memcopy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0], apdu_len,
len, MAX_APDU);
copy_len = memcopy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0],
apdu_len, len, MAX_APDU);
if (copy_len == 0) {
#if PRINT_ENABLED
fprintf(stderr, "RPM: Response too big!\r\n");
@@ -288,11 +275,10 @@ void handler_read_property_multiple(
if (rpmdata.array_index != BACNET_ARRAY_ALL) {
/* No array index options for this special property.
Encode error for this object property response */
len =
rpm_ack_encode_apdu_object_property(&Temp_Buf[0],
rpmdata.object_property, rpmdata.array_index);
copy_len =
memcopy(&Handler_Transmit_Buffer[npdu_len],
len = rpm_ack_encode_apdu_object_property(
&Temp_Buf[0], rpmdata.object_property,
rpmdata.array_index);
copy_len = memcopy(&Handler_Transmit_Buffer[npdu_len],
&Temp_Buf[0], apdu_len, len, MAX_APDU);
if (copy_len == 0) {
#if PRINT_ENABLED
@@ -305,12 +291,10 @@ void handler_read_property_multiple(
goto RPM_FAILURE;
}
apdu_len += len;
len =
rpm_ack_encode_apdu_object_property_error(&Temp_Buf[0],
ERROR_CLASS_PROPERTY,
len = rpm_ack_encode_apdu_object_property_error(
&Temp_Buf[0], ERROR_CLASS_PROPERTY,
ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY);
copy_len =
memcopy(&Handler_Transmit_Buffer[npdu_len],
copy_len = memcopy(&Handler_Transmit_Buffer[npdu_len],
&Temp_Buf[0], apdu_len, len, MAX_APDU);
if (copy_len == 0) {
#if PRINT_ENABLED
@@ -325,10 +309,10 @@ void handler_read_property_multiple(
} else {
special_object_property = rpmdata.object_property;
Device_Objects_Property_List(rpmdata.object_type,
rpmdata.object_instance, &property_list);
property_count =
RPM_Object_Property_Count(&property_list,
special_object_property);
rpmdata.object_instance,
&property_list);
property_count = RPM_Object_Property_Count(
&property_list, special_object_property);
if (property_count == 0) {
/* this only happens with the OPTIONAL property */
/* 135-2016bl-2. Clarify ReadPropertyMultiple
@@ -338,13 +322,11 @@ void handler_read_property_multiple(
for the specified property.*/
} else {
for (index = 0; index < property_count; index++) {
rpmdata.object_property =
RPM_Object_Property(&property_list,
special_object_property, index);
len =
RPM_Encode_Property(&Handler_Transmit_Buffer
[npdu_len], (uint16_t) apdu_len, MAX_APDU,
&rpmdata);
rpmdata.object_property = RPM_Object_Property(
&property_list, special_object_property, index);
len = RPM_Encode_Property(
&Handler_Transmit_Buffer[npdu_len],
(uint16_t)apdu_len, MAX_APDU, &rpmdata);
if (len > 0) {
apdu_len += len;
} else {
@@ -362,7 +344,7 @@ void handler_read_property_multiple(
/* handle an individual property */
len =
RPM_Encode_Property(&Handler_Transmit_Buffer[npdu_len],
(uint16_t) apdu_len, MAX_APDU, &rpmdata);
(uint16_t)apdu_len, MAX_APDU, &rpmdata);
if (len > 0) {
apdu_len += len;
} else {
@@ -378,9 +360,8 @@ void handler_read_property_multiple(
/* Reached end of property list so cap the result list */
decode_len++;
len = rpm_ack_encode_apdu_object_end(&Temp_Buf[0]);
copy_len =
memcopy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0],
apdu_len, len, MAX_APDU);
copy_len = memcopy(&Handler_Transmit_Buffer[npdu_len],
&Temp_Buf[0], apdu_len, len, MAX_APDU);
if (copy_len == 0) {
#if PRINT_ENABLED
fprintf(stderr, "RPM: Too full to encode object end!\r\n");
@@ -411,28 +392,26 @@ void handler_read_property_multiple(
goto RPM_FAILURE;
}
RPM_FAILURE:
RPM_FAILURE:
if (error) {
if (error == BACNET_STATUS_ABORT) {
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
abort_convert_error_code(rpmdata.error_code), true);
#if PRINT_ENABLED
fprintf(stderr, "RPM: Sending Abort!\n");
#endif
} else if (error == BACNET_STATUS_ERROR) {
apdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
rpmdata.error_class, rpmdata.error_code);
apdu_len = bacerror_encode_apdu(
&Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, rpmdata.error_class,
rpmdata.error_code);
#if PRINT_ENABLED
fprintf(stderr, "RPM: Sending Error!\n");
#endif
} else if (error == BACNET_STATUS_REJECT) {
apdu_len =
reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
apdu_len = reject_encode_apdu(
&Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
reject_convert_error_code(rpmdata.error_code));
#if PRINT_ENABLED
fprintf(stderr, "RPM: Sending Reject!\n");
@@ -441,8 +420,7 @@ void handler_read_property_multiple(
}
pdu_len = apdu_len + npdu_len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
if (bytes_sent <= 0) {
#if PRINT_ENABLED
+45 -54
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
@@ -53,10 +53,8 @@
* where the RPM data is to be stored.
* @return The number of bytes decoded, or -1 on error
*/
int rpm_ack_decode_service_request(
uint8_t * apdu,
int apdu_len,
BACNET_READ_ACCESS_DATA * read_access_data)
int rpm_ack_decode_service_request(uint8_t *apdu, int apdu_len,
BACNET_READ_ACCESS_DATA *read_access_data)
{
int decoded_len = 0; /* return value */
uint32_t error_value = 0; /* decoded error value */
@@ -74,8 +72,7 @@ int rpm_ack_decode_service_request(
rpm_object = read_access_data;
old_rpm_object = rpm_object;
while (rpm_object && apdu_len) {
len =
rpm_ack_decode_object_id(apdu, apdu_len, &rpm_object->object_type,
len = rpm_ack_decode_object_id(apdu, apdu_len, &rpm_object->object_type,
&rpm_object->object_instance);
if (len <= 0) {
old_rpm_object->next = NULL;
@@ -89,9 +86,8 @@ int rpm_ack_decode_service_request(
rpm_object->listOfProperties = rpm_property;
old_rpm_property = rpm_property;
while (rpm_property && apdu_len) {
len =
rpm_ack_decode_object_property(apdu, apdu_len,
&rpm_property->propertyIdentifier,
len = rpm_ack_decode_object_property(
apdu, apdu_len, &rpm_property->propertyIdentifier,
&rpm_property->propertyArrayIndex);
if (len <= 0) {
old_rpm_property->next = NULL;
@@ -117,12 +113,11 @@ int rpm_ack_decode_service_request(
old_value = value;
while (value && (apdu_len > 0)) {
if (IS_CONTEXT_SPECIFIC(*apdu)) {
len =
bacapp_decode_context_data(apdu, apdu_len, value,
len = bacapp_decode_context_data(
apdu, apdu_len, value,
rpm_property->propertyIdentifier);
} else {
len =
bacapp_decode_application_data(apdu, apdu_len,
len = bacapp_decode_application_data(apdu, apdu_len,
value);
}
/* If len == 0 then it's an empty structure, which is OK. */
@@ -201,8 +196,7 @@ int rpm_ack_decode_service_request(
}
/* for debugging... */
void rpm_ack_print_data(
BACNET_READ_ACCESS_DATA * rpm_data)
void rpm_ack_print_data(BACNET_READ_ACCESS_DATA *rpm_data)
{
BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
BACNET_PROPERTY_REFERENCE *listOfProperties;
@@ -213,7 +207,7 @@ void rpm_ack_print_data(
#if PRINT_ENABLED
fprintf(stdout, "%s #%lu\r\n",
bactext_object_type_name(rpm_data->object_type),
(unsigned long) rpm_data->object_instance);
(unsigned long)rpm_data->object_instance);
fprintf(stdout, "{\r\n");
#endif
listOfProperties = rpm_data->listOfProperties;
@@ -221,11 +215,11 @@ void rpm_ack_print_data(
#if PRINT_ENABLED
if (listOfProperties->propertyIdentifier < 512) {
fprintf(stdout, " %s: ",
bactext_property_name(listOfProperties->
propertyIdentifier));
bactext_property_name(
listOfProperties->propertyIdentifier));
} else {
fprintf(stdout, " proprietary %u: ",
(unsigned) listOfProperties->propertyIdentifier);
(unsigned)listOfProperties->propertyIdentifier);
}
#endif
if (listOfProperties->propertyArrayIndex != BACNET_ARRAY_ALL) {
@@ -269,10 +263,10 @@ void rpm_ack_print_data(
#if PRINT_ENABLED
/* AccessError */
fprintf(stdout, "BACnet Error: %s: %s\r\n",
bactext_error_class_name((int) listOfProperties->
error.error_class),
bactext_error_code_name((int) listOfProperties->
error.error_code));
bactext_error_class_name(
(int)listOfProperties->error.error_class),
bactext_error_code_name(
(int)listOfProperties->error.error_code));
#endif
}
listOfProperties = listOfProperties->next;
@@ -295,10 +289,8 @@ void rpm_ack_print_data(
* decoded from the APDU header of this message.
*/
void handler_read_property_multiple_ack(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{
int len = 0;
BACNET_READ_ACCESS_DATA *rpm_data;
@@ -308,13 +300,12 @@ void handler_read_property_multiple_ack(
BACNET_APPLICATION_DATA_VALUE *value;
BACNET_APPLICATION_DATA_VALUE *old_value;
(void) src;
(void) service_data; /* we could use these... */
(void)src;
(void)service_data; /* we could use these... */
rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
if (rpm_data) {
len =
rpm_ack_decode_service_request(service_request, service_len,
len = rpm_ack_decode_service_request(service_request, service_len,
rpm_data);
}
#if 1
+64 -60
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -41,13 +41,11 @@
/** @file h_rr.c Handles Read Range requests. */
static uint8_t Temp_Buf[MAX_APDU] = { 0 };
static uint8_t Temp_Buf[MAX_APDU] = {0};
/* Encodes the property APDU and returns the length,
or sets the error, and returns -1 */
static int Encode_RR_payload(
uint8_t * apdu,
BACNET_READ_RANGE_DATA * pRequest)
static int Encode_RR_payload(uint8_t* apdu, BACNET_READ_RANGE_DATA* pRequest)
{
int apdu_len = -1;
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);
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 */
pRequest->error_code = ERROR_CODE_OTHER; /* I couldn't see anything more appropriate so... */
if ((pRequest->RequestType == RR_BY_POSITION) &&
(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) &&
(pRequest->array_index != 0) &&
(pRequest->array_index != BACNET_ARRAY_ALL)) {
@@ -72,26 +75,32 @@ static int Encode_RR_payload(
pRequest->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
} else if ((pRequest->RequestType != RR_READ_ALL) &&
((PropInfo.RequestTypes & pRequest->RequestType) == 0)) {
/* By Time or By Sequence not supported - By Position is always required */
pRequest->error_code = 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... */
/* By Time or By Sequence not supported - By Position is always
* required */
pRequest->error_code =
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) {
apdu_len = PropInfo.Handler(apdu, pRequest);
}
} 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;
}
return apdu_len;
}
void handler_read_range(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_read_range(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data)
{
BACNET_READ_RANGE_DATA data;
int len = 0;
@@ -106,15 +115,13 @@ void handler_read_range(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr, "RR: Segmented message. Sending Abort!\n");
#endif
@@ -128,9 +135,9 @@ void handler_read_range(
#endif
if (len < 0) {
/* bad decoding - send an abort */
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER,
true);
#if PRINT_ENABLED
fprintf(stderr, "RR: Bad Encoding. Sending Abort!\n");
#endif
@@ -145,8 +152,7 @@ void handler_read_range(
data.application_data = &Temp_Buf[0];
data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */
len =
rr_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
len = rr_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data);
#if PRINT_ENABLED
fprintf(stderr, "RR: Sending Ack!\n");
@@ -156,27 +162,25 @@ void handler_read_range(
if (error) {
if (len == -2) {
/* BACnet APDU too small to fit data, so proper response is Abort */
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
len = abort_encode_apdu(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr, "RR: Reply too big to fit into APDU!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_READ_RANGE,
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_READ_RANGE,
data.error_class, data.error_code);
#if PRINT_ENABLED
fprintf(stderr, "RR: Sending Error!\n");
#endif
}
}
RR_ABORT:
RR_ABORT:
pdu_len += len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
+31 -35
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include "config.h"
@@ -43,8 +43,7 @@
/** @file h_rr_a.c Handles Read Range Acknowledgments. */
/* for debugging... */
static void PrintReadRangeData(
BACNET_READ_RANGE_DATA * data)
static void PrintReadRangeData(BACNET_READ_RANGE_DATA *data)
{
BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
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? */
/* value? need to loop until all of the len is gone... */
for (;;) {
len =
bacapp_decode_application_data(application_data,
(uint8_t) application_data_len, &value);
len = bacapp_decode_application_data(
application_data, (uint8_t)application_data_len, &value);
if (first_value && (len < application_data_len)) {
first_value = false;
#if PRINT_ENABLED
@@ -99,17 +97,15 @@ static void PrintReadRangeData(
}
}
void handler_read_range_ack(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
void handler_read_range_ack(uint8_t *service_request, uint16_t service_len,
BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{
int len = 0;
BACNET_READ_RANGE_DATA data;
(void) src;
(void) service_data; /* we could use these... */
(void)src;
(void)service_data; /* we could use these... */
len = rr_ack_decode_service_request(service_request, service_len, &data);
#if PRINT_ENABLED
+55 -73
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -49,36 +49,31 @@ static BACNET_DATE_TIME Next_Sync_Time;
#endif
#if PRINT_ENABLED
static void show_bacnet_date_time(
BACNET_DATE * bdate,
BACNET_TIME * btime)
static void show_bacnet_date_time(BACNET_DATE *bdate, BACNET_TIME *btime)
{
/* show the date received */
fprintf(stderr, "%u", (unsigned) bdate->year);
fprintf(stderr, "/%u", (unsigned) bdate->month);
fprintf(stderr, "/%u", (unsigned) bdate->day);
fprintf(stderr, "%u", (unsigned)bdate->year);
fprintf(stderr, "/%u", (unsigned)bdate->month);
fprintf(stderr, "/%u", (unsigned)bdate->day);
/* show the time received */
fprintf(stderr, " %02u", (unsigned) btime->hour);
fprintf(stderr, ":%02u", (unsigned) btime->min);
fprintf(stderr, ":%02u", (unsigned) btime->sec);
fprintf(stderr, ".%02u", (unsigned) btime->hundredths);
fprintf(stderr, " %02u", (unsigned)btime->hour);
fprintf(stderr, ":%02u", (unsigned)btime->min);
fprintf(stderr, ":%02u", (unsigned)btime->sec);
fprintf(stderr, ".%02u", (unsigned)btime->hundredths);
fprintf(stderr, "\r\n");
}
#endif
void handler_timesync(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
void handler_timesync(uint8_t *service_request, uint16_t service_len,
BACNET_ADDRESS *src)
{
int len = 0;
BACNET_DATE bdate = {0};
BACNET_TIME btime = {0};
(void) src;
(void) service_len;
len =
timesync_decode_service_request(service_request, service_len, &bdate,
(void)src;
(void)service_len;
len = timesync_decode_service_request(service_request, service_len, &bdate,
&btime);
if (len > 0) {
if (datetime_is_valid(&bdate, &btime)) {
@@ -96,19 +91,16 @@ void handler_timesync(
return;
}
void handler_timesync_utc(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
void handler_timesync_utc(uint8_t *service_request, uint16_t service_len,
BACNET_ADDRESS *src)
{
int len = 0;
BACNET_DATE bdate;
BACNET_TIME btime;
(void) src;
(void) service_len;
len =
timesync_decode_service_request(service_request, service_len, &bdate,
(void)src;
(void)service_len;
len = timesync_decode_service_request(service_request, service_len, &bdate,
&btime);
if (len > 0) {
if (datetime_is_valid(&bdate, &btime)) {
@@ -138,9 +130,7 @@ void handler_timesync_utc(
* @return How many bytes were encoded in the buffer, or
* BACNET_STATUS_ABORT if the response would not fit within the buffer.
*/
int handler_timesync_encode_recipients(
uint8_t * apdu,
int max_apdu)
int handler_timesync_encode_recipients(uint8_t *apdu, int max_apdu)
{
return timesync_encode_timesync_recipients(apdu, max_apdu,
&Time_Sync_Recipients[0]);
@@ -148,8 +138,7 @@ int handler_timesync_encode_recipients(
#endif
#if defined(BACNET_TIME_MASTER)
bool handler_timesync_recipient_write(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool handler_timesync_recipient_write(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false;
@@ -162,8 +151,7 @@ bool handler_timesync_recipient_write(
#endif
#if defined(BACNET_TIME_MASTER)
static void handler_timesync_send(
BACNET_DATE_TIME * current_date_time)
static void handler_timesync_send(BACNET_DATE_TIME *current_date_time)
{
unsigned index = 0;
bool status = false;
@@ -171,8 +159,7 @@ static void handler_timesync_send(
for (index = 0; index < MAX_TIME_SYNC_RECIPIENTS; index++) {
if (Time_Sync_Recipients[index].tag == 1) {
if (status) {
Send_TimeSync_Remote(
&Time_Sync_Recipients[index].type.address,
Send_TimeSync_Remote(&Time_Sync_Recipients[index].type.address,
&current_date_time->date,
&current_date_time->time);
}
@@ -182,9 +169,8 @@ static void handler_timesync_send(
#endif
#if defined(BACNET_TIME_MASTER)
static void handler_timesync_update(
uint32_t device_interval,
BACNET_DATE_TIME * current_date_time)
static void handler_timesync_update(uint32_t device_interval,
BACNET_DATE_TIME *current_date_time)
{
uint32_t current_minutes = 0;
uint32_t next_minutes = 0;
@@ -207,7 +193,7 @@ static void handler_timesync_update(
/* Interval_Minutes = 1 2 3 4 5 6 10 12 15 20 30 60 */
/* determine next interval */
current_minutes = Next_Sync_Time.time.min;
interval = current_minutes/device_interval;
interval = current_minutes / device_interval;
interval++;
next_minutes = interval * device_interval;
offset_minutes = interval_offset % device_interval;
@@ -223,7 +209,7 @@ static void handler_timesync_update(
144 160 180 240 288 360 480 720 1440 */
current_minutes =
datetime_minutes_since_midnight(&Next_Sync_Time.time);
interval = current_minutes/device_interval;
interval = current_minutes / device_interval;
interval++;
next_minutes = interval * device_interval;
offset_minutes = interval_offset % device_interval;
@@ -242,17 +228,14 @@ static void handler_timesync_update(
#endif
#if defined(BACNET_TIME_MASTER)
bool handler_timesync_recipient_address_set(
unsigned index,
bool handler_timesync_recipient_address_set(unsigned index,
BACNET_ADDRESS *address)
{
bool status = false;
if (address && (index < MAX_TIME_SYNC_RECIPIENTS)) {
Time_Sync_Recipients[index].tag = 1;
bacnet_address_copy(
&Time_Sync_Recipients[index].type.address,
address);
bacnet_address_copy(&Time_Sync_Recipients[index].type.address, address);
status = true;
}
@@ -261,8 +244,7 @@ bool handler_timesync_recipient_address_set(
#endif
#if defined(BACNET_TIME_MASTER)
void handler_timesync_task(
BACNET_DATE_TIME * current_date_time)
void handler_timesync_task(BACNET_DATE_TIME *current_date_time)
{
int compare = 0;
uint32_t device_interval = 0;
@@ -287,9 +269,9 @@ void handler_timesync_init(void)
unsigned i = 0;
/* connect linked list */
for (; i < (MAX_TIME_SYNC_RECIPIENTS-1); i++) {
Time_Sync_Recipients[i].next = &Time_Sync_Recipients[i+1];
Time_Sync_Recipients[i+1].next = NULL;
for (; i < (MAX_TIME_SYNC_RECIPIENTS - 1); i++) {
Time_Sync_Recipients[i].next = &Time_Sync_Recipients[i + 1];
Time_Sync_Recipients[i + 1].next = NULL;
}
for (i = 0; i < MAX_TIME_SYNC_RECIPIENTS; i++) {
Time_Sync_Recipients[i].tag = 0xFF;
+31 -33
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -57,10 +57,8 @@
* @param service_len [in] The length of the service_request.
* @param src [in] BACNET_ADDRESS of the source of the message (unused)
*/
void handler_ucov_notification(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
void handler_ucov_notification(uint8_t *service_request, uint16_t service_len,
BACNET_ADDRESS *src)
{
BACNET_COV_DATA cov_data;
BACNET_PROPERTY_VALUE property_value[MAX_COV_PROPERTIES];
@@ -77,14 +75,14 @@ void handler_ucov_notification(
fprintf(stderr, "UCOV: Received Notification!\n");
#endif
/* decode the service request only */
len =
cov_notify_decode_service_request(service_request, service_len,
len = cov_notify_decode_service_request(service_request, service_len,
&cov_data);
#if PRINT_ENABLED
if (len > 0) {
fprintf(stderr, "UCOV: PID=%u ", cov_data.subscriberProcessIdentifier);
fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier);
fprintf(stderr, "%s %u ",
fprintf(
stderr, "%s %u ",
bactext_object_type_name(cov_data.monitoredObjectIdentifier.type),
cov_data.monitoredObjectIdentifier.instance);
fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining);
@@ -93,9 +91,9 @@ void handler_ucov_notification(
while (pProperty_value) {
fprintf(stderr, "UCOV: ");
if (pProperty_value->propertyIdentifier < 512) {
fprintf(stderr, "%s ",
bactext_property_name
(pProperty_value->propertyIdentifier));
fprintf(
stderr, "%s ",
bactext_property_name(pProperty_value->propertyIdentifier));
} else {
fprintf(stderr, "proprietary %u ",
pProperty_value->propertyIdentifier);
+31 -35
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -39,8 +39,7 @@
/** @file h_upt.c Handles Unconfirmed Private Transfer requests. */
void private_transfer_print_data(
BACNET_PRIVATE_TRANSFER_DATA *private_data)
void private_transfer_print_data(BACNET_PRIVATE_TRANSFER_DATA *private_data)
{
BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */
@@ -53,16 +52,15 @@ void private_transfer_print_data(
if (private_data) {
#if PRINT_ENABLED
printf("PrivateTransfer:vendorID=%u\r\n",
(unsigned) private_data->vendorID);
(unsigned)private_data->vendorID);
printf("PrivateTransfer:serviceNumber=%lu\r\n",
(unsigned long) private_data->serviceNumber);
(unsigned long)private_data->serviceNumber);
#endif
application_data = private_data->serviceParameters;
application_data_len = private_data->serviceParametersLen;
for (;;) {
len =
bacapp_decode_application_data(application_data,
(uint8_t) application_data_len, &value);
len = bacapp_decode_application_data(
application_data, (uint8_t)application_data_len, &value);
if (first_value && (len < application_data_len)) {
first_value = false;
#if PRINT_ENABLED
@@ -101,10 +99,9 @@ void private_transfer_print_data(
}
}
void handler_unconfirmed_private_transfer(
uint8_t * service_request,
void handler_unconfirmed_private_transfer(uint8_t *service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
BACNET_ADDRESS *src)
{
BACNET_PRIVATE_TRANSFER_DATA private_data;
int len = 0;
@@ -112,8 +109,7 @@ void handler_unconfirmed_private_transfer(
#if PRINT_ENABLED
fprintf(stderr, "Received Unconfirmed Private Transfer Request!\n");
#endif
len =
ptransfer_decode_service_request(service_request, service_len,
len = ptransfer_decode_service_request(service_request, service_len,
&private_data);
if (len >= 0) {
private_transfer_print_data(&private_data);
+48 -52
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -42,8 +42,7 @@
* or object ID, if the Device has a match.
* @param data [in] The decoded who-has payload from the request.
*/
static void match_name_or_object(
BACNET_WHO_HAS_DATA * data)
static void match_name_or_object(BACNET_WHO_HAS_DATA* data)
{
int object_type = 0;
uint32_t object_instance = 0;
@@ -54,29 +53,26 @@ static void match_name_or_object(
note: we should have only 1 of such an object */
if (data->is_object_name) {
/* valid name in my device? */
found =
Device_Valid_Object_Name(&data->object.name, &object_type,
found = Device_Valid_Object_Name(&data->object.name, &object_type,
&object_instance);
if (found) {
Send_I_Have(Device_Object_Instance_Number(),
(BACNET_OBJECT_TYPE) object_type, object_instance,
(BACNET_OBJECT_TYPE)object_type, object_instance,
&data->object.name);
}
} else {
/* valid object_name copy in my device? */
found =
Device_Object_Name_Copy((BACNET_OBJECT_TYPE) data->
object.identifier.type, data->object.identifier.instance,
&object_name);
found = Device_Object_Name_Copy(
(BACNET_OBJECT_TYPE)data->object.identifier.type,
data->object.identifier.instance, &object_name);
if (found) {
Send_I_Have(Device_Object_Instance_Number(),
(BACNET_OBJECT_TYPE) data->object.identifier.type,
(BACNET_OBJECT_TYPE)data->object.identifier.type,
data->object.identifier.instance, &object_name);
}
}
}
/** Handler for Who-Has requests, with broadcast I-Have response.
* Will respond if the device Object ID matches, and we have
* the Object or Object Name requested.
@@ -86,22 +82,21 @@ static void match_name_or_object(
* @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source.
*/
void handler_who_has(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
void handler_who_has(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src)
{
int len = 0;
BACNET_WHO_HAS_DATA data;
bool directed_to_me = false;
(void) src;
(void)src;
len = whohas_decode_service_request(service_request, service_len, &data);
if (len > 0) {
if ((data.low_limit == -1) || (data.high_limit == -1))
directed_to_me = true;
else if ((Device_Object_Instance_Number() >= (uint32_t) data.low_limit)
&& (Device_Object_Instance_Number() <= (uint32_t) data.high_limit))
else if ((Device_Object_Instance_Number() >=
(uint32_t)data.low_limit) &&
(Device_Object_Instance_Number() <= (uint32_t)data.high_limit))
directed_to_me = true;
if (directed_to_me) {
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 */
/* EKH: I restored this to BAC_ROUTING (from DEPRECATED) because I found that the server demo with the built-in
virtual Router did not insert the SADRs of the virtual devices on the virtual network without it */
#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
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,
* with broadcast I-Have response.
@@ -124,24 +121,23 @@ void handler_who_has(
* @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source (ignored).
*/
void handler_who_has_for_routing(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
void handler_who_has_for_routing(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src)
{
int len = 0;
BACNET_WHO_HAS_DATA data;
int32_t dev_instance;
int cursor = 0; /* Starting hint */
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;
(void) src;
(void)src;
len = whohas_decode_service_request(service_request, service_len, &data);
if (len > 0) {
/* Go through all devices, starting with the root gateway Device */
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)) {
dev_instance = Device_Object_Instance_Number();
if ((data.low_limit == -1) || (data.high_limit == -1) ||
+54 -66
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -47,25 +47,22 @@
* @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source (ignored).
*/
void handler_who_is(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
void handler_who_is(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src)
{
int len = 0;
int32_t low_limit = 0;
int32_t high_limit = 0;
(void) src;
len =
whois_decode_service_request(service_request, service_len, &low_limit,
(void)src;
len = whois_decode_service_request(service_request, service_len, &low_limit,
&high_limit);
if (len == 0) {
Send_I_Am(&Handler_Transmit_Buffer[0]);
} else if (len != BACNET_STATUS_ERROR) {
/* is my device id within the limits? */
if ((Device_Object_Instance_Number() >= (uint32_t) low_limit) &&
(Device_Object_Instance_Number() <= (uint32_t) high_limit)) {
if ((Device_Object_Instance_Number() >= (uint32_t)low_limit) &&
(Device_Object_Instance_Number() <= (uint32_t)high_limit)) {
Send_I_Am(&Handler_Transmit_Buffer[0]);
}
}
@@ -73,32 +70,30 @@ void handler_who_is(
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
* @param service_request [in] The received message to be handled.
* @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source that the
* response will be sent back to.
*/
void handler_who_is_unicast(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
void handler_who_is_unicast(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src)
{
int len = 0;
int32_t low_limit = 0;
int32_t high_limit = 0;
len =
whois_decode_service_request(service_request, service_len, &low_limit,
len = whois_decode_service_request(service_request, service_len, &low_limit,
&high_limit);
/* If no limits, then always respond */
if (len == 0) {
Send_I_Am_Unicast(&Handler_Transmit_Buffer[0], src);
} else if (len != BACNET_STATUS_ERROR) {
/* is my device id within the limits? */
if ((Device_Object_Instance_Number() >= (uint32_t) low_limit) &&
(Device_Object_Instance_Number() <= (uint32_t) high_limit)) {
if ((Device_Object_Instance_Number() >= (uint32_t)low_limit) &&
(Device_Object_Instance_Number() <= (uint32_t)high_limit)) {
Send_I_Am_Unicast(&Handler_Transmit_Buffer[0], src);
}
}
@@ -106,11 +101,12 @@ void handler_who_is_unicast(
return;
}
#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
virtual Router did not insert the SADRs of the virtual devices on the virtual network without it */
#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
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.
* 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 src [in] The BACNET_ADDRESS of the message's source.
* @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(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
static void check_who_is_for_routing(uint8_t* service_request,
uint16_t service_len, BACNET_ADDRESS* src,
bool is_unicast)
{
int len = 0;
@@ -133,11 +128,10 @@ static void check_who_is_for_routing(
int32_t high_limit = 0;
int32_t dev_instance;
int cursor = 0; /* Starting hint */
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;
len =
whois_decode_service_request(service_request, service_len, &low_limit,
len = whois_decode_service_request(service_request, service_len, &low_limit,
&high_limit);
if (len == BACNET_STATUS_ERROR) {
/* Invalid; just leave */
@@ -150,18 +144,16 @@ static void check_who_is_for_routing(
while (Routed_Device_GetNext(&bcast_net, my_list, &cursor)) {
dev_instance = Device_Object_Instance_Number();
/* If len == 0, no limits and always respond */
if ((len == 0) || ((dev_instance >= low_limit) &&
(dev_instance <= high_limit))) {
if ((len == 0) ||
((dev_instance >= low_limit) && (dev_instance <= high_limit))) {
if (is_unicast)
Send_I_Am_Unicast(&Handler_Transmit_Buffer[0], src);
else
Send_I_Am(&Handler_Transmit_Buffer[0]);
}
}
}
/** Handler for Who-Is requests in the virtual routing setup,
* with broadcast I-Am response(s).
* @ingroup DMDDB
@@ -173,15 +165,12 @@ static void check_who_is_for_routing(
* @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source (ignored).
*/
void handler_who_is_bcast_for_routing(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
void handler_who_is_bcast_for_routing(uint8_t* service_request,
uint16_t service_len, BACNET_ADDRESS* src)
{
check_who_is_for_routing(service_request, service_len, src, false);
}
/** Handler for Who-Is requests in the virtual routing setup,
* with unicast I-Am response(s) returned to the src.
* Will check the gateway (root Device) and all virtual routed
@@ -193,10 +182,9 @@ void handler_who_is_bcast_for_routing(
* @param src [in] The BACNET_ADDRESS of the message's source that the
* response will be sent back to.
*/
void handler_who_is_unicast_for_routing(
uint8_t * service_request,
void handler_who_is_unicast_for_routing(uint8_t* service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
BACNET_ADDRESS* src)
{
check_who_is_for_routing(service_request, service_len, src, true);
}
+57 -68
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -42,7 +42,6 @@
/** @file h_wp.c Handles Write Property requests. */
/** Handler for a WriteProperty Service request.
* @ingroup DSWP
* This handler will be invoked by apdu_handler() if it has been enabled
@@ -61,11 +60,9 @@
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message.
*/
void handler_write_property(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_write_property(uint8_t* service_request, uint16_t service_len,
BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data)
{
BACNET_WRITE_PROPERTY_DATA wp_data;
int len = 0;
@@ -77,17 +74,15 @@ void handler_write_property(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
#if PRINT_ENABLED
fprintf(stderr, "WP: Received Request!\n");
#endif
if (service_data->segmented_message) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
fprintf(stderr, "WP: Segmented message. Sending Abort!\n");
#endif
@@ -96,45 +91,45 @@ void handler_write_property(
len = wp_decode_service_request(service_request, service_len, &wp_data);
#if PRINT_ENABLED
if (len > 0)
fprintf(stderr,
fprintf(
stderr,
"WP: type=%lu instance=%lu property=%lu priority=%lu index=%ld\n",
(unsigned long) wp_data.object_type,
(unsigned long) wp_data.object_instance,
(unsigned long) wp_data.object_property,
(unsigned long) wp_data.priority, (long) wp_data.array_index);
(unsigned long)wp_data.object_type,
(unsigned long)wp_data.object_instance,
(unsigned long)wp_data.object_property,
(unsigned long)wp_data.priority, (long)wp_data.array_index);
else
fprintf(stderr, "WP: Unable to decode Request!\n");
#endif
/* bad decoding or something we didn't understand - send an abort */
if (len <= 0) {
len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER,
true);
#if PRINT_ENABLED
fprintf(stderr, "WP: Bad Encoding. Sending Abort!\n");
#endif
goto WP_ABORT;
}
if (Device_Write_Property(&wp_data)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Simple Ack!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY,
wp_data.error_class, wp_data.error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Error!\n");
#endif
}
WP_ABORT:
WP_ABORT:
pdu_len += len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
if (bytes_sent <= 0) {
#if PRINT_ENABLED
@@ -145,19 +140,15 @@ void handler_write_property(
return;
}
/** Perform basic validation of Write Property argument based on
* the assumption that it is a string. Check for correct data type,
* correct encoding (fixed here as ANSI X34),correct length, and
* finally if it is allowed to be empty.
*/
bool WPValidateString(
BACNET_APPLICATION_DATA_VALUE * pValue,
int iMaxLen,
bool bEmptyAllowed,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateString(BACNET_APPLICATION_DATA_VALUE* pValue, int iMaxLen,
bool bEmptyAllowed, BACNET_ERROR_CLASS* pErrorClass,
BACNET_ERROR_CODE* pErrorCode)
{
bool bResult;
@@ -172,15 +163,15 @@ bool WPValidateString(
if (characterstring_encoding(&pValue->type.Character_String) ==
CHARACTER_ANSI_X34) {
if ((bEmptyAllowed == false) &&
(characterstring_length(&pValue->type.Character_String) ==
0)) {
(characterstring_length(&pValue->type.Character_String) == 0)) {
*pErrorCode = ERROR_CODE_VALUE_OUT_OF_RANGE;
} else if ((bEmptyAllowed == false) &&
(!characterstring_printable(&pValue->type.Character_String))) {
(!characterstring_printable(
&pValue->type.Character_String))) {
/* assumption: non-empty also means must be "printable" */
*pErrorCode = ERROR_CODE_VALUE_OUT_OF_RANGE;
} else if (characterstring_length(&pValue->type.Character_String) >
(uint16_t) iMaxLen) {
(uint16_t)iMaxLen) {
*pErrorClass = ERROR_CLASS_RESOURCES;
*pErrorCode = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
} else
@@ -198,11 +189,9 @@ bool WPValidateString(
* validation fails. Cuts out reams of repeated code in the object code.
*/
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE* pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS* pErrorClass,
BACNET_ERROR_CODE* pErrorCode)
{
bool bResult;
+55 -59
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -44,7 +44,6 @@
/** @file h_wpm.c Handles Write Property Multiple requests. */
/** Handler for a WriteProperty Service request.
* @ingroup DSWP
* This handler will be invoked by apdu_handler() if it has been enabled
@@ -63,10 +62,8 @@
* decoded from the APDU header of this message.
*/
void handler_write_property_multiple(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
uint8_t* service_request, uint16_t service_len, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data)
{
int len = 0;
int apdu_len = 0;
@@ -92,8 +89,7 @@ void handler_write_property_multiple(
decode_len = 0;
do {
/* decode Object Identifier */
len =
wpm_decode_object_id(&service_request[decode_len],
len = wpm_decode_object_id(&service_request[decode_len],
service_len - decode_len, &wp_data);
if (len > 0) {
uint8_t tag_number = 0;
@@ -103,21 +99,24 @@ void handler_write_property_multiple(
if (decode_is_opening_tag_number(&service_request[decode_len++],
1)) {
do {
/* decode a 'Property Identifier'; (3) an optional 'Property Array Index' */
/* (4) a 'Property Value'; and (5) an optional 'Priority'. */
len =
wpm_decode_object_property(&service_request
[decode_len], service_len - decode_len, &wp_data);
/* decode a 'Property Identifier'; (3) an optional 'Property
* Array Index' */
/* (4) a 'Property Value'; and (5) an optional 'Priority'.
*/
len = wpm_decode_object_property(
&service_request[decode_len], service_len - decode_len,
&wp_data);
if (len > 0) {
decode_len += len;
#if PRINT_ENABLED
fprintf(stderr,
"WPM: type=%lu instance=%lu property=%lu priority=%lu index=%ld\n",
(unsigned long) wp_data.object_type,
(unsigned long) wp_data.object_instance,
(unsigned long) wp_data.object_property,
(unsigned long) wp_data.priority,
(long) wp_data.array_index);
"WPM: type=%lu instance=%lu property=%lu "
"priority=%lu index=%ld\n",
(unsigned long)wp_data.object_type,
(unsigned long)wp_data.object_instance,
(unsigned long)wp_data.object_property,
(unsigned long)wp_data.priority,
(long)wp_data.array_index);
#endif
if (Device_Write_Property(&wp_data) == false) {
error = true;
@@ -133,15 +132,17 @@ void handler_write_property_multiple(
}
/* Closing tag 1 - List of Properties */
if (decode_is_closing_tag_number(&service_request
[decode_len], 1)) {
if (decode_is_closing_tag_number(
&service_request[decode_len], 1)) {
tag_number = 1;
decode_len++;
} 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 (tag_number != 1); /* end decoding List of Properties for "that" object */
} while (
tag_number !=
1); /* end decoding List of Properties for "that" object */
if (error) {
goto WPM_ABORT;
@@ -156,20 +157,18 @@ void handler_write_property_multiple(
}
} while (decode_len < service_len);
WPM_ABORT:
WPM_ABORT:
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
npdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
apdu_len = 0;
/* handle any errors */
if (error) {
if (len == BACNET_STATUS_ABORT) {
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
abort_convert_error_code(wp_data.error_code), true);
#if PRINT_ENABLED
fprintf(stderr, "WPM: Sending Abort!\n");
@@ -182,17 +181,15 @@ void handler_write_property_multiple(
fprintf(stderr, "WPM: Sending Error!\n");
#endif
} else if (len == BACNET_STATUS_REJECT) {
apdu_len =
reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
apdu_len = reject_encode_apdu(
&Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
reject_convert_error_code(wp_data.error_code));
#if PRINT_ENABLED
fprintf(stderr, "WPM: Sending Reject!\n");
#endif
}
} else {
apdu_len =
wpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
apdu_len = wpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id);
#if PRINT_ENABLED
fprintf(stderr, "WPM: Sending Ack!\n");
@@ -200,8 +197,7 @@ void handler_write_property_multiple(
}
pdu_len = npdu_len + apdu_len;
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0) {
+33 -37
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -49,11 +49,9 @@
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message.
*/
void handler_unrecognized_service(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
void handler_unrecognized_service(uint8_t* service_request,
uint16_t service_len, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data)
{
int len = 0;
int pdu_len = 0;
@@ -61,23 +59,21 @@ void handler_unrecognized_service(
BACNET_NPDU_DATA npdu_data;
BACNET_ADDRESS my_address;
(void) service_request;
(void) service_len;
(void)service_request;
(void)service_len;
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data);
/* encode the APDU portion of the packet */
len =
reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, REJECT_REASON_UNRECOGNIZED_SERVICE);
len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
REJECT_REASON_UNRECOGNIZED_SERVICE);
pdu_len += len;
/* send the data */
bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
if (bytes_sent > 0) {
#if PRINT_ENABLED
+14 -24
View File
@@ -44,36 +44,31 @@
/* list of devices */
static OS_Keylist Device_List = NULL;
void objects_init(
void)
void objects_init(void)
{
if (!Device_List)
Device_List = Keylist_Create();
}
int objects_device_count(
void)
int objects_device_count(void)
{
objects_init();
return Keylist_Count(Device_List);
}
OBJECT_DEVICE_T *objects_device_data(
int index)
OBJECT_DEVICE_T *objects_device_data(int index)
{
objects_init();
return Keylist_Data_Index(Device_List, index);
}
OBJECT_DEVICE_T *objects_device_by_instance(
uint32_t device_instance)
OBJECT_DEVICE_T *objects_device_by_instance(uint32_t device_instance)
{
objects_init();
return Keylist_Data(Device_List, device_instance);
}
OBJECT_DEVICE_T *objects_device_new(
uint32_t device_instance)
OBJECT_DEVICE_T *objects_device_new(uint32_t device_instance)
{
OBJECT_DEVICE_T *pDevice = NULL;
KEY key = device_instance;
@@ -94,7 +89,7 @@ OBJECT_DEVICE_T *objects_device_new(
} else {
fprintf(stderr,
"Objects: Unable to allocate device %lu buffer\n",
(unsigned long) device_instance);
(unsigned long)device_instance);
}
}
}
@@ -102,8 +97,7 @@ OBJECT_DEVICE_T *objects_device_new(
return pDevice;
}
OBJECT_DEVICE_T *objects_device_delete(
int index)
OBJECT_DEVICE_T *objects_device_delete(int index)
{
OBJECT_DEVICE_T *pDevice = NULL;
BACNET_OBJECT_ID *pObject;
@@ -112,7 +106,7 @@ OBJECT_DEVICE_T *objects_device_delete(
pDevice = Keylist_Data_Delete_By_Index(Device_List, index);
if (pDevice) {
fprintf(stderr, "Objects: removing device %lu",
(unsigned long) pDevice->Object_Identifier.instance);
(unsigned long)pDevice->Object_Identifier.instance);
if (pDevice->Object_List) {
do {
pObject =
@@ -137,9 +131,7 @@ OBJECT_DEVICE_T *objects_device_delete(
#include "ctest.h"
/* test the object creation and deletion */
void testBACnetObjectsCompare(
Test * pTest,
OBJECT_DEVICE_T * pDevice,
void testBACnetObjectsCompare(Test *pTest, OBJECT_DEVICE_T *pDevice,
uint32_t device_id)
{
ct_test(pTest, pDevice != NULL);
@@ -151,8 +143,7 @@ void testBACnetObjectsCompare(
}
}
void testBACnetObjects(
Test * pTest)
void testBACnetObjects(Test *pTest)
{
uint32_t device_id = 0;
unsigned test_point = 0;
@@ -175,8 +166,8 @@ void testBACnetObjects(
for (test_point = 0; test_point < max_test_points; test_point++) {
device_id = test_point * (BACNET_MAX_INSTANCE / max_test_points);
pDevice = objects_device_data(test_point);
testBACnetObjectsCompare(pTest, pDevice, Keylist_Key(Device_List,
test_point));
testBACnetObjectsCompare(pTest, pDevice,
Keylist_Key(Device_List, test_point));
}
for (test_point = 0; test_point < max_test_points; test_point++) {
pDevice = objects_device_delete(0);
@@ -184,8 +175,7 @@ void testBACnetObjects(
}
#ifdef TEST_OBJECT_LIST
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -198,7 +188,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
+30 -39
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2016 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2016 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -43,7 +43,6 @@
#include "handlers.h"
#include "client.h"
/** Encodes an Abort message
* @param buffer The buffer to build the message for sending.
* @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.
*/
int abort_encode_pdu(
uint8_t * buffer,
BACNET_ADDRESS * dest,
BACNET_ADDRESS * src,
BACNET_NPDU_DATA * npdu_data,
uint8_t invoke_id,
BACNET_ABORT_REASON reason,
bool server)
int abort_encode_pdu(uint8_t *buffer, BACNET_ADDRESS *dest, BACNET_ADDRESS *src,
BACNET_NPDU_DATA *npdu_data, uint8_t invoke_id,
BACNET_ABORT_REASON reason, bool server)
{
int 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.
*/
int Send_Abort_To_Network(
uint8_t * buffer,
BACNET_ADDRESS *dest,
uint8_t invoke_id,
BACNET_ABORT_REASON reason,
int Send_Abort_To_Network(uint8_t *buffer, BACNET_ADDRESS *dest,
uint8_t invoke_id, BACNET_ABORT_REASON reason,
bool server)
{
int pdu_len = 0;
@@ -100,8 +91,8 @@ int Send_Abort_To_Network(
BACNET_NPDU_DATA npdu_data;
datalink_get_my_address(&src);
pdu_len = abort_encode_pdu(buffer, dest, &src, &npdu_data,
invoke_id, reason, server);
pdu_len = abort_encode_pdu(buffer, dest, &src, &npdu_data, invoke_id,
reason, server);
bytes_sent = datalink_send_pdu(dest, &npdu_data, &buffer[0], pdu_len);
return bytes_sent;
+35 -39
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2009 John Minack <minack@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2009 John Minack <minack@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -48,10 +48,8 @@
/* returns the invoke ID for confirmed request, or zero on failure */
uint8_t Send_Alarm_Acknowledgement(
uint32_t device_id,
BACNET_ALARM_ACK_DATA * data)
uint8_t Send_Alarm_Acknowledgement(uint32_t device_id,
BACNET_ALARM_ACK_DATA* data)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -75,24 +73,22 @@ uint8_t Send_Alarm_Acknowledgement(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
len =
alarm_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
data);
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data);
len = alarm_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
invoke_id, data);
pdu_len += len;
/* will it fit in the sender?
note: if there is a bottleneck router in between
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Alarm Ack Request (%s)!\n",
+34 -39
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -45,9 +45,7 @@
/** @file s_arfs.c Send part of an Atomic Read File Stream. */
uint8_t Send_Atomic_Read_File_Stream(
uint32_t device_id,
uint32_t file_instance,
uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id, uint32_t file_instance,
int fileStartPosition,
unsigned requestedOctetCount)
{
@@ -81,11 +79,9 @@ uint8_t Send_Atomic_Read_File_Stream(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
len =
arf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data);
len = arf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
&data);
pdu_len += len;
/* will the APDU fit the target device?
@@ -93,16 +89,15 @@ uint8_t Send_Atomic_Read_File_Stream(
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
"Failed to Send AtomicReadFile Request (%s)!\n",
fprintf(stderr, "Failed to Send AtomicReadFile Request (%s)!\n",
strerror(errno));
#endif
} else {
+37 -39
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -45,11 +45,10 @@
/** @file s_awfs.c Send part of an Atomic Write File Stream request. */
uint8_t Send_Atomic_Write_File_Stream(
uint32_t device_id,
uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id,
uint32_t file_instance,
int fileStartPosition,
BACNET_OCTET_STRING * fileData)
BACNET_OCTET_STRING* fileData)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -82,12 +81,10 @@ uint8_t Send_Atomic_Write_File_Stream(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
len =
awf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
len = awf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
&data);
pdu_len += len;
/* will the APDU fit the target device?
@@ -95,13 +92,12 @@ uint8_t Send_Atomic_Write_File_Stream(
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len <= max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if ((unsigned)pdu_len <= max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
@@ -112,7 +108,8 @@ uint8_t Send_Atomic_Write_File_Stream(
tsm_free_invoke_id(invoke_id);
invoke_id = 0;
#if PRINT_ENABLED
fprintf(stderr,
fprintf(
stderr,
"Failed to Send AtomicWriteFile Request "
"(payload [%d] exceeds destination maximum APDU [%u])!\n",
pdu_len, max_apdu);
@@ -124,7 +121,8 @@ uint8_t Send_Atomic_Write_File_Stream(
#if PRINT_ENABLED
fprintf(stderr,
"Failed to Send AtomicWriteFile Request "
"(payload [%d] exceeds octet string capacity)!\n", pdu_len);
"(payload [%d] exceeds octet string capacity)!\n",
pdu_len);
#endif
}
}
+36 -38
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -47,9 +47,8 @@
* @return invoke id of outgoing message, or 0 if communication is disabled,
* or no tsm slot is available.
*/
uint8_t Send_CEvent_Notify(
uint32_t device_id,
BACNET_EVENT_NOTIFICATION_DATA * data)
uint8_t Send_CEvent_Notify(uint32_t device_id,
BACNET_EVENT_NOTIFICATION_DATA* data)
{
int len = 0;
int pdu_len = 0;
@@ -73,12 +72,10 @@ uint8_t Send_CEvent_Notify(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
len =
cevent_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
len = cevent_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
invoke_id, data);
pdu_len += len;
/* will it fit in the sender?
@@ -86,15 +83,16 @@ uint8_t Send_CEvent_Notify(
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0) {
fprintf(stderr,
fprintf(
stderr,
"Failed to Send ConfirmedEventNotification Request (%s)!\n",
strerror(errno));
}
+47 -53
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -42,7 +42,8 @@
#include "txbuf.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.
* @ingroup DSCOV
@@ -54,12 +55,9 @@
* @param cov_data [in] The COV update information to be encoded.
* @return Size of the message sent (bytes), or a negative value on error.
*/
int ucov_notify_encode_pdu(
uint8_t * buffer,
unsigned buffer_len,
BACNET_ADDRESS * dest,
BACNET_NPDU_DATA * npdu_data,
BACNET_COV_DATA * cov_data)
int ucov_notify_encode_pdu(uint8_t* buffer, unsigned buffer_len,
BACNET_ADDRESS* dest, BACNET_NPDU_DATA* npdu_data,
BACNET_COV_DATA* cov_data)
{
int len = 0;
int pdu_len = 0;
@@ -73,8 +71,8 @@ int ucov_notify_encode_pdu(
pdu_len = npdu_encode_pdu(&buffer[0], dest, &my_address, npdu_data);
/* encode the APDU portion of the packet */
len = ucov_notify_encode_apdu(&buffer[pdu_len],
buffer_len - pdu_len, cov_data);
len = ucov_notify_encode_apdu(&buffer[pdu_len], buffer_len - pdu_len,
cov_data);
if (len) {
pdu_len += len;
} else {
@@ -92,18 +90,16 @@ int ucov_notify_encode_pdu(
* @param cov_data [in] The COV update information to be encoded.
* @return Size of the message sent (bytes), or a negative value on error.
*/
int Send_UCOV_Notify(
uint8_t * buffer,
unsigned buffer_len,
BACNET_COV_DATA * cov_data)
int Send_UCOV_Notify(uint8_t* buffer, unsigned buffer_len,
BACNET_COV_DATA* cov_data)
{
int pdu_len = 0;
BACNET_ADDRESS dest;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
pdu_len = ucov_notify_encode_pdu(buffer, buffer_len, &dest, &npdu_data,
cov_data);
pdu_len =
ucov_notify_encode_pdu(buffer, buffer_len, &dest, &npdu_data, cov_data);
bytes_sent = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len);
return bytes_sent;
@@ -117,9 +113,8 @@ int Send_UCOV_Notify(
* @return invoke id of outgoing message, or 0 if communication is disabled or
* no slot is available from the tsm for sending.
*/
uint8_t Send_COV_Subscribe(
uint32_t device_id,
BACNET_SUBSCRIBE_COV_DATA * cov_data)
uint8_t Send_COV_Subscribe(uint32_t device_id,
BACNET_SUBSCRIBE_COV_DATA* cov_data)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -143,25 +138,24 @@ uint8_t Send_COV_Subscribe(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
len =
cov_subscribe_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer)-pdu_len, invoke_id, cov_data);
len = cov_subscribe_encode_apdu(
&Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer) - pdu_len, invoke_id, cov_data);
pdu_len += len;
/* will it fit in the sender?
note: if there is a bottleneck router in between
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
if (bytes_sent <= 0) {
#if PRINT_ENABLED
fprintf(stderr, "Failed to Send SubscribeCOV Request (%s)!\n",
+38 -40
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -56,10 +56,8 @@
*/
uint8_t Send_Device_Communication_Control_Request(
uint32_t device_id,
uint16_t timeDuration, /* 0=optional */
BACNET_COMMUNICATION_ENABLE_DISABLE state,
char *password)
uint32_t device_id, uint16_t timeDuration, /* 0=optional */
BACNET_COMMUNICATION_ENABLE_DISABLE state, char *password)
{ /* NULL=optional */
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -85,29 +83,29 @@ uint8_t Send_Device_Communication_Control_Request(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
characterstring_init_ansi(&password_string, password);
len =
dcc_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
timeDuration, state, password ? &password_string : NULL);
len = dcc_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
timeDuration, state,
password ? &password_string : NULL);
pdu_len += len;
/* will it fit in the sender?
note: if there is a bottleneck router in between
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
fprintf(
stderr,
"Failed to Send DeviceCommunicationControl Request (%s)!\n",
strerror(errno));
#endif
+31 -39
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2016 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2016 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -42,7 +42,6 @@
#include "handlers.h"
#include "client.h"
/** Encodes an Error message
* @param buffer The buffer to build the message for sending.
* @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.
*/
int error_encode_pdu(
uint8_t * buffer,
BACNET_ADDRESS * dest,
BACNET_ADDRESS * src,
BACNET_NPDU_DATA * npdu_data,
uint8_t invoke_id,
int error_encode_pdu(uint8_t *buffer, BACNET_ADDRESS *dest, BACNET_ADDRESS *src,
BACNET_NPDU_DATA *npdu_data, uint8_t invoke_id,
BACNET_CONFIRMED_SERVICE service,
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
@@ -72,8 +67,8 @@ int error_encode_pdu(
pdu_len = npdu_encode_pdu(&buffer[0], dest, src, npdu_data);
/* encode the APDU portion of the packet */
len = bacerror_encode_apdu(&buffer[pdu_len], invoke_id,
service, error_class, error_code);
len = bacerror_encode_apdu(&buffer[pdu_len], invoke_id, service,
error_class, error_code);
pdu_len += 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.
*/
int Send_Error_To_Network(
uint8_t * buffer,
BACNET_ADDRESS *dest,
uint8_t invoke_id,
BACNET_CONFIRMED_SERVICE service,
int Send_Error_To_Network(uint8_t *buffer, BACNET_ADDRESS *dest,
uint8_t invoke_id, BACNET_CONFIRMED_SERVICE service,
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
@@ -102,8 +94,8 @@ int Send_Error_To_Network(
BACNET_NPDU_DATA npdu_data;
datalink_get_my_address(&src);
pdu_len = error_encode_pdu(buffer, dest, &src, &npdu_data,
invoke_id, service, error_class, error_code);
pdu_len = error_encode_pdu(buffer, dest, &src, &npdu_data, invoke_id,
service, error_class, error_code);
bytes_sent = datalink_send_pdu(dest, &npdu_data, &buffer[0], pdu_len);
return bytes_sent;
+10 -15
View File
@@ -52,9 +52,7 @@
#include "client.h"
#include "get_alarm_sum.h"
uint8_t Send_Get_Alarm_Summary_Address(
BACNET_ADDRESS *dest,
uint16_t max_apdu)
uint8_t Send_Get_Alarm_Summary_Address(BACNET_ADDRESS *dest, uint16_t max_apdu)
{
int len = 0;
int pdu_len = 0;
@@ -72,23 +70,22 @@ uint8_t Send_Get_Alarm_Summary_Address(
/* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
len = get_alarm_summary_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
invoke_id);
pdu_len += len;
if ((uint16_t) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, dest,
&npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t) pdu_len);
if ((uint16_t)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
#if PRINT_ENABLED
bytes_sent =
#endif
datalink_send_pdu(dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
@@ -109,8 +106,7 @@ uint8_t Send_Get_Alarm_Summary_Address(
return invoke_id;
}
uint8_t Send_Get_Alarm_Summary(
uint32_t device_id)
uint8_t Send_Get_Alarm_Summary(uint32_t device_id)
{
BACNET_ADDRESS dest;
unsigned max_apdu = 0;
@@ -120,8 +116,7 @@ uint8_t Send_Get_Alarm_Summary(
/* is the device bound? */
status = address_get_by_device(device_id, &max_apdu, &dest);
if (status) {
invoke_id = Send_Get_Alarm_Summary_Address(
&dest, max_apdu);
invoke_id = Send_Get_Alarm_Summary_Address(&dest, max_apdu);
}
return invoke_id;
+14 -15
View File
@@ -55,9 +55,8 @@
#include "getevent.h"
uint8_t Send_Get_Event_Information_Address(
BACNET_ADDRESS *dest,
uint16_t max_apdu,
BACNET_OBJECT_ID * lastReceivedObjectIdentifier)
BACNET_ADDRESS *dest, uint16_t max_apdu,
BACNET_OBJECT_ID *lastReceivedObjectIdentifier)
{
int len = 0;
int pdu_len = 0;
@@ -74,25 +73,26 @@ uint8_t Send_Get_Event_Information_Address(
datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
len = getevent_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
invoke_id, lastReceivedObjectIdentifier);
len = getevent_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
lastReceivedObjectIdentifier);
pdu_len += len;
if ((uint16_t) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, dest,
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
if ((uint16_t)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
#if PRINT_ENABLED
bytes_sent =
#endif
datalink_send_pdu(dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
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));
#endif
} else {
@@ -110,8 +110,7 @@ uint8_t Send_Get_Event_Information_Address(
}
uint8_t Send_Get_Event_Information(
uint32_t device_id,
BACNET_OBJECT_ID * lastReceivedObjectIdentifier)
uint32_t device_id, BACNET_OBJECT_ID *lastReceivedObjectIdentifier)
{
BACNET_ADDRESS dest = {0};
unsigned max_apdu = 0;
+36 -39
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2015 bowe
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2015 bowe
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -46,13 +46,12 @@
/** @file s_getevent.c Send a GetEventInformation request. */
/** Send a GetEventInformation request to a remote network for a specific device, a range,
* or any device.
/** Send a GetEventInformation request to a remote network for a specific
* device, a range, or any device.
* @param target_address [in] BACnet address of target or broadcast
*/
uint8_t Send_GetEvent(
BACNET_ADDRESS * target_address,
BACNET_OBJECT_ID * lastReceivedObjectIdentifier)
uint8_t Send_GetEvent(BACNET_ADDRESS* target_address,
BACNET_OBJECT_ID* lastReceivedObjectIdentifier)
{
int len = 0;
int pdu_len = 0;
@@ -65,24 +64,23 @@ uint8_t Send_GetEvent(
/* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address,
&my_address, &npdu_data);
invoke_id = tsm_next_free_invokeID();
if (invoke_id) {
/* encode the APDU portion of the packet */
len =
getevent_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, lastReceivedObjectIdentifier);
len = getevent_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
lastReceivedObjectIdentifier);
pdu_len += len;
bytes_sent =
datalink_send_pdu(target_address, &npdu_data,
bytes_sent = datalink_send_pdu(target_address, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send GetEventInformation Request (%s)!\n",
fprintf(stderr,
"Failed to Send GetEventInformation Request (%s)!\n",
strerror(errno));
#endif
#endif
} else {
tsm_free_invoke_id(invoke_id);
invoke_id = 0;
@@ -97,7 +95,7 @@ uint8_t Send_GetEvent(
/** Send a global GetEventInformation request.
*/
uint8_t Send_GetEvent_Global( void )
uint8_t Send_GetEvent_Global(void)
{
BACNET_ADDRESS dest;
@@ -108,4 +106,3 @@ uint8_t Send_GetEvent_Global( void )
return Send_GetEvent(&dest, NULL);
}
+42 -58
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -51,11 +51,8 @@
* @param segmentation [in] #BACNET_SEGMENTATION enumeration
* @param vendor_id [in] BACnet vendor ID 0-65535
*/
void Send_I_Am_To_Network(
BACNET_ADDRESS * target_address,
uint32_t device_id,
unsigned int max_apdu,
int segmentation,
void Send_I_Am_To_Network(BACNET_ADDRESS* target_address, uint32_t device_id,
unsigned int max_apdu, int segmentation,
uint16_t vendor_id)
{
int len = 0;
@@ -68,25 +65,20 @@ void Send_I_Am_To_Network(
/* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
/* encode the APDU portion of the packet */
len =
iam_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
device_id, max_apdu, segmentation, vendor_id);
len = iam_encode_apdu(&Handler_Transmit_Buffer[pdu_len], device_id,
max_apdu, segmentation, vendor_id);
pdu_len += len;
bytes_sent =
datalink_send_pdu(target_address, &npdu_data,
bytes_sent = datalink_send_pdu(target_address, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if (bytes_sent <= 0) {
#if PRINT_ENABLED
fprintf(stderr, "Failed to Send I-Am Request (%s)!\n",
strerror(errno));
fprintf(stderr, "Failed to Send I-Am Request (%s)!\n", strerror(errno));
#endif
}
}
/** Encode an I Am message to be broadcast.
@@ -95,10 +87,8 @@ void Send_I_Am_To_Network(
* @param npdu_data [out] The NPDU structure describing the message.
* @return The length of the message in buffer[].
*/
int iam_encode_pdu(
uint8_t * buffer,
BACNET_ADDRESS * dest,
BACNET_NPDU_DATA * npdu_data)
int iam_encode_pdu(uint8_t* buffer, BACNET_ADDRESS* dest,
BACNET_NPDU_DATA* npdu_data)
{
int len = 0;
int pdu_len = 0;
@@ -111,9 +101,9 @@ int iam_encode_pdu(
pdu_len = npdu_encode_pdu(&buffer[0], dest, &my_address, npdu_data);
/* encode the APDU portion of the packet */
len =
iam_encode_apdu(&buffer[pdu_len], Device_Object_Instance_Number(),
MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier());
len = iam_encode_apdu(&buffer[pdu_len], Device_Object_Instance_Number(),
MAX_APDU, SEGMENTATION_NONE,
Device_Vendor_Identifier());
pdu_len += 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.
*/
void Send_I_Am(
uint8_t * buffer)
void Send_I_Am(uint8_t* buffer)
{
int pdu_len = 0;
BACNET_ADDRESS dest;
@@ -165,11 +154,8 @@ void Send_I_Am(
* @param npdu_data [out] The NPDU structure describing the message.
* @return The length of the message in buffer[].
*/
int iam_unicast_encode_pdu(
uint8_t * buffer,
BACNET_ADDRESS * src,
BACNET_ADDRESS * dest,
BACNET_NPDU_DATA * npdu_data)
int iam_unicast_encode_pdu(uint8_t* buffer, BACNET_ADDRESS* src,
BACNET_ADDRESS* dest, BACNET_NPDU_DATA* npdu_data)
{
int npdu_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_len = npdu_encode_pdu(&buffer[0], dest, &my_address, npdu_data);
/* encode the APDU portion of the packet */
apdu_len =
iam_encode_apdu(&buffer[npdu_len], Device_Object_Instance_Number(),
MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier());
apdu_len = iam_encode_apdu(&buffer[npdu_len],
Device_Object_Instance_Number(), MAX_APDU,
SEGMENTATION_NONE, Device_Vendor_Identifier());
pdu_len = npdu_len + apdu_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 src [in] The source address information from service handler.
*/
void Send_I_Am_Unicast(
uint8_t * buffer,
BACNET_ADDRESS * src)
void Send_I_Am_Unicast(uint8_t* buffer, BACNET_ADDRESS* src)
{
int pdu_len = 0;
BACNET_ADDRESS dest;
+29 -35
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -53,11 +53,8 @@
* @param object_instance [in] The Object ID that I Have.
* @param object_name [in] The Name of the Object I Have.
*/
void Send_I_Have(
uint32_t device_id,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
void Send_I_Have(uint32_t device_id, BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, BACNET_CHARACTER_STRING* object_name)
{
int len = 0;
int pdu_len = 0;
@@ -75,8 +72,7 @@ void Send_I_Have(
datalink_get_broadcast_address(&dest);
/* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
/* 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);
pdu_len += len;
/* send the data */
bytes_sent =
datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if (bytes_sent <= 0) {
#if PRINT_ENABLED
fprintf(stderr, "Failed to Send I-Have Reply (%s)!\n",
strerror(errno));
fprintf(stderr, "Failed to Send I-Have Reply (%s)!\n", strerror(errno));
#endif
}
}
+34 -38
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2009 John Minack <minack@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2009 John Minack <minack@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -48,10 +48,8 @@
/* returns the invoke ID for confirmed request, or zero on failure */
uint8_t Send_Life_Safety_Operation_Data(
uint32_t device_id,
BACNET_LSO_DATA * data)
uint8_t Send_Life_Safety_Operation_Data(uint32_t device_id,
BACNET_LSO_DATA* data)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -75,24 +73,22 @@ uint8_t Send_Life_Safety_Operation_Data(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data);
len =
lso_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
data);
lso_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, data);
pdu_len += len;
/* will it fit in the sender?
note: if there is a bottleneck router in between
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Life Safe Op Request (%s)!\n",
+51 -56
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
@@ -48,19 +48,13 @@
/** @file s_ptransfer.c Send a Private Transfer request. */
/* This function is exported. Hence this unnecessary prototype. */
uint8_t Send_Private_Transfer_Request(
uint32_t device_id,
uint16_t vendor_id,
uint8_t Send_Private_Transfer_Request(uint32_t device_id, uint16_t vendor_id,
uint32_t service_number,
char block_number,
DATABLOCK * block);
char block_number, DATABLOCK *block);
uint8_t Send_Private_Transfer_Request(
uint32_t device_id,
uint16_t vendor_id,
uint8_t Send_Private_Transfer_Request(uint32_t device_id, uint16_t vendor_id,
uint32_t service_number,
char block_number,
DATABLOCK * block)
char block_number, DATABLOCK *block)
{ /* NULL=optional */
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -71,7 +65,8 @@ uint8_t Send_Private_Transfer_Request(
int pdu_len = 0;
int bytes_sent = 0;
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_CHARACTER_STRING bsTemp;
@@ -88,34 +83,34 @@ uint8_t Send_Private_Transfer_Request(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
pt_block.vendorID = vendor_id;
pt_block.serviceNumber = service_number;
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 {
len += encode_application_unsigned(&pt_req_buffer[len], block_number); /* The block number */
len += encode_application_unsigned(&pt_req_buffer[len], block->cMyByte1); /* And Then the block contents */
len +=
encode_application_unsigned(&pt_req_buffer[len],
len += encode_application_unsigned(
&pt_req_buffer[len], block_number); /* The block number */
len += encode_application_unsigned(
&pt_req_buffer[len],
block->cMyByte1); /* And Then the block contents */
len += encode_application_unsigned(&pt_req_buffer[len],
block->cMyByte2);
len +=
encode_application_real(&pt_req_buffer[len], block->fMyReal);
characterstring_init_ansi(&bsTemp, (char *) block->sMyString);
len +=
encode_application_character_string(&pt_req_buffer[len],
len += encode_application_real(&pt_req_buffer[len], block->fMyReal);
characterstring_init_ansi(&bsTemp, (char *)block->sMyString);
len += encode_application_character_string(&pt_req_buffer[len],
&bsTemp);
}
pt_block.serviceParameters = &pt_req_buffer[0];
pt_block.serviceParametersLen = len;
len =
ptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
&pt_block);
len = ptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
invoke_id, &pt_block);
pdu_len += len;
/* will it fit in the sender?
@@ -124,12 +119,12 @@ uint8_t Send_Private_Transfer_Request(
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
+36 -38
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -49,12 +49,12 @@
* @ingroup DMRD
*
* @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.
* @return The invokeID of the transmitted message, or 0 on failure.
*/
uint8_t Send_Reinitialize_Device_Request(
uint32_t device_id,
uint8_t Send_Reinitialize_Device_Request(uint32_t device_id,
BACNET_REINITIALIZED_STATE state,
char *password)
{
@@ -82,26 +82,24 @@ uint8_t Send_Reinitialize_Device_Request(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
characterstring_init_ansi(&password_string, password);
len =
rd_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, state,
password ? &password_string : NULL);
len = rd_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
state, password ? &password_string : NULL);
pdu_len += len;
/* will it fit in the sender?
note: if there is a bottleneck router in between
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
+36 -38
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -47,9 +47,8 @@
/** @file s_readrange.c Send a ReadRange request. */
/* returns invoke id of 0 if device is not bound or no tsm available */
uint8_t Send_ReadRange_Request(
uint32_t device_id, /* destination device */
BACNET_READ_RANGE_DATA * read_access_data)
uint8_t Send_ReadRange_Request(uint32_t device_id, /* destination device */
BACNET_READ_RANGE_DATA* read_access_data)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -74,13 +73,11 @@ uint8_t Send_ReadRange_Request(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
len =
rr_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
len = rr_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
read_access_data);
if (len <= 0) {
return 0;
@@ -92,12 +89,12 @@ uint8_t Send_ReadRange_Request(
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send ReadRange Request (%s)!\n",
@@ -108,7 +105,8 @@ uint8_t Send_ReadRange_Request(
invoke_id = 0;
#if PRINT_ENABLED
fprintf(stderr,
"Failed to Send ReadRange Request (exceeds destination maximum APDU)!\n");
"Failed to Send ReadRange Request (exceeds destination "
"maximum APDU)!\n");
#endif
}
}
+52 -69
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -43,7 +43,8 @@
#include "client.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,
* and add the Network Layer Message fields.
@@ -52,16 +53,16 @@
* APDU instead of a Network Layer Message.
*
* @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 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,
* like B'11' = Life Safety message
*/
static void npdu_encode_npdu_network(
BACNET_NPDU_DATA * npdu_data,
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
bool data_expecting_reply,
BACNET_NPDU_DATA *npdu_data,
BACNET_NETWORK_MESSAGE_TYPE network_message_type, bool data_expecting_reply,
BACNET_MESSAGE_PRIORITY priority)
{
if (npdu_data) {
@@ -75,7 +76,6 @@ static void npdu_encode_npdu_network(
}
}
/** Function to encode and send any supported Network Layer Message.
* The payload for the message is encoded from information in the iArgs[] array.
* The contents of iArgs are are, per message type:
@@ -97,10 +97,8 @@ static void npdu_encode_npdu_network(
* the type of message.
* @return Number of bytes sent, or <=0 if no message was sent.
*/
int Send_Network_Layer_Message(
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
BACNET_ADDRESS * dst,
int *iArgs)
int Send_Network_Layer_Message(BACNET_NETWORK_MESSAGE_TYPE network_message_type,
BACNET_ADDRESS *dst, int *iArgs)
{
int len = 0;
int pdu_len = 0;
@@ -134,9 +132,8 @@ int Send_Network_Layer_Message(
switch (network_message_type) {
case NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK:
if (*pVal >= 0) {
len =
encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
(uint16_t) * pVal);
len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
(uint16_t)*pVal);
pdu_len += len;
}
/* else, don't encode a DNET */
@@ -146,9 +143,8 @@ int Send_Network_Layer_Message(
case NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK:
case NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK:
while (*pVal >= 0) {
len =
encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
(uint16_t) * pVal);
len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
(uint16_t)*pVal);
pdu_len += len;
pVal++;
}
@@ -156,11 +152,10 @@ int Send_Network_Layer_Message(
case NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK:
/* Encode the Reason byte, then the DNET */
Handler_Transmit_Buffer[pdu_len++] = (uint8_t) * pVal;
Handler_Transmit_Buffer[pdu_len++] = (uint8_t)*pVal;
pVal++;
len =
encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
(uint16_t) * pVal);
len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
(uint16_t)*pVal);
pdu_len += len;
break;
@@ -172,7 +167,7 @@ int Send_Network_Layer_Message(
len++;
pVal++;
}
Handler_Transmit_Buffer[pdu_len++] = (uint8_t) len;
Handler_Transmit_Buffer[pdu_len++] = (uint8_t)len;
if (len > 0) {
uint8_t portID = 1;
@@ -182,9 +177,8 @@ int Send_Network_Layer_Message(
* and have no PortInfo.
*/
while (*pVal >= 0) {
len =
encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
(uint16_t) * pVal);
len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
(uint16_t)*pVal);
pdu_len += len;
Handler_Transmit_Buffer[pdu_len++] = portID++;
Handler_Transmit_Buffer[pdu_len++] = 0;
@@ -204,14 +198,14 @@ int Send_Network_Layer_Message(
if (dst != NULL)
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
debug_printf("Sending %s message to local BACnet network \n",
bactext_network_layer_msg_name(network_message_type));
/* Now send the message */
bytes_sent =
datalink_send_pdu(dst, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = datalink_send_pdu(dst, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0) {
@@ -224,7 +218,6 @@ int Send_Network_Layer_Message(
return bytes_sent;
}
/** Finds a specific router, or all reachable BACnet networks.
* The response(s) will come in I-am-router-to-network message(s).
* @ingroup NMRC
@@ -236,9 +229,7 @@ int Send_Network_Layer_Message(
* will be sent and the receiving router(s) will send
* their full list of reachable BACnet networks.
*/
void Send_Who_Is_Router_To_Network(
BACNET_ADDRESS * dst,
int dnet)
void Send_Who_Is_Router_To_Network(BACNET_ADDRESS *dst, int dnet)
{
Send_Network_Layer_Message(NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, dst,
&dnet);
@@ -253,12 +244,11 @@ void Send_Who_Is_Router_To_Network(
* @param DNET_list [in] List of BACnet network numbers for which I am a router,
* terminated with -1
*/
void Send_I_Am_Router_To_Network(
const int DNET_list[])
void Send_I_Am_Router_To_Network(const int DNET_list[])
{
/* Use a NULL dst here since we want a broadcast MAC address. */
Send_Network_Layer_Message(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, NULL,
(int *) DNET_list);
(int *)DNET_list);
}
/** Finds a specific router, or all reachable BACnet networks.
@@ -271,9 +261,7 @@ void Send_I_Am_Router_To_Network(
* @param reject_reason [in] One of the BACNET_NETWORK_REJECT_REASONS codes.
* @param dnet [in] Which BACnet network orginated the message.
*/
void Send_Reject_Message_To_Network(
BACNET_ADDRESS * dst,
uint8_t reject_reason,
void Send_Reject_Message_To_Network(BACNET_ADDRESS *dst, uint8_t reject_reason,
int dnet)
{
int iArgs[2];
@@ -284,7 +272,6 @@ void Send_Reject_Message_To_Network(
debug_printf(" Reject Reason=%d, DNET=%u\n", reject_reason, dnet);
}
/** Send an Initialize Routing Table message, built from an optional DNET[]
* array.
* 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
* requesting a routing table.
*/
void Send_Initialize_Routing_Table(
BACNET_ADDRESS * dst,
const int DNET_list[])
void Send_Initialize_Routing_Table(BACNET_ADDRESS *dst, const int DNET_list[])
{
/* Use a NULL dst here since we want a broadcast MAC address. */
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.
* There are two cases here:
* 1) We are responding to a NETWORK_MESSAGE_INIT_RT_TABLE requesting our table.
@@ -328,10 +312,9 @@ void Send_Initialize_Routing_Table(
* terminated with -1. May be just -1 when no table
* should be sent.
*/
void Send_Initialize_Routing_Table_Ack(
BACNET_ADDRESS * dst,
void Send_Initialize_Routing_Table_Ack(BACNET_ADDRESS *dst,
const int DNET_list[])
{
Send_Network_Layer_Message(NETWORK_MESSAGE_INIT_RT_TABLE_ACK, dst,
(int *) DNET_list);
(int *)DNET_list);
}
+46 -46
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -52,15 +52,16 @@
* @param max_apdu [in]
* @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_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,
* - 0 for the array size
* - 1 to n for individual array members
* - 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(
BACNET_ADDRESS * dest,
uint8_t Send_Read_Property_Request_Address(BACNET_ADDRESS* dest,
uint16_t max_apdu,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
@@ -87,29 +88,27 @@ uint8_t Send_Read_Property_Request_Address(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
&npdu_data);
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
data.object_type = object_type;
data.object_instance = object_instance;
data.object_property = object_property;
data.array_index = array_index;
len =
rp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
&data);
rp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, &data);
pdu_len += len;
/* will it fit in the sender?
note: if there is a bottleneck router in between
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((uint16_t) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, dest,
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if ((uint16_t)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(
dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
if (bytes_sent <= 0) {
#if PRINT_ENABLED
fprintf(stderr, "Failed to Send ReadProperty Request (%s)!\n",
@@ -136,21 +135,22 @@ uint8_t Send_Read_Property_Request_Address(
* @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_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,
* - 0 for the array size
* - 1 to n for individual array members
* - 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(
uint32_t device_id, /* destination device */
uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_PROPERTY_ID object_property,
uint32_t array_index)
{
BACNET_ADDRESS dest = { 0 };
BACNET_ADDRESS dest = {0};
unsigned max_apdu = 0;
uint8_t invoke_id = 0;
bool status = false;
@@ -158,9 +158,9 @@ uint8_t Send_Read_Property_Request(
/* is the device bound? */
status = address_get_by_device(device_id, &max_apdu, &dest);
if (status) {
invoke_id =
Send_Read_Property_Request_Address(&dest, max_apdu, object_type,
object_instance, object_property, array_index);
invoke_id = Send_Read_Property_Request_Address(
&dest, max_apdu, object_type, object_instance, object_property,
array_index);
}
return invoke_id;
+32 -35
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -53,13 +53,12 @@
* @param device_id [in] ID of the destination device
* @param read_access_data [in] Ptr to structure with the linked list of
* 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 * pdu,
size_t max_pdu,
uint32_t device_id, /* destination device */
BACNET_READ_ACCESS_DATA * read_access_data)
uint8_t* pdu, size_t max_pdu, uint32_t device_id, /* destination device */
BACNET_READ_ACCESS_DATA* read_access_data)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -85,8 +84,7 @@ uint8_t Send_Read_Property_Multiple_Request(
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len = npdu_encode_pdu(&pdu[0], &dest, &my_address, &npdu_data);
/* encode the APDU portion of the packet */
len =
rpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len, invoke_id,
len = rpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len, invoke_id,
read_access_data);
if (len <= 0) {
return 0;
@@ -97,11 +95,10 @@ uint8_t Send_Read_Property_Multiple_Request(
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &pdu[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data, &pdu[0], pdu_len);
if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &pdu[0], (uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(&dest, &npdu_data, &pdu[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
+38 -52
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -52,10 +52,8 @@
* @param bdate - #BACNET_DATE
* @param btime - #BACNET_TIME
*/
void Send_TimeSync_Remote(
BACNET_ADDRESS * dest,
BACNET_DATE * bdate,
BACNET_TIME * btime)
void Send_TimeSync_Remote(BACNET_ADDRESS* dest, BACNET_DATE* bdate,
BACNET_TIME* btime)
{
int len = 0;
int pdu_len = 0;
@@ -69,17 +67,14 @@ void Send_TimeSync_Remote(
datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
&npdu_data);
/* encode the APDU portion of the packet */
len =
timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate, btime);
len = timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate, btime);
pdu_len += len;
/* send it out the datalink */
bytes_sent =
datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
bytes_sent = datalink_send_pdu(dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Time-Synchronization Request (%s)!\n",
@@ -93,9 +88,7 @@ void Send_TimeSync_Remote(
* @param bdate - #BACNET_DATE
* @param btime - #BACNET_TIME
*/
void Send_TimeSync(
BACNET_DATE * bdate,
BACNET_TIME * btime)
void Send_TimeSync(BACNET_DATE* bdate, BACNET_TIME* btime)
{
BACNET_ADDRESS dest;
@@ -110,10 +103,8 @@ void Send_TimeSync(
* @param bdate - #BACNET_DATE
* @param btime - #BACNET_TIME
*/
void Send_TimeSyncUTC_Remote(
BACNET_ADDRESS * dest,
BACNET_DATE * bdate,
BACNET_TIME * btime)
void Send_TimeSyncUTC_Remote(BACNET_ADDRESS* dest, BACNET_DATE* bdate,
BACNET_TIME* btime)
{
int len = 0;
int pdu_len = 0;
@@ -127,17 +118,14 @@ void Send_TimeSyncUTC_Remote(
datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
&npdu_data);
/* encode the APDU portion of the packet */
len =
timesync_utc_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
bdate, btime);
len = timesync_utc_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate,
btime);
pdu_len += len;
bytes_sent =
datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
bytes_sent = datalink_send_pdu(dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
@@ -152,9 +140,7 @@ void Send_TimeSyncUTC_Remote(
* @param bdate - #BACNET_DATE
* @param btime - #BACNET_TIME
*/
void Send_TimeSyncUTC(
BACNET_DATE * bdate,
BACNET_TIME * btime)
void Send_TimeSyncUTC(BACNET_DATE* bdate, BACNET_TIME* btime)
{
BACNET_ADDRESS dest;
+25 -27
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2008 John Minack
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2008 John Minack
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -40,10 +40,8 @@
* @param dest [in] The destination address information (may be a broadcast).
* @return Size of the message sent (bytes), or a negative value on error.
*/
int Send_UEvent_Notify(
uint8_t * buffer,
BACNET_EVENT_NOTIFICATION_DATA * data,
BACNET_ADDRESS * dest)
int Send_UEvent_Notify(uint8_t* buffer, BACNET_EVENT_NOTIFICATION_DATA* data,
BACNET_ADDRESS* dest)
{
int len = 0;
int pdu_len = 0;
+29 -33
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -45,9 +45,8 @@
/** @file s_upt.c Send an Unconfirmed Private Transfer request. */
int Send_UnconfirmedPrivateTransfer(
BACNET_ADDRESS * dest,
BACNET_PRIVATE_TRANSFER_DATA * private_data)
int Send_UnconfirmedPrivateTransfer(BACNET_ADDRESS* dest,
BACNET_PRIVATE_TRANSFER_DATA* private_data)
{
int len = 0;
int pdu_len = 0;
@@ -61,18 +60,15 @@ int Send_UnconfirmedPrivateTransfer(
datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
&npdu_data);
/* encode the APDU portion of the packet */
len =
uptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
private_data);
uptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len], private_data);
pdu_len += len;
bytes_sent =
datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
bytes_sent = datalink_send_pdu(dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if (bytes_sent <= 0) {
#if PRINT_ENABLED
fprintf(stderr,
+39 -47
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -47,17 +47,15 @@
/** Send a Who-Has request for a device which has a named Object.
* @ingroup DMDOB
* If low_limit and high_limit both are -1, then the device ID range is unlimited.
* If low_limit and high_limit have the same non-negative value, then only
* that device will respond.
* Otherwise, low_limit must be less than high_limit for a range.
* If low_limit and high_limit both are -1, then the device ID range is
* unlimited. If low_limit and high_limit have the same non-negative value, then
* only that device will respond. Otherwise, low_limit must be less than
* high_limit for a range.
* @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 object_name [in] The Name of the desired Object.
*/
void Send_WhoHas_Name(
int32_t low_limit,
int32_t high_limit,
void Send_WhoHas_Name(int32_t low_limit, int32_t high_limit,
const char *object_name)
{
int len = 0;
@@ -76,8 +74,7 @@ void Send_WhoHas_Name(
datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
/* 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);
pdu_len += len;
/* send the data */
bytes_sent =
datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
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.
* @ingroup DMDOB
* If low_limit and high_limit both are -1, then the device ID range is unlimited.
* If low_limit and high_limit have the same non-negative value, then only
* that device will respond.
* Otherwise, low_limit must be less than high_limit for a range.
* If low_limit and high_limit both are -1, then the device ID range is
* unlimited. If low_limit and high_limit have the same non-negative value, then
* only that device will respond. Otherwise, low_limit must be less than
* high_limit for a range.
* @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 object_type [in] The BACNET_OBJECT_TYPE of the desired Object.
* @param object_instance [in] The ID of the desired Object.
*/
void Send_WhoHas_Object(
int32_t low_limit,
int32_t high_limit,
void Send_WhoHas_Object(int32_t low_limit, int32_t high_limit,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance)
{
@@ -131,8 +125,7 @@ void Send_WhoHas_Object(
datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
/* encode the APDU portion of the packet */
@@ -143,9 +136,8 @@ void Send_WhoHas_Object(
data.object.identifier.instance = object_instance;
len = whohas_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data);
pdu_len += len;
bytes_sent =
datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len);
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Who-Has Request (%s)!\n",
+33 -46
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -56,9 +56,7 @@
* @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
*/
void Send_WhoIs_To_Network(
BACNET_ADDRESS * target_address,
int32_t low_limit,
void Send_WhoIs_To_Network(BACNET_ADDRESS* target_address, int32_t low_limit,
int32_t high_limit)
{
int len = 0;
@@ -71,16 +69,13 @@ void Send_WhoIs_To_Network(
/* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address,
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
len =
whois_encode_apdu(&Handler_Transmit_Buffer[pdu_len], low_limit,
len = whois_encode_apdu(&Handler_Transmit_Buffer[pdu_len], low_limit,
high_limit);
pdu_len += len;
bytes_sent =
datalink_send_pdu(target_address, &npdu_data,
bytes_sent = datalink_send_pdu(target_address, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
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 high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
*/
void Send_WhoIs_Global(
int32_t low_limit,
int32_t high_limit)
void Send_WhoIs_Global(int32_t low_limit, int32_t high_limit)
{
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 high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
*/
void Send_WhoIs_Local(
int32_t low_limit,
int32_t high_limit)
void Send_WhoIs_Local(int32_t low_limit, int32_t high_limit)
{
BACNET_ADDRESS dest;
char temp[6];
@@ -138,7 +129,8 @@ void Send_WhoIs_Local(
/* I added this to make it a local broadcast */
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[1] = dest.mac[2];
@@ -147,7 +139,6 @@ void Send_WhoIs_Local(
temp[4] = dest.mac[5];
temp[5] = dest.mac[4];
for (loop = 0; loop < 6; 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 high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
*/
void Send_WhoIs_Remote(
BACNET_ADDRESS * target_address,
int32_t low_limit,
void Send_WhoIs_Remote(BACNET_ADDRESS* target_address, int32_t low_limit,
int32_t high_limit)
{
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 high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
*/
void Send_WhoIs(
int32_t low_limit,
int32_t high_limit)
void Send_WhoIs(int32_t low_limit, int32_t high_limit)
{
Send_WhoIs_Global(low_limit, high_limit);
}
+47 -53
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -46,15 +46,13 @@
/** @file s_wp.c Send a Write Property request. */
/** returns the invoke ID for confirmed request, or zero on failure */
uint8_t Send_Write_Property_Request_Data(
uint32_t device_id,
uint8_t Send_Write_Property_Request_Data(uint32_t device_id,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_PROPERTY_ID object_property,
uint8_t * application_data,
uint8_t* application_data,
int application_data_len,
uint8_t priority,
uint32_t array_index)
uint8_t priority, uint32_t array_index)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -79,9 +77,8 @@ uint8_t Send_Write_Property_Request_Data(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data);
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data);
/* encode the APDU portion of the packet */
data.object_type = object_type;
data.object_instance = object_instance;
@@ -92,20 +89,19 @@ uint8_t Send_Write_Property_Request_Data(
application_data_len);
data.priority = priority;
len =
wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
&data);
wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, &data);
pdu_len += len;
/* will it fit in the sender?
note: if there is a bottleneck router in between
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send WriteProperty Request (%s)!\n",
@@ -125,7 +121,6 @@ uint8_t Send_Write_Property_Request_Data(
return invoke_id;
}
/** Sends a Write Property request.
* @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)
* @return invoke id of outgoing message, or 0 on failure.
*/
uint8_t Send_Write_Property_Request(
uint32_t device_id,
uint8_t Send_Write_Property_Request(uint32_t device_id,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_PROPERTY_ID object_property,
BACNET_APPLICATION_DATA_VALUE * object_value,
uint8_t priority,
uint32_t array_index)
BACNET_APPLICATION_DATA_VALUE* object_value,
uint8_t priority, uint32_t array_index)
{
uint8_t application_data[MAX_APDU] = { 0 };
uint8_t application_data[MAX_APDU] = {0};
int apdu_len = 0, len = 0;
while (object_value) {
#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"),
(int) (object_value->
context_specific ? object_value->context_tag : object_value->
tag));
(int)(object_value->context_specific ? object_value->context_tag
: object_value->tag));
#endif
len = bacapp_encode_data(&application_data[apdu_len], object_value);
if ((len + apdu_len) < MAX_APDU) {
@@ -170,7 +164,7 @@ uint8_t Send_Write_Property_Request(
object_value = object_value->next;
}
return Send_Write_Property_Request_Data(device_id, object_type,
object_instance, object_property, &application_data[0], apdu_len,
priority, array_index);
return Send_Write_Property_Request_Data(
device_id, object_type, object_instance, object_property,
&application_data[0], apdu_len, priority, array_index);
}
+39 -43
View File
@@ -1,32 +1,32 @@
/**
* @file
* @author Daniel Blazevic <daniel.blazevic@gmail.com>
* @date 2013
* @brief Send Write Property Multiple request
*
* @section LICENSE
*
* Copyright (C) 2013 Daniel Blazevic <daniel.blazevic@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
* @file
* @author Daniel Blazevic <daniel.blazevic@gmail.com>
* @date 2013
* @brief Send Write Property Multiple request
*
* @section LICENSE
*
* Copyright (C) 2013 Daniel Blazevic <daniel.blazevic@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
@@ -55,13 +55,12 @@
* @param device_id [in] ID of the destination device
* @param write_access_data [in] Ptr to structure with the linked list of
* 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 * pdu,
size_t max_pdu,
uint32_t device_id,
BACNET_WRITE_ACCESS_DATA * write_access_data)
uint8_t* pdu, size_t max_pdu, uint32_t device_id,
BACNET_WRITE_ACCESS_DATA* write_access_data)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -87,11 +86,10 @@ uint8_t Send_Write_Property_Multiple_Request(
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
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 */
len =
wpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len,
invoke_id, write_access_data);
len = wpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len, invoke_id,
write_access_data);
pdu_len += len;
/* will it fit in the sender?
@@ -99,12 +97,10 @@ uint8_t Send_Write_Property_Multiple_Request(
us and the destination, we won't know unless
we have a way to check for that and update the
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &pdu[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&pdu[0], pdu_len);
if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(
invoke_id, &dest, &npdu_data, &pdu[0], (uint16_t)pdu_len);
bytes_sent = datalink_send_pdu(&dest, &npdu_data, &pdu[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0) {
fprintf(stderr,
+24 -24
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include "config.h"
@@ -29,4 +29,4 @@
/** @file txbuf.c Declare the global Transmit Buffer for handler functions. */
uint8_t Handler_Transmit_Buffer[MAX_PDU] = { 0 };
uint8_t Handler_Transmit_Buffer[MAX_PDU] = {0};
+49 -56
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2016 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2016 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service */
#include <stddef.h>
@@ -55,32 +55,26 @@ static int Target_Segmentation = SEGMENTATION_NONE;
/* flag for signalling errors */
static bool Error_Detected = false;
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t abort_reason, bool server)
{
(void) src;
(void) invoke_id;
(void) server;
(void)src;
(void)invoke_id;
(void)server;
printf("BACnet Abort: %s\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t reject_reason)
{
(void) src;
(void) invoke_id;
(void)src;
(void)invoke_id;
printf("BACnet Reject: %s\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(
void)
static void Init_Service_Handlers(void)
{
Device_Init(NULL);
/* 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);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
@@ -111,7 +104,8 @@ static void print_usage(char *filename)
static void print_help(char *filename)
{
printf("Send BACnet I-Am message for a device.\n");
printf("--mac A\n"
printf(
"--mac A\n"
"Optional BACnet mac address."
"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"
@@ -123,12 +117,14 @@ static void print_help(char *filename)
"and 65535 is network broadcast.\n"
"\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"
"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"
"\n");
printf("device-instance:\n"
printf(
"device-instance:\n"
" BACnet device-ID 0..4194303\n"
"vendor-id:\n"
" Vendor Identifier 0..65535\n"
@@ -141,14 +137,12 @@ static void print_help(char *filename)
filename);
}
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
long dnet = -1;
BACNET_MAC_ADDRESS mac = { 0 };
BACNET_MAC_ADDRESS adr = { 0 };
BACNET_ADDRESS dest = { 0 };
BACNET_MAC_ADDRESS mac = {0};
BACNET_MAC_ADDRESS adr = {0};
BACNET_ADDRESS dest = {0};
bool specific_address = false;
int argi = 0;
unsigned int target_args = 0;
@@ -163,8 +157,10 @@ int main(
}
if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2016 by Steve Karg and others.\n"
"This is free software; see the source for copying conditions.\n"
printf(
"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"
"FITNESS FOR A PARTICULAR PURPOSE.\n");
return 0;
@@ -245,11 +241,8 @@ int main(
dlenv_init();
atexit(datalink_cleanup);
/* send the request */
Send_I_Am_To_Network(&dest,
Target_Device_ID,
Target_Max_APDU,
Target_Segmentation,
Target_Vendor_ID);
Send_I_Am_To_Network(&dest, Target_Device_ID, Target_Max_APDU,
Target_Segmentation, Target_Vendor_ID);
return 0;
}
+45 -49
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
@@ -49,38 +49,32 @@
/* global variables used in this file */
#define MAX_ROUTER_DNETS 64
static int Target_Router_Networks[MAX_ROUTER_DNETS] = { -1 };
static int Target_Router_Networks[MAX_ROUTER_DNETS] = {-1};
static bool Error_Detected = false;
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t abort_reason, bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
(void)src;
(void)invoke_id;
(void)server;
printf("BACnet Abort: %s\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void)src;
(void)invoke_id;
printf("BACnet Reject: %s\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(
void)
static void Init_Service_Handlers(void)
{
Device_Init(NULL);
/* 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);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
@@ -108,19 +101,20 @@ static void print_usage(char *filename)
static void print_help(char *filename)
{
printf("Send BACnet I-Am-Router-To-Network message for \n"
"one or more networks.\n" "\nDNET:\n"
printf(
"Send BACnet I-Am-Router-To-Network message for \n"
"one or more networks.\n"
"\nDNET:\n"
"BACnet destination network number 0-65534\n"
"To send a I-Am-Router-To-Network message for DNET 86:\n"
"%s 86\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);
}
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
unsigned arg_count = 0;
int argi = 0;
@@ -135,8 +129,10 @@ int main(
}
if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2014 by Steve Karg and others.\n"
"This is free software; see the source for copying conditions.\n"
printf(
"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"
"FITNESS FOR A PARTICULAR PURPOSE.\n");
exit(0);
+65 -75
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the reply */
#include <stddef.h>
@@ -52,7 +52,7 @@
#include "dlenv.h"
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
static uint8_t Rx_Buf[MAX_MPDU] = {0};
/* target address */
static BACNET_ADDRESS Target_Router_Address;
@@ -68,36 +68,29 @@ int DNET_list[2] = {
static bool Error_Detected = false;
static void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t abort_reason, bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
(void)src;
(void)invoke_id;
(void)server;
printf("BACnet Abort: %s\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
static void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
static void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void)src;
(void)invoke_id;
printf("BACnet Reject: %s\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void My_Router_Handler(
BACNET_ADDRESS * src,
BACNET_NPDU_DATA * npdu_data,
uint8_t * npdu, /* PDU data */
static void My_Router_Handler(BACNET_ADDRESS *src, BACNET_NPDU_DATA *npdu_data,
uint8_t *npdu, /* PDU data */
uint16_t npdu_len)
{
uint16_t npdu_offset = 0;
@@ -183,20 +176,19 @@ static void My_Router_Handler(
}
}
static void My_NPDU_Handler(
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */
uint16_t pdu_len)
{ /* length PDU */
int apdu_offset = 0;
BACNET_ADDRESS dest = { 0 };
BACNET_NPDU_DATA npdu_data = { 0 };
BACNET_ADDRESS dest = {0};
BACNET_NPDU_DATA npdu_data = {0};
apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data);
if (npdu_data.network_layer_message) {
if (apdu_offset <= pdu_len) {
My_Router_Handler(src, &npdu_data, &pdu[apdu_offset],
(uint16_t) (pdu_len - apdu_offset));
(uint16_t)(pdu_len - apdu_offset));
}
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) &&
@@ -205,7 +197,7 @@ static void My_NPDU_Handler(
/* and we are not a router, so ignore messages with
routing information cause they are not for us */
apdu_handler(src, &pdu[apdu_offset],
(uint16_t) (pdu_len - apdu_offset));
(uint16_t)(pdu_len - apdu_offset));
} else {
if (dest.net) {
debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net);
@@ -219,8 +211,7 @@ static void My_NPDU_Handler(
return;
}
static void Init_Service_Handlers(
void)
static void Init_Service_Handlers(void)
{
Device_Init(NULL);
/* 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);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
@@ -248,23 +238,27 @@ static void print_usage(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"
"\n" "address:\n"
"\n"
"address:\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"
" Destination network number 0-65534\n" " ID:\n"
" Port Identifier number 0-255\n" " Info:\n"
"DNET ID Len Info:\n"
"Port-info data:\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"
"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"
"%s 192.168.0.18:47808\n", filename);
"%s 192.168.0.18:47808\n",
filename);
}
static void address_parse(
BACNET_ADDRESS * dst,
int argc,
char *argv[])
static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
{
unsigned mac[6];
unsigned port;
@@ -272,8 +266,7 @@ static void address_parse(
int index = 0;
if (argc > 0) {
count =
sscanf(argv[0], "%u.%u.%u.%u:%u", &mac[0], &mac[1], &mac[2],
count = sscanf(argv[0], "%u.%u.%u.%u:%u", &mac[0], &mac[1], &mac[2],
&mac[3], &port);
if (count == 5) {
dst->mac_len = 6;
@@ -282,9 +275,8 @@ static void address_parse(
}
encode_unsigned16(&dst->mac[4], port);
} else {
count =
sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
&mac[3], &mac[4], &mac[5]);
count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1],
&mac[2], &mac[3], &mac[4], &mac[5]);
dst->mac_len = count;
for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) {
@@ -302,13 +294,9 @@ static void address_parse(
}
}
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
BACNET_ADDRESS src = {
0
}; /* address where message came from */
BACNET_ADDRESS src = {0}; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
time_t total_seconds = 0;
@@ -328,8 +316,10 @@ int main(
}
if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2014 by Steve Karg and others.\n"
"This is free software; see the source for copying conditions.\n"
printf(
"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"
"FITNESS FOR A PARTICULAR PURPOSE.\n");
exit(0);
+139 -177
View File
@@ -54,18 +54,18 @@
#include "iam.h"
#ifdef _WIN32
#define strncasecmp(x,y,z) _strnicmp(x,y,z)
#define strncasecmp(x, y, z) _strnicmp(x, y, z)
#endif
/* define our Data Link Type for libPCAP */
#define DLT_BACNET_MS_TP 165
/* local min/max macros */
#ifndef max
#define max(a,b) (((a) (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a)(b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
#define MSTP_HEADER_MAX (2+1+1+1+2+1)
#define MSTP_HEADER_MAX (2 + 1 + 1 + 1 + 2 + 1)
/* local port data - shared with RS-485 */
static volatile struct mstp_port_struct_t MSTP_Port;
@@ -133,27 +133,22 @@ struct mstp_statistics {
static struct mstp_statistics MSTP_Statistics[MAX_MSTP_DEVICES];
static uint32_t Invalid_Frame_Count;
static uint32_t timeval_diff_ms(
struct timeval *old,
struct timeval *now)
static uint32_t timeval_diff_ms(struct timeval *old, struct timeval *now)
{
uint32_t ms = 0;
/* convert to milliseconds */
ms = (now->tv_sec - old->tv_sec) * 1000 + (now->tv_usec -
old->tv_usec) / 1000;
ms = (now->tv_sec - old->tv_sec) * 1000 +
(now->tv_usec - old->tv_usec) / 1000;
return ms;
}
static void mstp_monitor_i_am(
uint8_t mac,
uint8_t * pdu,
uint16_t pdu_len)
static void mstp_monitor_i_am(uint8_t mac, uint8_t *pdu, uint16_t pdu_len)
{
BACNET_ADDRESS src = { 0 };
BACNET_ADDRESS dest = { 0 };
BACNET_NPDU_DATA npdu_data = { 0 };
BACNET_ADDRESS src = {0};
BACNET_ADDRESS dest = {0};
BACNET_NPDU_DATA npdu_data = {0};
int apdu_offset = 0;
uint16_t apdu_len = 0;
uint8_t *apdu = NULL;
@@ -176,9 +171,8 @@ static void mstp_monitor_i_am(
service_choice = apdu[1];
service_request = &apdu[2];
if (service_choice == SERVICE_UNCONFIRMED_I_AM) {
len =
iam_decode_service_request(service_request, &device_id,
NULL, NULL, NULL);
len = iam_decode_service_request(
service_request, &device_id, NULL, NULL, NULL);
if (len != -1) {
MSTP_Statistics[mac].device_id = device_id;
}
@@ -188,11 +182,10 @@ static void mstp_monitor_i_am(
}
}
static void packet_statistics(
struct timeval *tv,
static void packet_statistics(struct timeval *tv,
volatile struct mstp_port_struct_t *mstp_port)
{
static struct timeval old_tv = { 0 };
static struct timeval old_tv = {0};
static uint8_t old_frame = 255;
static uint8_t old_src = 255;
static uint8_t old_dst = 255;
@@ -243,8 +236,7 @@ static void packet_statistics(
break;
case FRAME_TYPE_POLL_FOR_MASTER:
if (MSTP_Statistics[src].last_pfm_tokens) {
npoll =
MSTP_Statistics[src].token_received_count -
npoll = MSTP_Statistics[src].token_received_count -
MSTP_Statistics[src].last_pfm_tokens;
if (npoll > MSTP_Statistics[src].npoll) {
MSTP_Statistics[src].npoll = npoll;
@@ -324,8 +316,7 @@ static void packet_statistics(
old_tv.tv_usec = tv->tv_usec;
}
static void packet_statistics_print(
void)
static void packet_statistics_print(void)
{
unsigned i; /* loop counter */
unsigned node_count = 0;
@@ -333,32 +324,32 @@ static void packet_statistics_print(
fprintf(stdout, "\n");
fprintf(stdout, "==== MS/TP Frame Counts ====\n");
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC",
"Device", "Tokens", "PFM", "RPFM", "DER", "Postpd", "DNER", "TestReq",
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", "Device",
"Tokens", "PFM", "RPFM", "DER", "Postpd", "DNER", "TestReq",
"TestRsp");
fprintf(stdout, "\n");
for (i = 0; i < MAX_MSTP_DEVICES; i++) {
/* check for masters or slaves */
if ((MSTP_Statistics[i].token_count) || (MSTP_Statistics[i].der_reply)
|| (MSTP_Statistics[i].pfm_count)) {
if ((MSTP_Statistics[i].token_count) ||
(MSTP_Statistics[i].der_reply) || (MSTP_Statistics[i].pfm_count)) {
node_count++;
fprintf(stdout, "%-8u", i);
if (MSTP_Statistics[i].device_id <= 4194303) {
fprintf(stdout, "%-8lu",
(long unsigned int) MSTP_Statistics[i].device_id);
(long unsigned int)MSTP_Statistics[i].device_id);
} else {
fprintf(stdout, "%-8s", "-");
}
fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu",
(long unsigned int) MSTP_Statistics[i].token_count,
(long unsigned int) MSTP_Statistics[i].pfm_count,
(long unsigned int) MSTP_Statistics[i].rpfm_count,
(long unsigned int) MSTP_Statistics[i].der_count);
(long unsigned int)MSTP_Statistics[i].token_count,
(long unsigned int)MSTP_Statistics[i].pfm_count,
(long unsigned int)MSTP_Statistics[i].rpfm_count,
(long unsigned int)MSTP_Statistics[i].der_count);
fprintf(stdout, "%-8lu%-8lu%-8lu%-7lu",
(long unsigned int) MSTP_Statistics[i].reply_postponed_count,
(long unsigned int) MSTP_Statistics[i].dner_count,
(long unsigned int) MSTP_Statistics[i].test_request_count,
(long unsigned int) MSTP_Statistics[i].test_response_count);
(long unsigned int)MSTP_Statistics[i].reply_postponed_count,
(long unsigned int)MSTP_Statistics[i].dner_count,
(long unsigned int)MSTP_Statistics[i].test_request_count,
(long unsigned int)MSTP_Statistics[i].test_response_count);
fprintf(stdout, "\n");
}
}
@@ -367,38 +358,37 @@ static void packet_statistics_print(
fprintf(stdout, "\n");
fprintf(stdout, "==== MS/TP Usage and Timing Maximums ====\n");
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC",
"MaxMstr", "Retries", "Npoll", "Self/TT", "Treply", "Tusage", "Trpfm",
"Tder", "Tpostpd");
"MaxMstr", "Retries", "Npoll", "Self/TT", "Treply", "Tusage",
"Trpfm", "Tder", "Tpostpd");
fprintf(stdout, "\n");
for (i = 0; i < MAX_MSTP_DEVICES; i++) {
/* check for masters or slaves */
if ((MSTP_Statistics[i].token_count) || (MSTP_Statistics[i].der_reply)
|| (MSTP_Statistics[i].pfm_count)) {
if ((MSTP_Statistics[i].token_count) ||
(MSTP_Statistics[i].der_reply) || (MSTP_Statistics[i].pfm_count)) {
node_count++;
self_or_ooo_count = MSTP_Statistics[i].self_token_count +
MSTP_Statistics[i].ooo_token_count;
fprintf(stdout, "%-8u", i);
fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu%-8lu",
(long unsigned int) MSTP_Statistics[i].max_master,
(long unsigned int) MSTP_Statistics[i].token_retries,
(long unsigned int) MSTP_Statistics[i].npoll,
(long unsigned int)MSTP_Statistics[i].max_master,
(long unsigned int)MSTP_Statistics[i].token_retries,
(long unsigned int)MSTP_Statistics[i].npoll,
self_or_ooo_count,
(long unsigned int) MSTP_Statistics[i].token_reply);
(long unsigned int)MSTP_Statistics[i].token_reply);
fprintf(stdout, "%-8lu%-8lu%-8lu%-7lu",
(long unsigned int) MSTP_Statistics[i].tusage_timeout,
(long unsigned int) MSTP_Statistics[i].pfm_reply,
(long unsigned int) MSTP_Statistics[i].der_reply,
(long unsigned int) MSTP_Statistics[i].reply_postponed);
(long unsigned int)MSTP_Statistics[i].tusage_timeout,
(long unsigned int)MSTP_Statistics[i].pfm_reply,
(long unsigned int)MSTP_Statistics[i].der_reply,
(long unsigned int)MSTP_Statistics[i].reply_postponed);
fprintf(stdout, "\n");
}
}
fprintf(stdout, "Node Count: %u\n", node_count);
fprintf(stdout, "Invalid Frame Count: %lu\n",
(long unsigned int) Invalid_Frame_Count);
(long unsigned int)Invalid_Frame_Count);
}
static void packet_statistics_clear(
void)
static void packet_statistics_clear(void)
{
unsigned i = 0;
@@ -409,44 +399,39 @@ static void packet_statistics_clear(
Invalid_Frame_Count = 0;
}
static uint32_t Timer_Silence(
void *pArg)
static uint32_t Timer_Silence(void *pArg)
{
return timer_milliseconds(TIMER_SILENCE);
}
static void Timer_Silence_Reset(
void *pArg)
static void Timer_Silence_Reset(void *pArg)
{
timer_reset(TIMER_SILENCE);
}
/* functions used by the MS/TP state machine to put or get data */
uint16_t MSTP_Put_Receive(
volatile struct mstp_port_struct_t *mstp_port)
uint16_t MSTP_Put_Receive(volatile struct mstp_port_struct_t *mstp_port)
{
(void) mstp_port;
(void)mstp_port;
return 0;
}
/* for the MS/TP state machine to use for getting data to send */
/* Return: amount of PDU data */
uint16_t MSTP_Get_Send(
volatile struct mstp_port_struct_t * mstp_port,
uint16_t MSTP_Get_Send(volatile struct mstp_port_struct_t *mstp_port,
unsigned timeout)
{ /* milliseconds to wait for a packet */
(void) mstp_port;
(void) timeout;
(void)mstp_port;
(void)timeout;
return 0;
}
uint16_t MSTP_Get_Reply(
volatile struct mstp_port_struct_t * mstp_port,
uint16_t MSTP_Get_Reply(volatile struct mstp_port_struct_t *mstp_port,
unsigned timeout)
{ /* milliseconds to wait for a packet */
(void) mstp_port;
(void) timeout;
(void)mstp_port;
(void)timeout;
return 0;
}
@@ -454,31 +439,23 @@ static char Capture_Filename[64] = "mstp_20090123091200.cap";
static FILE *pFile = NULL; /* stream pointer */
#if defined(_WIN32)
static HANDLE hPipe = INVALID_HANDLE_VALUE; /* pipe handle */
static void named_pipe_create(
char *pipe_name)
static void named_pipe_create(char *pipe_name)
{
if (!Wireshark_Capture) {
fprintf(stdout, "mstpcap: Creating Named Pipe \"%s\"\n", pipe_name);
}
/* create the pipe */
while (hPipe == INVALID_HANDLE_VALUE)
{
while (hPipe == INVALID_HANDLE_VALUE) {
/* use CreateFile rather than CreateNamedPipe */
hPipe = CreateFile(
pipe_name,
GENERIC_READ |
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
hPipe = CreateFile(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
if (hPipe != INVALID_HANDLE_VALUE) {
break;
}
/* if an error occured at handle creation */
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"
"then the pipe doesn't exist!\n");
Exit_Requested = true;
@@ -488,14 +465,11 @@ static void named_pipe_create(
ConnectNamedPipe(hPipe, NULL);
}
size_t data_write(
const void *ptr,
size_t size,
size_t nitems)
size_t data_write(const void *ptr, size_t size, size_t nitems)
{
DWORD cbWritten = 0;
if (hPipe != INVALID_HANDLE_VALUE) {
(void) WriteFile(hPipe, /* handle to pipe */
(void)WriteFile(hPipe, /* handle to pipe */
ptr, /* buffer to write from */
size * nitems, /* number of bytes to write */
&cbWritten, /* number of bytes written */
@@ -505,15 +479,12 @@ size_t data_write(
return fwrite(ptr, size, nitems, pFile);
}
size_t data_write_header(
const void *ptr,
size_t size,
size_t nitems,
size_t data_write_header(const void *ptr, size_t size, size_t nitems,
bool pipe_enable)
{
DWORD cbWritten = 0;
if (pipe_enable && (hPipe != INVALID_HANDLE_VALUE)) {
(void) WriteFile(hPipe, /* handle to pipe */
(void)WriteFile(hPipe, /* handle to pipe */
ptr, /* buffer to write from */
size * nitems, /* number of bytes to write */
&cbWritten, /* number of bytes written */
@@ -524,8 +495,7 @@ size_t data_write_header(
}
#else
static int FD_Pipe = -1;
static void named_pipe_create(
char *name)
static void named_pipe_create(char *name)
{
int rv = 0;
rv = mkfifo(name, 0666);
@@ -540,10 +510,7 @@ static void named_pipe_create(
}
}
size_t data_write(
const void *ptr,
size_t size,
size_t nitems)
size_t data_write(const void *ptr, size_t size, size_t nitems)
{
ssize_t bytes = 0;
if (FD_Pipe != -1) {
@@ -553,10 +520,7 @@ size_t data_write(
return fwrite(ptr, size, nitems, pFile);
}
size_t data_write_header(
const void *ptr,
size_t size,
size_t nitems,
size_t data_write_header(const void *ptr, size_t size, size_t nitems,
bool pipe_enable)
{
ssize_t bytes = 0;
@@ -568,8 +532,7 @@ size_t data_write_header(
}
#endif
static void filename_create(
char *filename)
static void filename_create(char *filename)
{
time_t my_time;
struct tm *today;
@@ -584,8 +547,7 @@ static void filename_create(
}
/* write packet to file in libpcap format */
static void write_global_header(
const char *filename)
static void write_global_header(const char *filename)
{
static bool pipe_enable = true; /* don't write more than one header */
uint32_t magic_number = 0xa1b2c3d4; /* magic number */
@@ -599,16 +561,16 @@ static void write_global_header(
/* create a new file. */
pFile = fopen(filename, "wb");
if (pFile) {
(void) data_write_header(&magic_number, sizeof(magic_number), 1,
(void)data_write_header(&magic_number, sizeof(magic_number), 1,
pipe_enable);
(void) data_write_header(&version_major, sizeof(version_major), 1,
(void)data_write_header(&version_major, sizeof(version_major), 1,
pipe_enable);
(void) data_write_header(&version_minor, sizeof(version_minor), 1,
(void)data_write_header(&version_minor, sizeof(version_minor), 1,
pipe_enable);
(void) data_write_header(&thiszone, sizeof(thiszone), 1, pipe_enable);
(void) data_write_header(&sigfigs, sizeof(sigfigs), 1, pipe_enable);
(void) data_write_header(&snaplen, sizeof(snaplen), 1, pipe_enable);
(void) data_write_header(&network, sizeof(network), 1, pipe_enable);
(void)data_write_header(&thiszone, sizeof(thiszone), 1, pipe_enable);
(void)data_write_header(&sigfigs, sizeof(sigfigs), 1, pipe_enable);
(void)data_write_header(&snaplen, sizeof(snaplen), 1, pipe_enable);
(void)data_write_header(&network, sizeof(network), 1, pipe_enable);
fflush(pFile);
if (!Wireshark_Capture) {
fprintf(stdout, "mstpcap: saving capture to %s\n", filename);
@@ -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)
{
uint32_t ts_sec = 0; /* timestamp seconds */
@@ -643,27 +603,28 @@ static void write_received_packet(
(mstp_port->ReceivedValidFrameNotForUs)) {
packet_statistics(&tv, mstp_port);
}
(void) data_write(&ts_sec, sizeof(ts_sec), 1);
(void) data_write(&ts_usec, sizeof(ts_usec), 1);
(void)data_write(&ts_sec, sizeof(ts_sec), 1);
(void)data_write(&ts_usec, sizeof(ts_usec), 1);
if (mstp_port->ReceivedInvalidFrame) {
if (mstp_port->Index) {
max_data = min(mstp_port->InputBufferSize, mstp_port->Index);
incl_len = orig_len = header_len + max_data + 2/* checksum*/;
incl_len = orig_len = header_len + max_data + 2 /* checksum*/;
} else {
/* header only */
incl_len = orig_len = header_len;
}
} else {
if (mstp_port->DataLength) {
max_data = min(mstp_port->InputBufferSize, mstp_port->DataLength);
incl_len = orig_len = header_len + max_data + 2/* checksum*/;
max_data =
min(mstp_port->InputBufferSize, mstp_port->DataLength);
incl_len = orig_len = header_len + max_data + 2 /* checksum*/;
} else {
/* header only - or at least some bytes of the header */
incl_len = orig_len = header_len;
}
}
(void) data_write(&incl_len, sizeof(incl_len), 1);
(void) data_write(&orig_len, sizeof(orig_len), 1);
(void)data_write(&incl_len, sizeof(incl_len), 1);
(void)data_write(&orig_len, sizeof(orig_len), 1);
if (header_len == 1) {
header[0] = mstp_port->DataRegister;
} else if (header_len == 2) {
@@ -679,11 +640,11 @@ static void write_received_packet(
header[6] = LO_BYTE(mstp_port->DataLength);
header[7] = mstp_port->HeaderCRCActual;
}
(void) data_write(header, header_len, 1);
(void)data_write(header, header_len, 1);
if (max_data) {
(void) data_write(mstp_port->InputBuffer, max_data, 1);
(void) data_write((char *) &mstp_port->DataCRCActualMSB, 1, 1);
(void) data_write((char *) &mstp_port->DataCRCActualLSB, 1, 1);
(void)data_write(mstp_port->InputBuffer, max_data, 1);
(void)data_write((char *)&mstp_port->DataCRCActualMSB, 1, 1);
(void)data_write((char *)&mstp_port->DataCRCActualLSB, 1, 1);
}
} else {
fprintf(stderr, "mstpcap[packet]: failed to open %s: %s\n",
@@ -692,8 +653,7 @@ static void write_received_packet(
}
/* read header from file in libpcap format */
static bool test_global_header(
const char *filename)
static bool test_global_header(const char *filename)
{
uint32_t magic_number = 0; /* magic number */
uint16_t version_major = 0; /* major version number */
@@ -765,14 +725,13 @@ static bool test_global_header(
return true;
}
static bool read_received_packet(
volatile struct mstp_port_struct_t *mstp_port)
static bool read_received_packet(volatile struct mstp_port_struct_t *mstp_port)
{
uint32_t ts_sec = 0; /* timestamp seconds */
uint32_t ts_usec = 0; /* timestamp microseconds */
uint32_t incl_len = 0; /* number of octets of packet saved in file */
uint32_t orig_len = 0; /* actual length of packet */
uint8_t header[8] = { 0 }; /* MS/TP header */
uint8_t header[8] = {0}; /* MS/TP header */
struct timeval tv;
size_t count = 0;
unsigned i = 0;
@@ -841,13 +800,13 @@ static bool read_received_packet(
pFile = NULL;
return false;
}
count = fread((char *) &mstp_port->DataCRCActualMSB, 1, 1, pFile);
count = fread((char *)&mstp_port->DataCRCActualMSB, 1, 1, pFile);
if (count != 1) {
fclose(pFile);
pFile = NULL;
return false;
}
count = fread((char *) &mstp_port->DataCRCActualLSB, 1, 1, pFile);
count = fread((char *)&mstp_port->DataCRCActualLSB, 1, 1, pFile);
if (count != 1) {
fclose(pFile);
pFile = NULL;
@@ -855,8 +814,7 @@ static bool read_received_packet(
}
mstp_port->DataCRC = 0xFFFF;
for (i = 0; i < mstp_port->DataLength; i++) {
mstp_port->DataCRC =
CRC_Calc_Data(mstp_port->InputBuffer[i],
mstp_port->DataCRC = CRC_Calc_Data(mstp_port->InputBuffer[i],
mstp_port->DataCRC);
}
mstp_port->DataCRC =
@@ -888,8 +846,7 @@ static bool read_received_packet(
return true;
}
static void cleanup(
void)
static void cleanup(void)
{
if (!Wireshark_Capture) {
packet_statistics_print();
@@ -902,8 +859,7 @@ static void cleanup(
}
#if defined(_WIN32)
static BOOL WINAPI CtrlCHandler(
DWORD dwCtrlType)
static BOOL WINAPI CtrlCHandler(DWORD dwCtrlType)
{
dwCtrlType = dwCtrlType;
@@ -923,10 +879,9 @@ static BOOL WINAPI CtrlCHandler(
return TRUE;
}
#else
static void sig_int(
int signo)
static void sig_int(int signo)
{
(void) signo;
(void)signo;
if (FD_Pipe != -1) {
close(FD_Pipe);
}
@@ -934,8 +889,7 @@ static void sig_int(
exit(0);
}
void signal_init(
void)
void signal_init(void)
{
signal(SIGINT, sig_int);
signal(SIGHUP, sig_int);
@@ -943,8 +897,7 @@ void signal_init(
}
#endif
void filename_create_new(
void)
void filename_create_new(void)
{
if (pFile) {
fclose(pFile);
@@ -954,8 +907,7 @@ void filename_create_new(
write_global_header(&Capture_Filename[0]);
}
static void print_usage(
char *filename)
static void print_usage(char *filename)
{
printf("Usage: %s", filename);
printf(" [--scan <filename>]\n");
@@ -965,15 +917,19 @@ static void print_usage(
printf(" [--version][--help]\n");
}
static void print_help(char *filename) {
printf("%s --scan <filename>\n"
static void print_help(char *filename)
{
printf(
"%s --scan <filename>\n"
"perform statistic analysis on MS/TP capture file.\n",
filename);
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"
"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"
"[--extcap-interface port] - serial interface.\n"
#if defined(_WIN32)
@@ -992,7 +948,8 @@ static void print_help(char *filename) {
#endif
" Use that name as the interface name in Wireshark.\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"
"[--extcap-interface iface]\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 */
static void mstp_structure_init(
volatile struct mstp_port_struct_t *mstp_port)
static void mstp_structure_init(volatile struct mstp_port_struct_t *mstp_port)
{
if (mstp_port) {
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 */
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
volatile struct mstp_port_struct_t *mstp_port;
long my_baud = 38400;
@@ -1053,8 +1007,10 @@ int main(
}
if (strcmp(argv[argi], "--version") == 0) {
printf("mstpcap %s\n", BACNET_VERSION_TEXT);
printf("Copyright (C) 2011-2016 by Steve Karg\n"
"This is free software; see the source for copying conditions.\n"
printf(
"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"
"FITNESS FOR A PARTICULAR PURPOSE.\n");
return 0;
@@ -1070,8 +1026,7 @@ int main(
if (test_global_header(argv[argi])) {
while (read_received_packet(mstp_port)) {
packet_count++;
fprintf(stderr, "\r%u packets",
(unsigned) packet_count);
fprintf(stderr, "\r%u packets", (unsigned)packet_count);
}
if (packet_count) {
packet_statistics_print();
@@ -1092,21 +1047,27 @@ int main(
printf("An interface must be provided.\n");
return 0;
}
printf("dlt {number=%u}{name=BACnet MS/TP}"
printf(
"dlt {number=%u}{name=BACnet MS/TP}"
"{display=BACnet MS/TP}\n",
DLT_BACNET_MS_TP);
Exit_Requested = true;
}
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}"
"{type=selector}\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=57600}{display=57600}{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");
printf(
"value {arg=0}{value=57600}{display=57600}{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;
}
if (strcmp(argv[argi], "--capture") == 0) {
@@ -1116,7 +1077,8 @@ int main(
if (strcmp(argv[argi], "--extcap-interface") == 0) {
argi++;
if (argi >= argc) {
printf("An interface must be provided or "
printf(
"An interface must be provided or "
"the selection must be displayed.\n");
return 0;
}
@@ -1126,7 +1088,7 @@ int main(
if (strncasecmp(argv[argi], "com", 3) == 0) {
/* legacy command line options */
RS485_Set_Interface(argv[argi]);
if ((argi+1) < argc) {
if ((argi + 1) < argc) {
argi++;
my_baud = strtol(argv[argi], NULL, 0);
RS485_Set_Baud_Rate(my_baud);
@@ -1136,7 +1098,7 @@ int main(
if (strncasecmp(argv[argi], "/dev/", 5) == 0) {
/* legacy command line options */
RS485_Set_Interface(argv[argi]);
if ((argi+1) < argc) {
if ((argi + 1) < argc) {
argi++;
my_baud = strtol(argv[argi], NULL, 0);
RS485_Set_Baud_Rate(my_baud);
@@ -1173,11 +1135,11 @@ int main(
timer_init();
if (!Wireshark_Capture) {
fprintf(stdout, "mstpcap: Using %s for capture at %ld bps.\n",
RS485_Interface(), (long) RS485_Get_Baud_Rate());
RS485_Interface(), (long)RS485_Get_Baud_Rate());
}
#if defined(_WIN32)
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT);
SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlCHandler, TRUE);
SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlCHandler, TRUE);
#else
signal_init();
#endif
@@ -1228,8 +1190,8 @@ int main(
}
if (!Wireshark_Capture) {
if (!(packet_count % 100)) {
fprintf(stdout, "\r%hu packets, %hu invalid frames", packet_count,
Invalid_Frame_Count);
fprintf(stdout, "\r%hu packets, %hu invalid frames",
packet_count, Invalid_Frame_Count);
}
if (packet_count >= 65535) {
packet_statistics_print();
+46 -54
View File
@@ -50,8 +50,8 @@
#include "version.h"
#ifndef max
#define max(a,b) (((a) (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a)(b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
/* buffer needed by CRC functions */
@@ -68,14 +68,13 @@ static FILE *pFile = NULL; /* stream pointer */
static FILE *pText_File = NULL; /* stream pointer */
/******************************************************************
* DESCRIPTION: Takes one of the arguments passed by the main function
* and converts it into a buffer value.
* argi - single argument in string form.
* RETURN: nothing
* NOTES: none
******************************************************************/
static void Parse_Number(
char *argi)
* DESCRIPTION: Takes one of the arguments passed by the main function
* and converts it into a buffer value.
* argi - single argument in string form.
* RETURN: nothing
* NOTES: none
******************************************************************/
static void Parse_Number(char *argi)
{
long long_value = 0;
@@ -84,21 +83,19 @@ static void Parse_Number(
} else {
long_value = strtol(argi, NULL, 16);
}
CRC_Buffer[CRC_Buffer_Len] = (uint8_t) long_value;
CRC_Buffer[CRC_Buffer_Len] = (uint8_t)long_value;
CRC_Buffer_Len++;
}
/******************************************************************
* DESCRIPTION: Takes one of the arguments passed by the main function
* and sets flags if it matches one of the predefined args.
* PARAMETERS: argc (IN) number of arguments.
* argv (IN) an array of arguments in string form.
* RETURN: number of arguments parsed
* NOTES: none
******************************************************************/
static void Parse_Arguments(
int argc,
char *argv[])
* DESCRIPTION: Takes one of the arguments passed by the main function
* and sets flags if it matches one of the predefined args.
* PARAMETERS: argc (IN) number of arguments.
* argv (IN) an array of arguments in string form.
* RETURN: number of arguments parsed
* NOTES: none
******************************************************************/
static void Parse_Arguments(int argc, char *argv[])
{
int i = 0;
long long_value = 0;
@@ -156,8 +153,7 @@ static void Parse_Arguments(
}
}
static void filename_create(
char *filename)
static void filename_create(char *filename)
{
time_t my_time;
struct tm *today;
@@ -172,8 +168,7 @@ static void filename_create(
}
/* write packet to file in libpcap format */
static void write_global_header(
const char *filename)
static void write_global_header(const char *filename)
{
uint32_t magic_number = 0xa1b2c3d4; /* magic number */
uint16_t version_major = 2; /* major version number */
@@ -186,13 +181,13 @@ static void write_global_header(
/* create a new file. */
pFile = fopen(filename, "wb");
if (pFile) {
(void) fwrite(&magic_number, sizeof(magic_number), 1, pFile);
(void) fwrite(&version_major, sizeof(version_major), 1, pFile);
(void) fwrite(&version_minor, sizeof(version_minor), 1, pFile);
(void) fwrite(&thiszone, sizeof(thiszone), 1, pFile);
(void) fwrite(&sigfigs, sizeof(sigfigs), 1, pFile);
(void) fwrite(&snaplen, sizeof(snaplen), 1, pFile);
(void) fwrite(&network, sizeof(network), 1, pFile);
(void)fwrite(&magic_number, sizeof(magic_number), 1, pFile);
(void)fwrite(&version_major, sizeof(version_major), 1, pFile);
(void)fwrite(&version_minor, sizeof(version_minor), 1, pFile);
(void)fwrite(&thiszone, sizeof(thiszone), 1, pFile);
(void)fwrite(&sigfigs, sizeof(sigfigs), 1, pFile);
(void)fwrite(&snaplen, sizeof(snaplen), 1, pFile);
(void)fwrite(&network, sizeof(network), 1, pFile);
fflush(pFile);
fprintf(stdout, "mstpcap: saving capture to %s\n", filename);
} else {
@@ -201,9 +196,7 @@ static void write_global_header(
}
}
static void write_received_packet(
uint8_t * buffer,
unsigned length)
static void write_received_packet(uint8_t *buffer, unsigned length)
{
uint32_t ts_sec; /* timestamp seconds */
uint32_t ts_usec; /* timestamp microseconds */
@@ -215,21 +208,19 @@ static void write_received_packet(
gettimeofday(&tv, NULL);
ts_sec = tv.tv_sec;
ts_usec = tv.tv_usec;
(void) fwrite(&ts_sec, sizeof(ts_sec), 1, pFile);
(void) fwrite(&ts_usec, sizeof(ts_usec), 1, pFile);
(void)fwrite(&ts_sec, sizeof(ts_sec), 1, pFile);
(void)fwrite(&ts_usec, sizeof(ts_usec), 1, pFile);
orig_len = incl_len = length;
(void) fwrite(&incl_len, sizeof(incl_len), 1, pFile);
(void) fwrite(&orig_len, sizeof(orig_len), 1, pFile);
(void) fwrite(buffer, length, 1, pFile);
(void)fwrite(&incl_len, sizeof(incl_len), 1, pFile);
(void)fwrite(&orig_len, sizeof(orig_len), 1, pFile);
(void)fwrite(buffer, length, 1, pFile);
} else {
fprintf(stderr, "mstpcrc[packet]: failed to open %s: %s\n",
Capture_Filename, strerror(errno));
}
}
static void Write_Pcap(
uint8_t * buffer,
unsigned length)
static void Write_Pcap(uint8_t *buffer, unsigned length)
{
filename_create(&Capture_Filename[0]);
write_global_header(&Capture_Filename[0]);
@@ -239,7 +230,7 @@ static void Write_Pcap(
}
}
/* hold 3 ASCII characters per byte of data */
static char Text_Buffer[1024*3];
static char Text_Buffer[1024 * 3];
static void Process_Text_File(void)
{
char *argi = NULL;
@@ -269,9 +260,7 @@ static void Process_Text_File(void)
}
/* simple program to CRC the data and print the CRC */
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
/* accumulates the crc value */
uint8_t crc8 = 0xff;
@@ -280,8 +269,10 @@ int main(
/* initialize our interface */
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("mstpcrc [options] <05 03 01 0D...>\r\n"
"perform MS/TP CRC on data bytes.\r\n" "options:\r\n"
printf(
"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"
"[-d] interprete the argument as ascii decimal\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)) {
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"
"There is NO warranty; not even for MERCHANTABILITY or\r\n"
"FITNESS FOR A PARTICULAR PURPOSE.\r\n");
@@ -314,7 +306,7 @@ int main(
crc16 = CRC_Calc_Data(CRC_Buffer[i], crc16);
}
if (ASCII_Decimal) {
printf("%u\r\n", (unsigned) CRC_Buffer[i]);
printf("%u\r\n", (unsigned)CRC_Buffer[i]);
} else {
printf("0x%02X\r\n", CRC_Buffer[i]);
}
@@ -322,15 +314,15 @@ int main(
if (CRC_Size == 8) {
crc8 = ~crc8;
if (ASCII_Decimal) {
printf("%u Header CRC\r\n", (unsigned) crc8);
printf("%u Header CRC\r\n", (unsigned)crc8);
} else {
printf("0x%02X Header CRC\r\n", crc8);
}
} else if (CRC_Size == 16) {
crc16 = ~crc16;
if (ASCII_Decimal) {
printf("%u Data CRC\r\n", (unsigned) (crc16 & 0xFF));
printf("%u Data CRC\r\n", (unsigned) (crc16 >> 8));
printf("%u Data CRC\r\n", (unsigned)(crc16 & 0xFF));
printf("%u Data CRC\r\n", (unsigned)(crc16 >> 8));
} else {
printf("0x%02X Data CRC\r\n", (crc16 & 0xFF));
printf("0x%02X Data CRC\r\n", (crc16 >> 8));
+89 -122
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the credential to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the credential to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Access Credential Objects - customize for your use */
@@ -43,8 +43,7 @@ static bool Access_Credential_Initialized = false;
static ACCESS_CREDENTIAL_DESCR ac_descr[MAX_ACCESS_CREDENTIALS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
static const int Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_GLOBAL_IDENTIFIER,
@@ -57,19 +56,13 @@ static const int Properties_Required[] = {
PROP_EXPIRATION_TIME,
PROP_CREDENTIAL_DISABLE,
PROP_ASSIGNED_ACCESS_RIGHTS,
-1
};
-1};
static const int Properties_Optional[] = {
-1
};
static const int Properties_Optional[] = {-1};
static const int Properties_Proprietary[] = {
-1
};
static const int Properties_Proprietary[] = {-1};
void Access_Credential_Property_Lists(
const int **pRequired,
void Access_Credential_Property_Lists(const int **pRequired,
const int **pOptional,
const int **pProprietary)
{
@@ -83,8 +76,7 @@ void Access_Credential_Property_Lists(
return;
}
void Access_Credential_Init(
void)
void Access_Credential_Init(void)
{
unsigned i;
@@ -92,7 +84,8 @@ void Access_Credential_Init(
Access_Credential_Initialized = true;
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].credential_status = false;
ac_descr[i].reasons_count = 0;
@@ -110,8 +103,7 @@ void Access_Credential_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Access_Credential_Valid_Instance(
uint32_t object_instance)
bool Access_Credential_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ACCESS_CREDENTIALS)
return true;
@@ -121,8 +113,7 @@ bool Access_Credential_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Access_Credential_Count(
void)
unsigned Access_Credential_Count(void)
{
return MAX_ACCESS_CREDENTIALS;
}
@@ -130,8 +121,7 @@ unsigned Access_Credential_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Access_Credential_Index_To_Instance(
unsigned index)
uint32_t Access_Credential_Index_To_Instance(unsigned index)
{
return index;
}
@@ -139,8 +129,7 @@ uint32_t Access_Credential_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Access_Credential_Instance_To_Index(
uint32_t object_instance)
unsigned Access_Credential_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_ACCESS_CREDENTIALS;
@@ -151,16 +140,15 @@ unsigned Access_Credential_Instance_To_Index(
}
/* note: the object name must be unique within this device */
bool Access_Credential_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Access_Credential_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
if (object_instance < MAX_ACCESS_CREDENTIALS) {
sprintf(text_string, "ACCESS CREDENTIAL %lu",
(unsigned long) object_instance);
(unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
@@ -168,8 +156,7 @@ bool Access_Credential_Object_Name(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Access_Credential_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Access_Credential_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
int apdu_len = 0; /* return value */
@@ -184,13 +171,11 @@ int Access_Credential_Read_Property(
return 0;
}
apdu = rpdata->application_data;
object_index =
Access_Credential_Instance_To_Index(rpdata->object_instance);
object_index = Access_Credential_Instance_To_Index(rpdata->object_instance);
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0],
OBJECT_ACCESS_CREDENTIAL, rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_ACCESS_CREDENTIAL, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
Access_Credential_Object_Name(rpdata->object_instance,
@@ -199,14 +184,12 @@ int Access_Credential_Read_Property(
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0],
apdu_len = encode_application_enumerated(&apdu[0],
OBJECT_ACCESS_CREDENTIAL);
break;
case PROP_GLOBAL_IDENTIFIER:
apdu_len =
encode_application_unsigned(&apdu[0],
ac_descr[object_index].global_identifier);
apdu_len = encode_application_unsigned(
&apdu[0], ac_descr[object_index].global_identifier);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
@@ -217,20 +200,17 @@ int Access_Credential_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_RELIABILITY:
apdu_len =
encode_application_enumerated(&apdu[0],
ac_descr[object_index].reliability);
apdu_len = encode_application_enumerated(
&apdu[0], ac_descr[object_index].reliability);
break;
case PROP_CREDENTIAL_STATUS:
apdu_len =
encode_application_enumerated(&apdu[0],
ac_descr[object_index].credential_status);
apdu_len = encode_application_enumerated(
&apdu[0], ac_descr[object_index].credential_status);
break;
case PROP_REASON_FOR_DISABLE:
for (i = 0; i < ac_descr[object_index].reasons_count; i++) {
len =
encode_application_enumerated(&apdu[0],
ac_descr[object_index].reason_for_disable[i]);
len = encode_application_enumerated(
&apdu[0], ac_descr[object_index].reason_for_disable[i]);
if (apdu_len + len < MAX_APDU)
apdu_len += len;
else {
@@ -243,14 +223,13 @@ int Access_Credential_Read_Property(
break;
case PROP_AUTHENTICATION_FACTORS:
if (rpdata->array_index == 0) {
apdu_len =
encode_application_unsigned(&apdu[0],
ac_descr[object_index].auth_factors_count);
apdu_len = encode_application_unsigned(
&apdu[0], ac_descr[object_index].auth_factors_count);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; i < ac_descr[object_index].auth_factors_count; i++) {
len =
bacapp_encode_credential_authentication_factor(&apdu
[0], &ac_descr[object_index].auth_factors[i]);
for (i = 0; i < ac_descr[object_index].auth_factors_count;
i++) {
len = bacapp_encode_credential_authentication_factor(
&apdu[0], &ac_descr[object_index].auth_factors[i]);
if (apdu_len + len < MAX_APDU)
apdu_len += len;
else {
@@ -263,11 +242,9 @@ int Access_Credential_Read_Property(
} else {
if (rpdata->array_index <=
ac_descr[object_index].auth_factors_count) {
apdu_len =
bacapp_encode_credential_authentication_factor(&apdu
[0],
&ac_descr[object_index].
auth_factors[rpdata->array_index - 1]);
apdu_len = bacapp_encode_credential_authentication_factor(
&apdu[0], &ac_descr[object_index]
.auth_factors[rpdata->array_index - 1]);
} else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -276,31 +253,28 @@ int Access_Credential_Read_Property(
}
break;
case PROP_ACTIVATION_TIME:
apdu_len =
bacapp_encode_datetime(&apdu[0],
&ac_descr[object_index].activation_time);
apdu_len = bacapp_encode_datetime(
&apdu[0], &ac_descr[object_index].activation_time);
break;
case PROP_EXPIRATION_TIME:
apdu_len =
bacapp_encode_datetime(&apdu[0],
&ac_descr[object_index].expiration_time);
apdu_len = bacapp_encode_datetime(
&apdu[0], &ac_descr[object_index].expiration_time);
break;
case PROP_CREDENTIAL_DISABLE:
apdu_len =
encode_application_enumerated(&apdu[0],
ac_descr[object_index].credential_disable);
apdu_len = encode_application_enumerated(
&apdu[0], ac_descr[object_index].credential_disable);
break;
case PROP_ASSIGNED_ACCESS_RIGHTS:
if (rpdata->array_index == 0) {
apdu_len =
encode_application_unsigned(&apdu[0],
apdu_len = encode_application_unsigned(
&apdu[0],
ac_descr[object_index].assigned_access_rights_count);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0;
i < ac_descr[object_index].assigned_access_rights_count;
i++) {
len =
bacapp_encode_assigned_access_rights(&apdu[0],
len = bacapp_encode_assigned_access_rights(
&apdu[0],
&ac_descr[object_index].assigned_access_rights[i]);
if (apdu_len + len < MAX_APDU)
apdu_len += len;
@@ -314,10 +288,10 @@ int Access_Credential_Read_Property(
} else {
if (rpdata->array_index <=
ac_descr[object_index].assigned_access_rights_count) {
apdu_len =
bacapp_encode_assigned_access_rights(&apdu[0],
&ac_descr[object_index].
assigned_access_rights[rpdata->array_index - 1]);
apdu_len = bacapp_encode_assigned_access_rights(
&apdu[0],
&ac_descr[object_index]
.assigned_access_rights[rpdata->array_index - 1]);
} else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -333,9 +307,9 @@ int Access_Credential_Read_Property(
}
/* only array properties can have array options */
if ((apdu_len >= 0) &&
(rpdata->object_property != PROP_AUTHENTICATION_FACTORS)
&& (rpdata->object_property != PROP_ASSIGNED_ACCESS_RIGHTS)
&& (rpdata->array_index != BACNET_ARRAY_ALL)) {
(rpdata->object_property != PROP_AUTHENTICATION_FACTORS) &&
(rpdata->object_property != PROP_ASSIGNED_ACCESS_RIGHTS) &&
(rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR;
@@ -345,8 +319,7 @@ int Access_Credential_Read_Property(
}
/* returns true if successful */
bool Access_Credential_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Access_Credential_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
@@ -354,8 +327,7 @@ bool Access_Credential_Write_Property(
unsigned object_index = 0;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -365,9 +337,9 @@ bool Access_Credential_Write_Property(
return false;
}
/* only array properties can have array options */
if ((wp_data->object_property != PROP_AUTHENTICATION_FACTORS)
&& (wp_data->object_property != PROP_ASSIGNED_ACCESS_RIGHTS)
&& (wp_data->array_index != BACNET_ARRAY_ALL)) {
if ((wp_data->object_property != PROP_AUTHENTICATION_FACTORS) &&
(wp_data->object_property != PROP_ASSIGNED_ACCESS_RIGHTS) &&
(wp_data->array_index != BACNET_ARRAY_ALL)) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
return false;
@@ -408,17 +380,14 @@ bool Access_Credential_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -428,10 +397,9 @@ bool WPValidateArgType(
return false;
}
void testAccessCredential(
Test * pTest)
void testAccessCredential(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -458,8 +426,7 @@ void testAccessCredential(
}
#ifdef TEST_ACCESS_CREDENTIAL
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -471,7 +438,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+105 -156
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Access Door Objects - customize for your use */
@@ -42,8 +42,7 @@ static bool Access_Door_Initialized = false;
static ACCESS_DOOR_DESCR ad_descr[MAX_ACCESS_DOORS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
static const int Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
@@ -56,25 +55,16 @@ static const int Properties_Required[] = {
PROP_DOOR_PULSE_TIME,
PROP_DOOR_EXTENDED_PULSE_TIME,
PROP_DOOR_OPEN_TOO_LONG_TIME,
-1
};
-1};
static const int Properties_Optional[] = {
PROP_DOOR_STATUS,
PROP_LOCK_STATUS,
PROP_SECURED_STATUS,
PROP_DOOR_UNLOCK_DELAY_TIME,
PROP_DOOR_ALARM_STATE,
-1
};
PROP_DOOR_STATUS, PROP_LOCK_STATUS,
PROP_SECURED_STATUS, PROP_DOOR_UNLOCK_DELAY_TIME,
PROP_DOOR_ALARM_STATE, -1};
static const int Properties_Proprietary[] = {
-1
};
static const int Properties_Proprietary[] = {-1};
void Access_Door_Property_Lists(
const int **pRequired,
const int **pOptional,
void Access_Door_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -87,8 +77,7 @@ void Access_Door_Property_Lists(
return;
}
void Access_Door_Init(
void)
void Access_Door_Init(void)
{
unsigned i, j;
@@ -123,8 +112,7 @@ void Access_Door_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Access_Door_Valid_Instance(
uint32_t object_instance)
bool Access_Door_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ACCESS_DOORS)
return true;
@@ -134,8 +122,7 @@ bool Access_Door_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Access_Door_Count(
void)
unsigned Access_Door_Count(void)
{
return MAX_ACCESS_DOORS;
}
@@ -143,8 +130,7 @@ unsigned Access_Door_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Access_Door_Index_To_Instance(
unsigned index)
uint32_t Access_Door_Index_To_Instance(unsigned index)
{
return index;
}
@@ -152,8 +138,7 @@ uint32_t Access_Door_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Access_Door_Instance_To_Index(
uint32_t object_instance)
unsigned Access_Door_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_ACCESS_DOORS;
@@ -163,8 +148,7 @@ unsigned Access_Door_Instance_To_Index(
return index;
}
BACNET_DOOR_VALUE Access_Door_Present_Value(
uint32_t object_instance)
BACNET_DOOR_VALUE Access_Door_Present_Value(uint32_t object_instance)
{
unsigned index = 0;
unsigned i = 0;
@@ -183,8 +167,7 @@ BACNET_DOOR_VALUE Access_Door_Present_Value(
return value;
}
unsigned Access_Door_Present_Value_Priority(
uint32_t object_instance)
unsigned Access_Door_Present_Value_Priority(uint32_t object_instance)
{
unsigned index = 0; /* instance to index conversion */
unsigned i = 0; /* loop counter */
@@ -203,10 +186,8 @@ unsigned Access_Door_Present_Value_Priority(
return priority;
}
bool Access_Door_Present_Value_Set(
uint32_t object_instance,
BACNET_DOOR_VALUE value,
unsigned priority)
bool Access_Door_Present_Value_Set(uint32_t object_instance,
BACNET_DOOR_VALUE value, unsigned priority)
{
unsigned index = 0;
bool status = false;
@@ -214,8 +195,7 @@ bool Access_Door_Present_Value_Set(
index = Access_Door_Instance_To_Index(object_instance);
if (index < MAX_ACCESS_DOORS) {
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value >= DOOR_VALUE_LOCK) &&
(priority != 6 /* reserved */) && (value >= DOOR_VALUE_LOCK) &&
(value <= DOOR_VALUE_EXTENDED_PULSE_UNLOCK)) {
ad_descr[index].value_active[priority - 1] = true;
ad_descr[index].priority_array[priority - 1] = value;
@@ -232,8 +212,7 @@ bool Access_Door_Present_Value_Set(
return status;
}
bool Access_Door_Present_Value_Relinquish(
uint32_t object_instance,
bool Access_Door_Present_Value_Relinquish(uint32_t object_instance,
unsigned priority)
{
unsigned index = 0;
@@ -242,7 +221,7 @@ bool Access_Door_Present_Value_Relinquish(
index = Access_Door_Instance_To_Index(object_instance);
if (index < MAX_ACCESS_DOORS) {
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ )) {
(priority != 6 /* reserved */)) {
ad_descr[index].value_active[priority - 1] = false;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
@@ -257,8 +236,7 @@ bool Access_Door_Present_Value_Relinquish(
return status;
}
BACNET_DOOR_VALUE Access_Door_Relinquish_Default(
uint32_t object_instance)
BACNET_DOOR_VALUE Access_Door_Relinquish_Default(uint32_t object_instance)
{
BACNET_DOOR_VALUE status = -1;
unsigned index = 0;
@@ -271,24 +249,21 @@ BACNET_DOOR_VALUE Access_Door_Relinquish_Default(
}
/* note: the object name must be unique within this device */
bool Access_Door_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Access_Door_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
if (object_instance < MAX_ACCESS_DOORS) {
sprintf(text_string, "ACCESS DOOR %lu",
(unsigned long) object_instance);
sprintf(text_string, "ACCESS DOOR %lu", (unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
return status;
}
bool Access_Door_Out_Of_Service(
uint32_t instance)
bool Access_Door_Out_Of_Service(uint32_t instance)
{
unsigned index = 0;
bool oos_flag = false;
@@ -301,9 +276,7 @@ bool Access_Door_Out_Of_Service(
return oos_flag;
}
void Access_Door_Out_Of_Service_Set(
uint32_t instance,
bool oos_flag)
void Access_Door_Out_Of_Service_Set(uint32_t instance, bool oos_flag)
{
unsigned index = 0;
@@ -314,8 +287,7 @@ void Access_Door_Out_Of_Service_Set(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Access_Door_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Access_Door_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
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);
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ACCESS_DOOR,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_ACCESS_DOOR, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
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);
break;
case PROP_PRESENT_VALUE:
apdu_len =
encode_application_enumerated(&apdu[0],
Access_Door_Present_Value(rpdata->object_instance));
apdu_len = encode_application_enumerated(
&apdu[0], Access_Door_Present_Value(rpdata->object_instance));
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
@@ -362,14 +332,12 @@ int Access_Door_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len =
encode_application_enumerated(&apdu[0],
ad_descr[object_index].event_state);
apdu_len = encode_application_enumerated(
&apdu[0], ad_descr[object_index].event_state);
break;
case PROP_RELIABILITY:
apdu_len =
encode_application_enumerated(&apdu[0],
ad_descr[object_index].reliability);
apdu_len = encode_application_enumerated(
&apdu[0], ad_descr[object_index].reliability);
break;
case PROP_OUT_OF_SERVICE:
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])
len = encode_application_null(&apdu[apdu_len]);
else
len =
encode_application_enumerated(&apdu[apdu_len],
len = encode_application_enumerated(
&apdu[apdu_len],
ad_descr[object_index].priority_array[i]);
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
@@ -406,8 +374,8 @@ int Access_Door_Read_Property(
if (ad_descr[object_index].value_active[i])
apdu_len = encode_application_null(&apdu[0]);
else {
apdu_len =
encode_application_enumerated(&apdu[apdu_len],
apdu_len = encode_application_enumerated(
&apdu[apdu_len],
ad_descr[object_index].priority_array[i]);
}
} else {
@@ -418,49 +386,41 @@ int Access_Door_Read_Property(
}
break;
case PROP_RELINQUISH_DEFAULT:
apdu_len =
encode_application_enumerated(&apdu[0],
apdu_len = encode_application_enumerated(
&apdu[0],
Access_Door_Relinquish_Default(rpdata->object_instance));
break;
case PROP_DOOR_STATUS:
apdu_len =
encode_application_enumerated(&apdu[0],
ad_descr[object_index].door_status);
apdu_len = encode_application_enumerated(
&apdu[0], ad_descr[object_index].door_status);
break;
case PROP_LOCK_STATUS:
apdu_len =
encode_application_enumerated(&apdu[0],
ad_descr[object_index].lock_status);
apdu_len = encode_application_enumerated(
&apdu[0], ad_descr[object_index].lock_status);
break;
case PROP_SECURED_STATUS:
apdu_len =
encode_application_enumerated(&apdu[0],
ad_descr[object_index].secured_status);
apdu_len = encode_application_enumerated(
&apdu[0], ad_descr[object_index].secured_status);
break;
case PROP_DOOR_PULSE_TIME:
apdu_len =
encode_application_unsigned(&apdu[0],
ad_descr[object_index].door_pulse_time);
apdu_len = encode_application_unsigned(
&apdu[0], ad_descr[object_index].door_pulse_time);
break;
case PROP_DOOR_EXTENDED_PULSE_TIME:
apdu_len =
encode_application_unsigned(&apdu[0],
ad_descr[object_index].door_extended_pulse_time);
apdu_len = encode_application_unsigned(
&apdu[0], ad_descr[object_index].door_extended_pulse_time);
break;
case PROP_DOOR_UNLOCK_DELAY_TIME:
apdu_len =
encode_application_unsigned(&apdu[0],
ad_descr[object_index].door_unlock_delay_time);
apdu_len = encode_application_unsigned(
&apdu[0], ad_descr[object_index].door_unlock_delay_time);
break;
case PROP_DOOR_OPEN_TOO_LONG_TIME:
apdu_len =
encode_application_unsigned(&apdu[0],
ad_descr[object_index].door_open_too_long_time);
apdu_len = encode_application_unsigned(
&apdu[0], ad_descr[object_index].door_open_too_long_time);
break;
case PROP_DOOR_ALARM_STATE:
apdu_len =
encode_application_enumerated(&apdu[0],
ad_descr[object_index].door_alarm_state);
apdu_len = encode_application_enumerated(
&apdu[0], ad_descr[object_index].door_alarm_state);
break;
default:
rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -480,8 +440,7 @@ int Access_Door_Read_Property(
}
/* returns true if successful */
bool Access_Door_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Access_Door_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
@@ -489,8 +448,7 @@ bool Access_Door_Write_Property(
unsigned object_index = 0;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -513,9 +471,9 @@ bool Access_Door_Write_Property(
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
status =
Access_Door_Present_Value_Set(wp_data->object_instance,
value.type.Enumerated, wp_data->priority);
status = Access_Door_Present_Value_Set(wp_data->object_instance,
value.type.Enumerated,
wp_data->priority);
if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
@@ -527,13 +485,12 @@ bool Access_Door_Write_Property(
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class, &wp_data->error_code);
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class,
&wp_data->error_code);
if (status) {
status =
Access_Door_Present_Value_Relinquish
(wp_data->object_instance, wp_data->priority);
status = Access_Door_Present_Value_Relinquish(
wp_data->object_instance, wp_data->priority);
if (!status) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
@@ -552,10 +509,9 @@ bool Access_Door_Write_Property(
break;
case PROP_DOOR_STATUS:
if (Access_Door_Out_Of_Service(wp_data->object_instance)) {
status =
WPValidateArgType(&value,
BACNET_APPLICATION_TAG_ENUMERATED, &wp_data->error_class,
&wp_data->error_code);
status = WPValidateArgType(
&value, BACNET_APPLICATION_TAG_ENUMERATED,
&wp_data->error_class, &wp_data->error_code);
if (status) {
ad_descr[object_index].door_status = value.type.Enumerated;
}
@@ -566,10 +522,9 @@ bool Access_Door_Write_Property(
break;
case PROP_LOCK_STATUS:
if (Access_Door_Out_Of_Service(wp_data->object_instance)) {
status =
WPValidateArgType(&value,
BACNET_APPLICATION_TAG_ENUMERATED, &wp_data->error_class,
&wp_data->error_code);
status = WPValidateArgType(
&value, BACNET_APPLICATION_TAG_ENUMERATED,
&wp_data->error_class, &wp_data->error_code);
if (status) {
ad_descr[object_index].lock_status = value.type.Enumerated;
}
@@ -580,10 +535,9 @@ bool Access_Door_Write_Property(
break;
case PROP_DOOR_ALARM_STATE:
if (Access_Door_Out_Of_Service(wp_data->object_instance)) {
status =
WPValidateArgType(&value,
BACNET_APPLICATION_TAG_ENUMERATED, &wp_data->error_class,
&wp_data->error_code);
status = WPValidateArgType(
&value, BACNET_APPLICATION_TAG_ENUMERATED,
&wp_data->error_class, &wp_data->error_code);
if (status) {
ad_descr[object_index].door_alarm_state =
value.type.Enumerated;
@@ -618,17 +572,14 @@ bool Access_Door_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -638,10 +589,9 @@ bool WPValidateArgType(
return false;
}
void testAccessDoor(
Test * pTest)
void testAccessDoor(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -668,8 +618,7 @@ void testAccessDoor(
}
#ifdef TEST_ACCESS_DOOR
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -681,7 +630,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+77 -115
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Access Point Objects - customize for your use */
@@ -60,20 +60,13 @@ static const int Properties_Required[] = {
PROP_ACCESS_EVENT_CREDENTIAL,
PROP_ACCESS_DOORS,
PROP_PRIORITY_FOR_WRITING,
-1
};
-1};
static const int Properties_Optional[] = {
-1
};
static const int Properties_Optional[] = {-1};
static const int Properties_Proprietary[] = {
-1
};
static const int Properties_Proprietary[] = {-1};
void Access_Point_Property_Lists(
const int **pRequired,
const int **pOptional,
void Access_Point_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -86,8 +79,7 @@ void Access_Point_Property_Lists(
return;
}
void Access_Point_Init(
void)
void Access_Point_Init(void)
{
unsigned i;
@@ -98,8 +90,7 @@ void Access_Point_Init(
ap_descr[i].event_state = EVENT_STATE_NORMAL;
ap_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
ap_descr[i].out_of_service = false;
ap_descr[i].authentication_status =
AUTHENTICATION_STATUS_NOT_READY;
ap_descr[i].authentication_status = AUTHENTICATION_STATUS_NOT_READY;
ap_descr[i].active_authentication_policy = 0;
ap_descr[i].number_of_authentication_policies = 0;
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 */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Access_Point_Valid_Instance(
uint32_t object_instance)
bool Access_Point_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ACCESS_POINTS)
return true;
@@ -129,8 +119,7 @@ bool Access_Point_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Access_Point_Count(
void)
unsigned Access_Point_Count(void)
{
return MAX_ACCESS_POINTS;
}
@@ -138,8 +127,7 @@ unsigned Access_Point_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Access_Point_Index_To_Instance(
unsigned index)
uint32_t Access_Point_Index_To_Instance(unsigned index)
{
return index;
}
@@ -147,8 +135,7 @@ uint32_t Access_Point_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Access_Point_Instance_To_Index(
uint32_t object_instance)
unsigned Access_Point_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_ACCESS_POINTS;
@@ -159,24 +146,22 @@ unsigned Access_Point_Instance_To_Index(
}
/* note: the object name must be unique within this device */
bool Access_Point_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Access_Point_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
if (object_instance < MAX_ACCESS_POINTS) {
sprintf(text_string, "ACCESS POINT %lu",
(unsigned long) object_instance);
(unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
return status;
}
bool Access_Point_Out_Of_Service(
uint32_t instance)
bool Access_Point_Out_Of_Service(uint32_t instance)
{
unsigned index = 0;
bool oos_flag = false;
@@ -189,9 +174,7 @@ bool Access_Point_Out_Of_Service(
return oos_flag;
}
void Access_Point_Out_Of_Service_Set(
uint32_t instance,
bool oos_flag)
void Access_Point_Out_Of_Service_Set(uint32_t instance, bool oos_flag)
{
unsigned index = 0;
@@ -202,8 +185,7 @@ void Access_Point_Out_Of_Service_Set(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Access_Point_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Access_Point_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
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);
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ACCESS_POINT,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_ACCESS_POINT, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
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);
break;
case PROP_EVENT_STATE:
apdu_len =
encode_application_enumerated(&apdu[0],
ap_descr[object_index].event_state);
apdu_len = encode_application_enumerated(
&apdu[0], ap_descr[object_index].event_state);
break;
case PROP_RELIABILITY:
apdu_len =
encode_application_enumerated(&apdu[0],
ap_descr[object_index].reliability);
apdu_len = encode_application_enumerated(
&apdu[0], ap_descr[object_index].reliability);
break;
case PROP_OUT_OF_SERVICE:
state = Access_Point_Out_Of_Service(rpdata->object_instance);
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_AUTHENTICATION_STATUS:
apdu_len =
encode_application_enumerated(&apdu[0],
ap_descr[object_index].authentication_status);
apdu_len = encode_application_enumerated(
&apdu[0], ap_descr[object_index].authentication_status);
break;
case PROP_ACTIVE_AUTHENTICATION_POLICY:
apdu_len =
encode_application_unsigned(&apdu[0],
ap_descr[object_index].active_authentication_policy);
apdu_len = encode_application_unsigned(
&apdu[0], ap_descr[object_index].active_authentication_policy);
break;
case PROP_NUMBER_OF_AUTHENTICATION_POLICIES:
apdu_len =
encode_application_unsigned(&apdu[0],
apdu_len = encode_application_unsigned(
&apdu[0],
ap_descr[object_index].number_of_authentication_policies);
break;
case PROP_AUTHORIZATION_MODE:
apdu_len =
encode_application_enumerated(&apdu[0],
ap_descr[object_index].authorization_mode);
apdu_len = encode_application_enumerated(
&apdu[0], ap_descr[object_index].authorization_mode);
break;
case PROP_ACCESS_EVENT:
apdu_len =
encode_application_enumerated(&apdu[0],
ap_descr[object_index].access_event);
apdu_len = encode_application_enumerated(
&apdu[0], ap_descr[object_index].access_event);
break;
case PROP_ACCESS_EVENT_TAG:
apdu_len =
encode_application_unsigned(&apdu[0],
ap_descr[object_index].access_event_tag);
apdu_len = encode_application_unsigned(
&apdu[0], ap_descr[object_index].access_event_tag);
break;
case PROP_ACCESS_EVENT_TIME:
apdu_len =
bacapp_encode_timestamp(&apdu[0],
&ap_descr[object_index].access_event_time);
apdu_len = bacapp_encode_timestamp(
&apdu[0], &ap_descr[object_index].access_event_time);
break;
case PROP_ACCESS_EVENT_CREDENTIAL:
apdu_len =
bacapp_encode_device_obj_ref(&apdu[0],
&ap_descr[object_index].access_event_credential);
apdu_len = bacapp_encode_device_obj_ref(
&apdu[0], &ap_descr[object_index].access_event_credential);
break;
case PROP_ACCESS_DOORS:
if (rpdata->array_index == 0) {
apdu_len =
encode_application_unsigned(&apdu[0],
ap_descr[object_index].num_doors);
apdu_len = encode_application_unsigned(
&apdu[0], ap_descr[object_index].num_doors);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; i < ap_descr[object_index].num_doors; i++) {
len =
bacapp_encode_device_obj_ref(&apdu[0],
&ap_descr[object_index].access_doors[i]);
len = bacapp_encode_device_obj_ref(
&apdu[0], &ap_descr[object_index].access_doors[i]);
if (apdu_len + len < MAX_APDU)
apdu_len += len;
else {
@@ -319,10 +289,9 @@ int Access_Point_Read_Property(
}
} else {
if (rpdata->array_index <= ap_descr[object_index].num_doors) {
apdu_len =
bacapp_encode_device_obj_ref(&apdu[0],
&ap_descr[object_index].access_doors[rpdata->
array_index - 1]);
apdu_len = bacapp_encode_device_obj_ref(
&apdu[0], &ap_descr[object_index]
.access_doors[rpdata->array_index - 1]);
} else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -348,16 +317,14 @@ int Access_Point_Read_Property(
}
/* returns true if successful */
bool Access_Point_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Access_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -404,17 +371,14 @@ bool Access_Point_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -424,10 +388,9 @@ bool WPValidateArgType(
return false;
}
void testAccessPoint(
Test * pTest)
void testAccessPoint(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -454,8 +417,7 @@ void testAccessPoint(
}
#ifdef TEST_ACCESS_POINT
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -467,7 +429,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+78 -103
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Access Rights Objects - customize for your use */
@@ -42,8 +42,7 @@ static bool Access_Rights_Initialized = false;
static ACCESS_RIGHTS_DESCR ar_descr[MAX_ACCESS_RIGHTSS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
static const int Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_GLOBAL_IDENTIFIER,
@@ -52,20 +51,13 @@ static const int Properties_Required[] = {
PROP_ENABLE,
PROP_NEGATIVE_ACCESS_RULES,
PROP_POSITIVE_ACCESS_RULES,
-1
};
-1};
static const int Properties_Optional[] = {
-1
};
static const int Properties_Optional[] = {-1};
static const int Properties_Proprietary[] = {
-1
};
static const int Properties_Proprietary[] = {-1};
void Access_Rights_Property_Lists(
const int **pRequired,
const int **pOptional,
void Access_Rights_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -78,8 +70,7 @@ void Access_Rights_Property_Lists(
return;
}
void Access_Rights_Init(
void)
void Access_Rights_Init(void)
{
unsigned i;
@@ -87,7 +78,8 @@ void Access_Rights_Init(
Access_Rights_Initialized = true;
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].enable = false;
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 */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Access_Rights_Valid_Instance(
uint32_t object_instance)
bool Access_Rights_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ACCESS_RIGHTSS)
return true;
@@ -113,8 +104,7 @@ bool Access_Rights_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Access_Rights_Count(
void)
unsigned Access_Rights_Count(void)
{
return MAX_ACCESS_RIGHTSS;
}
@@ -122,8 +112,7 @@ unsigned Access_Rights_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Access_Rights_Index_To_Instance(
unsigned index)
uint32_t Access_Rights_Index_To_Instance(unsigned index)
{
return index;
}
@@ -131,8 +120,7 @@ uint32_t Access_Rights_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Access_Rights_Instance_To_Index(
uint32_t object_instance)
unsigned Access_Rights_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_ACCESS_RIGHTSS;
@@ -143,16 +131,15 @@ unsigned Access_Rights_Instance_To_Index(
}
/* note: the object name must be unique within this device */
bool Access_Rights_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Access_Rights_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
if (object_instance < MAX_ACCESS_RIGHTSS) {
sprintf(text_string, "ACCESS RIGHTS %lu",
(unsigned long) object_instance);
(unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
@@ -160,8 +147,7 @@ bool Access_Rights_Object_Name(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Access_Rights_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Access_Rights_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
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);
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ACCESS_RIGHTS,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_ACCESS_RIGHTS, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
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);
break;
case PROP_GLOBAL_IDENTIFIER:
apdu_len =
encode_application_unsigned(&apdu[0],
ar_descr[object_index].global_identifier);
apdu_len = encode_application_unsigned(
&apdu[0], ar_descr[object_index].global_identifier);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
@@ -206,26 +190,24 @@ int Access_Rights_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_RELIABILITY:
apdu_len =
encode_application_enumerated(&apdu[0],
ar_descr[object_index].reliability);
apdu_len = encode_application_enumerated(
&apdu[0], ar_descr[object_index].reliability);
break;
case PROP_ENABLE:
apdu_len =
encode_application_boolean(&apdu[0],
ar_descr[object_index].enable);
apdu_len = encode_application_boolean(
&apdu[0], ar_descr[object_index].enable);
break;
case PROP_NEGATIVE_ACCESS_RULES:
if (rpdata->array_index == 0) {
apdu_len =
encode_application_unsigned(&apdu[0],
apdu_len = encode_application_unsigned(
&apdu[0],
ar_descr[object_index].negative_access_rules_count);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0;
i < ar_descr[object_index].negative_access_rules_count;
i++) {
len =
bacapp_encode_access_rule(&apdu[0],
len = bacapp_encode_access_rule(
&apdu[0],
&ar_descr[object_index].negative_access_rules[i]);
if (apdu_len + len < MAX_APDU)
apdu_len += len;
@@ -239,10 +221,10 @@ int Access_Rights_Read_Property(
} else {
if (rpdata->array_index <=
ar_descr[object_index].negative_access_rules_count) {
apdu_len =
bacapp_encode_access_rule(&apdu[0],
&ar_descr[object_index].
negative_access_rules[rpdata->array_index - 1]);
apdu_len = bacapp_encode_access_rule(
&apdu[0],
&ar_descr[object_index]
.negative_access_rules[rpdata->array_index - 1]);
} else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -252,15 +234,15 @@ int Access_Rights_Read_Property(
break;
case PROP_POSITIVE_ACCESS_RULES:
if (rpdata->array_index == 0) {
apdu_len =
encode_application_unsigned(&apdu[0],
apdu_len = encode_application_unsigned(
&apdu[0],
ar_descr[object_index].positive_access_rules_count);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0;
i < ar_descr[object_index].positive_access_rules_count;
i++) {
len =
bacapp_encode_access_rule(&apdu[0],
len = bacapp_encode_access_rule(
&apdu[0],
&ar_descr[object_index].positive_access_rules[i]);
if (apdu_len + len < MAX_APDU)
apdu_len += len;
@@ -274,10 +256,10 @@ int Access_Rights_Read_Property(
} else {
if (rpdata->array_index <=
ar_descr[object_index].positive_access_rules_count) {
apdu_len =
bacapp_encode_access_rule(&apdu[0],
&ar_descr[object_index].
positive_access_rules[rpdata->array_index - 1]);
apdu_len = bacapp_encode_access_rule(
&apdu[0],
&ar_descr[object_index]
.positive_access_rules[rpdata->array_index - 1]);
} else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -293,9 +275,9 @@ int Access_Rights_Read_Property(
}
/* only array properties can have array options */
if ((apdu_len >= 0) &&
(rpdata->object_property != PROP_NEGATIVE_ACCESS_RULES)
&& (rpdata->object_property != PROP_POSITIVE_ACCESS_RULES)
&& (rpdata->array_index != BACNET_ARRAY_ALL)) {
(rpdata->object_property != PROP_NEGATIVE_ACCESS_RULES) &&
(rpdata->object_property != PROP_POSITIVE_ACCESS_RULES) &&
(rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR;
@@ -305,8 +287,7 @@ int Access_Rights_Read_Property(
}
/* returns true if successful */
bool Access_Rights_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Access_Rights_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
@@ -314,8 +295,7 @@ bool Access_Rights_Write_Property(
unsigned object_index = 0;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -325,9 +305,9 @@ bool Access_Rights_Write_Property(
return false;
}
/* only array properties can have array options */
if ((wp_data->object_property != PROP_NEGATIVE_ACCESS_RULES)
&& (wp_data->object_property != PROP_POSITIVE_ACCESS_RULES)
&& (wp_data->array_index != BACNET_ARRAY_ALL)) {
if ((wp_data->object_property != PROP_NEGATIVE_ACCESS_RULES) &&
(wp_data->object_property != PROP_POSITIVE_ACCESS_RULES) &&
(wp_data->array_index != BACNET_ARRAY_ALL)) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
return false;
@@ -363,17 +343,14 @@ bool Access_Rights_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -383,10 +360,9 @@ bool WPValidateArgType(
return false;
}
void testAccessRights(
Test * pTest)
void testAccessRights(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -413,8 +389,7 @@ void testAccessRights(
}
#ifdef TEST_ACCESS_RIGHTS
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -426,7 +401,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+59 -91
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Access User Objects - customize for your use */
@@ -43,28 +43,15 @@ static ACCESS_USER_DESCR au_descr[MAX_ACCESS_USERS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_GLOBAL_IDENTIFIER,
PROP_STATUS_FLAGS,
PROP_RELIABILITY,
PROP_USER_TYPE,
PROP_CREDENTIALS,
-1
};
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
PROP_GLOBAL_IDENTIFIER, PROP_STATUS_FLAGS, PROP_RELIABILITY,
PROP_USER_TYPE, PROP_CREDENTIALS, -1};
static const int Properties_Optional[] = {
-1
};
static const int Properties_Optional[] = {-1};
static const int Properties_Proprietary[] = {
-1
};
static const int Properties_Proprietary[] = {-1};
void Access_User_Property_Lists(
const int **pRequired,
const int **pOptional,
void Access_User_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -77,8 +64,7 @@ void Access_User_Property_Lists(
return;
}
void Access_User_Init(
void)
void Access_User_Init(void)
{
unsigned i;
@@ -86,7 +72,8 @@ void Access_User_Init(
Access_User_Initialized = true;
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].user_type = ACCESS_USER_TYPE_PERSON;
au_descr[i].credentials_count = 0;
@@ -100,8 +87,7 @@ void Access_User_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Access_User_Valid_Instance(
uint32_t object_instance)
bool Access_User_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ACCESS_USERS)
return true;
@@ -111,8 +97,7 @@ bool Access_User_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Access_User_Count(
void)
unsigned Access_User_Count(void)
{
return MAX_ACCESS_USERS;
}
@@ -120,8 +105,7 @@ unsigned Access_User_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Access_User_Index_To_Instance(
unsigned index)
uint32_t Access_User_Index_To_Instance(unsigned index)
{
return index;
}
@@ -129,8 +113,7 @@ uint32_t Access_User_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Access_User_Instance_To_Index(
uint32_t object_instance)
unsigned Access_User_Instance_To_Index(uint32_t object_instance)
{
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 */
bool Access_User_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Access_User_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
if (object_instance < MAX_ACCESS_USERS) {
sprintf(text_string, "ACCESS USER %lu",
(unsigned long) object_instance);
sprintf(text_string, "ACCESS USER %lu", (unsigned long)object_instance);
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 */
int Access_User_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Access_User_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
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);
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ACCESS_USER,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_ACCESS_USER, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
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);
break;
case PROP_GLOBAL_IDENTIFIER:
apdu_len =
encode_application_unsigned(&apdu[0],
au_descr[object_index].global_identifier);
apdu_len = encode_application_unsigned(
&apdu[0], au_descr[object_index].global_identifier);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
@@ -204,20 +182,17 @@ int Access_User_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_RELIABILITY:
apdu_len =
encode_application_enumerated(&apdu[0],
au_descr[object_index].reliability);
apdu_len = encode_application_enumerated(
&apdu[0], au_descr[object_index].reliability);
break;
case PROP_USER_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0],
au_descr[object_index].user_type);
apdu_len = encode_application_enumerated(
&apdu[0], au_descr[object_index].user_type);
break;
case PROP_CREDENTIALS:
for (i = 0; i < au_descr[object_index].credentials_count; i++) {
len =
bacapp_encode_device_obj_ref(&apdu[0],
&au_descr[object_index].credentials[i]);
len = bacapp_encode_device_obj_ref(
&apdu[0], &au_descr[object_index].credentials[i]);
if (apdu_len + len < MAX_APDU)
apdu_len += len;
else {
@@ -245,8 +220,7 @@ int Access_User_Read_Property(
}
/* returns true if successful */
bool Access_User_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Access_User_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
@@ -254,8 +228,7 @@ bool Access_User_Write_Property(
unsigned object_index = 0;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -301,17 +274,14 @@ bool Access_User_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -321,10 +291,9 @@ bool WPValidateArgType(
return false;
}
void testAccessUser(
Test * pTest)
void testAccessUser(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -351,8 +320,7 @@ void testAccessUser(
}
#ifdef TEST_ACCESS_USER
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -364,7 +332,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+69 -109
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Access Zone Objects - customize for your use */
@@ -43,31 +43,16 @@ static ACCESS_ZONE_DESCR az_descr[MAX_ACCESS_ZONES];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_GLOBAL_IDENTIFIER,
PROP_OCCUPANCY_STATE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_RELIABILITY,
PROP_OUT_OF_SERVICE,
PROP_ENTRY_POINTS,
PROP_EXIT_POINTS,
-1
};
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
PROP_GLOBAL_IDENTIFIER, 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[] = {
-1
};
static const int Properties_Optional[] = {-1};
static const int Properties_Proprietary[] = {
-1
};
static const int Properties_Proprietary[] = {-1};
void Access_Zone_Property_Lists(
const int **pRequired,
const int **pOptional,
void Access_Zone_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -80,8 +65,7 @@ void Access_Zone_Property_Lists(
return;
}
void Access_Zone_Init(
void)
void Access_Zone_Init(void)
{
unsigned i;
@@ -89,7 +73,8 @@ void Access_Zone_Init(
Access_Zone_Initialized = true;
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].event_state = EVENT_STATE_NORMAL;
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 */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Access_Zone_Valid_Instance(
uint32_t object_instance)
bool Access_Zone_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ACCESS_ZONES)
return true;
@@ -117,8 +101,7 @@ bool Access_Zone_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Access_Zone_Count(
void)
unsigned Access_Zone_Count(void)
{
return MAX_ACCESS_ZONES;
}
@@ -126,8 +109,7 @@ unsigned Access_Zone_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Access_Zone_Index_To_Instance(
unsigned index)
uint32_t Access_Zone_Index_To_Instance(unsigned index)
{
return index;
}
@@ -135,8 +117,7 @@ uint32_t Access_Zone_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Access_Zone_Instance_To_Index(
uint32_t object_instance)
unsigned Access_Zone_Instance_To_Index(uint32_t object_instance)
{
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 */
bool Access_Zone_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Access_Zone_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
if (object_instance < MAX_ACCESS_ZONES) {
sprintf(text_string, "ACCESS ZONE %lu",
(unsigned long) object_instance);
sprintf(text_string, "ACCESS ZONE %lu", (unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
return status;
}
bool Access_Zone_Out_Of_Service(
uint32_t instance)
bool Access_Zone_Out_Of_Service(uint32_t instance)
{
unsigned index = 0;
bool oos_flag = false;
@@ -177,9 +155,7 @@ bool Access_Zone_Out_Of_Service(
return oos_flag;
}
void Access_Zone_Out_Of_Service_Set(
uint32_t instance,
bool oos_flag)
void Access_Zone_Out_Of_Service_Set(uint32_t instance, bool oos_flag)
{
unsigned index = 0;
@@ -190,8 +166,7 @@ void Access_Zone_Out_Of_Service_Set(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Access_Zone_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Access_Zone_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
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);
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ACCESS_ZONE,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_ACCESS_ZONE, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
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);
break;
case PROP_GLOBAL_IDENTIFIER:
apdu_len =
encode_application_unsigned(&apdu[0],
az_descr[object_index].global_identifier);
apdu_len = encode_application_unsigned(
&apdu[0], az_descr[object_index].global_identifier);
break;
case PROP_OCCUPANCY_STATE:
apdu_len =
encode_application_enumerated(&apdu[0],
az_descr[object_index].occupancy_state);
apdu_len = encode_application_enumerated(
&apdu[0], az_descr[object_index].occupancy_state);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
@@ -243,14 +215,12 @@ int Access_Zone_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len =
encode_application_enumerated(&apdu[0],
az_descr[object_index].event_state);
apdu_len = encode_application_enumerated(
&apdu[0], az_descr[object_index].event_state);
break;
case PROP_RELIABILITY:
apdu_len =
encode_application_enumerated(&apdu[0],
az_descr[object_index].reliability);
apdu_len = encode_application_enumerated(
&apdu[0], az_descr[object_index].reliability);
break;
case PROP_OUT_OF_SERVICE:
state = Access_Zone_Out_Of_Service(rpdata->object_instance);
@@ -258,9 +228,8 @@ int Access_Zone_Read_Property(
break;
case PROP_ENTRY_POINTS:
for (i = 0; i < az_descr[object_index].entry_points_count; i++) {
len =
bacapp_encode_device_obj_ref(&apdu[0],
&az_descr[object_index].entry_points[i]);
len = bacapp_encode_device_obj_ref(
&apdu[0], &az_descr[object_index].entry_points[i]);
if (apdu_len + len < MAX_APDU)
apdu_len += len;
else {
@@ -273,9 +242,8 @@ int Access_Zone_Read_Property(
break;
case PROP_EXIT_POINTS:
for (i = 0; i < az_descr[object_index].exit_points_count; i++) {
len =
bacapp_encode_device_obj_ref(&apdu[0],
&az_descr[object_index].exit_points[i]);
len = bacapp_encode_device_obj_ref(
&apdu[0], &az_descr[object_index].exit_points[i]);
if (apdu_len + len < MAX_APDU)
apdu_len += len;
else {
@@ -303,8 +271,7 @@ int Access_Zone_Read_Property(
}
/* returns true if successful */
bool Access_Zone_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Access_Zone_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
@@ -312,8 +279,7 @@ bool Access_Zone_Write_Property(
unsigned object_index = 0;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -341,10 +307,9 @@ bool Access_Zone_Write_Property(
break;
case PROP_RELIABILITY:
if (Access_Zone_Out_Of_Service(wp_data->object_instance)) {
status =
WPValidateArgType(&value,
BACNET_APPLICATION_TAG_ENUMERATED, &wp_data->error_class,
&wp_data->error_code);
status = WPValidateArgType(
&value, BACNET_APPLICATION_TAG_ENUMERATED,
&wp_data->error_class, &wp_data->error_code);
if (status) {
az_descr[object_index].reliability = value.type.Enumerated;
}
@@ -374,17 +339,14 @@ bool Access_Zone_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -394,10 +356,9 @@ bool WPValidateArgType(
return false;
}
void testAccessZone(
Test * pTest)
void testAccessZone(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -424,8 +385,7 @@ void testAccessZone(
}
#ifdef TEST_ACCESS_ZONE
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -437,7 +397,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+249 -290
View File
File diff suppressed because it is too large Load Diff
+70 -102
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Analog Output Objects - customize for your use */
@@ -60,8 +60,7 @@ static bool Out_Of_Service[MAX_ANALOG_OUTPUTS];
static bool Analog_Output_Initialized = false;
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
static const int Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
@@ -71,20 +70,13 @@ static const int Properties_Required[] = {
PROP_UNITS,
PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT,
-1
};
-1};
static const int Properties_Optional[] = {
-1
};
static const int Properties_Optional[] = {-1};
static const int Properties_Proprietary[] = {
-1
};
static const int Properties_Proprietary[] = {-1};
void Analog_Output_Property_Lists(
const int **pRequired,
const int **pOptional,
void Analog_Output_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -97,8 +89,7 @@ void Analog_Output_Property_Lists(
return;
}
void Analog_Output_Init(
void)
void Analog_Output_Init(void)
{
unsigned i, j;
@@ -119,8 +110,7 @@ void Analog_Output_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Output_Valid_Instance(
uint32_t object_instance)
bool Analog_Output_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ANALOG_OUTPUTS)
return true;
@@ -130,8 +120,7 @@ bool Analog_Output_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Analog_Output_Count(
void)
unsigned Analog_Output_Count(void)
{
return MAX_ANALOG_OUTPUTS;
}
@@ -139,8 +128,7 @@ unsigned Analog_Output_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Analog_Output_Index_To_Instance(
unsigned index)
uint32_t Analog_Output_Index_To_Instance(unsigned index)
{
return index;
}
@@ -148,8 +136,7 @@ uint32_t Analog_Output_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Analog_Output_Instance_To_Index(
uint32_t object_instance)
unsigned Analog_Output_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_ANALOG_OUTPUTS;
@@ -159,8 +146,7 @@ unsigned Analog_Output_Instance_To_Index(
return index;
}
float Analog_Output_Present_Value(
uint32_t object_instance)
float Analog_Output_Present_Value(uint32_t object_instance)
{
float value = AO_RELINQUISH_DEFAULT;
unsigned index = 0;
@@ -179,8 +165,7 @@ float Analog_Output_Present_Value(
return value;
}
unsigned Analog_Output_Present_Value_Priority(
uint32_t object_instance)
unsigned Analog_Output_Present_Value_Priority(uint32_t object_instance)
{
unsigned index = 0; /* instance to index conversion */
unsigned i = 0; /* loop counter */
@@ -199,9 +184,7 @@ unsigned Analog_Output_Present_Value_Priority(
return priority;
}
bool Analog_Output_Present_Value_Set(
uint32_t object_instance,
float value,
bool Analog_Output_Present_Value_Set(uint32_t object_instance, float value,
unsigned priority)
{
unsigned index = 0;
@@ -210,9 +193,9 @@ bool Analog_Output_Present_Value_Set(
index = Analog_Output_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_OUTPUTS) {
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value >= 0.0) && (value <= 100.0)) {
Analog_Output_Level[index][priority - 1] = (uint8_t) value;
(priority != 6 /* reserved */) && (value >= 0.0) &&
(value <= 100.0)) {
Analog_Output_Level[index][priority - 1] = (uint8_t)value;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
@@ -226,8 +209,7 @@ bool Analog_Output_Present_Value_Set(
return status;
}
bool Analog_Output_Present_Value_Relinquish(
uint32_t object_instance,
bool Analog_Output_Present_Value_Relinquish(uint32_t object_instance,
unsigned priority)
{
unsigned index = 0;
@@ -236,7 +218,7 @@ bool Analog_Output_Present_Value_Relinquish(
index = Analog_Output_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_OUTPUTS) {
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ )) {
(priority != 6 /* reserved */)) {
Analog_Output_Level[index][priority - 1] = AO_LEVEL_NULL;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
@@ -252,24 +234,22 @@ bool Analog_Output_Present_Value_Relinquish(
}
/* note: the object name must be unique within this device */
bool Analog_Output_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Analog_Output_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
if (object_instance < MAX_ANALOG_OUTPUTS) {
sprintf(text_string, "ANALOG OUTPUT %lu",
(unsigned long) object_instance);
(unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
return status;
}
bool Analog_Output_Out_Of_Service(
uint32_t instance)
bool Analog_Output_Out_Of_Service(uint32_t instance)
{
unsigned index = 0;
bool oos_flag = false;
@@ -282,9 +262,7 @@ bool Analog_Output_Out_Of_Service(
return oos_flag;
}
void Analog_Output_Out_Of_Service_Set(
uint32_t instance,
bool oos_flag)
void Analog_Output_Out_Of_Service_Set(uint32_t instance, bool oos_flag)
{
unsigned index = 0;
@@ -295,14 +273,13 @@ void Analog_Output_Out_Of_Service_Set(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Analog_Output_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Analog_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
float real_value = (float) 1.414;
float real_value = (float)1.414;
unsigned object_index = 0;
unsigned i = 0;
bool state = false;
@@ -315,9 +292,8 @@ int Analog_Output_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ANALOG_OUTPUT,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_ANALOG_OUTPUT, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
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]);
else {
real_value = Analog_Output_Level[object_index][i];
len =
encode_application_real(&apdu[apdu_len],
len = encode_application_real(&apdu[apdu_len],
real_value);
}
/* add it if we have room */
@@ -390,7 +365,8 @@ int Analog_Output_Read_Property(
1] == AO_LEVEL_NULL)
apdu_len = encode_application_null(&apdu[0]);
else {
real_value = Analog_Output_Level[object_index]
real_value =
Analog_Output_Level[object_index]
[rpdata->array_index - 1];
apdu_len =
encode_application_real(&apdu[0], real_value);
@@ -424,16 +400,14 @@ int Analog_Output_Read_Property(
}
/* returns true if successful */
bool Analog_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -455,9 +429,9 @@ bool Analog_Output_Write_Property(
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
status =
Analog_Output_Present_Value_Set(wp_data->object_instance,
value.type.Real, wp_data->priority);
status = Analog_Output_Present_Value_Set(
wp_data->object_instance, value.type.Real,
wp_data->priority);
if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
@@ -469,13 +443,12 @@ bool Analog_Output_Write_Property(
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class, &wp_data->error_code);
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class,
&wp_data->error_code);
if (status) {
status =
Analog_Output_Present_Value_Relinquish
(wp_data->object_instance, wp_data->priority);
status = Analog_Output_Present_Value_Relinquish(
wp_data->object_instance, wp_data->priority);
if (!status) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
@@ -512,17 +485,14 @@ bool Analog_Output_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
bool bResult;
@@ -540,10 +510,9 @@ bool WPValidateArgType(
return (bResult);
}
void testAnalogOutput(
Test * pTest)
void testAnalogOutput(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -570,8 +539,7 @@ void testAnalogOutput(
}
#ifdef TEST_ANALOG_OUTPUT
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -583,7 +551,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+230 -261
View File
@@ -1,28 +1,28 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Analog Value Objects - customize for your use */
@@ -41,7 +41,6 @@
#include "handlers.h"
#include "av.h"
#ifndef MAX_ANALOG_VALUES
#define MAX_ANALOG_VALUES 4
#endif
@@ -50,19 +49,11 @@ ANALOG_VALUE_DESCR AV_Descr[MAX_ANALOG_VALUES];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Value_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_UNITS,
-1
};
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE, PROP_UNITS, -1};
static const int Analog_Value_Properties_Optional[] = {
PROP_DESCRIPTION,
static const int Analog_Value_Properties_Optional[] = {PROP_DESCRIPTION,
PROP_COV_INCREMENT,
#if defined(INTRINSIC_REPORTING)
PROP_TIME_DELAY,
@@ -76,16 +67,11 @@ static const int Analog_Value_Properties_Optional[] = {
PROP_NOTIFY_TYPE,
PROP_EVENT_TIME_STAMPS,
#endif
-1
};
-1};
static const int Analog_Value_Properties_Proprietary[] = {
-1
};
static const int Analog_Value_Properties_Proprietary[] = {-1};
void Analog_Value_Property_Lists(
const int **pRequired,
const int **pOptional,
void Analog_Value_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -98,8 +84,7 @@ void Analog_Value_Property_Lists(
return;
}
void Analog_Value_Init(
void)
void Analog_Value_Init(void)
{
unsigned i;
#if defined(INTRINSIC_REPORTING)
@@ -139,8 +124,7 @@ void Analog_Value_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Value_Valid_Instance(
uint32_t object_instance)
bool Analog_Value_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ANALOG_VALUES)
return true;
@@ -150,8 +134,7 @@ bool Analog_Value_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Analog_Value_Count(
void)
unsigned Analog_Value_Count(void)
{
return MAX_ANALOG_VALUES;
}
@@ -159,8 +142,7 @@ unsigned Analog_Value_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Analog_Value_Index_To_Instance(
unsigned index)
uint32_t Analog_Value_Index_To_Instance(unsigned index)
{
return index;
}
@@ -168,8 +150,7 @@ uint32_t Analog_Value_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Analog_Value_Instance_To_Index(
uint32_t object_instance)
unsigned Analog_Value_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_ANALOG_VALUES;
@@ -179,8 +160,7 @@ unsigned Analog_Value_Instance_To_Index(
return index;
}
static void Analog_Value_COV_Detect(unsigned int index,
float value)
static void Analog_Value_COV_Detect(unsigned int index, float value)
{
float prior_value = 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.
*/
bool Analog_Value_Present_Value_Set(
uint32_t object_instance,
float value,
bool Analog_Value_Present_Value_Set(uint32_t object_instance, float value,
uint8_t priority)
{
unsigned index = 0;
@@ -228,8 +206,7 @@ bool Analog_Value_Present_Value_Set(
return status;
}
float Analog_Value_Present_Value(
uint32_t object_instance)
float Analog_Value_Present_Value(uint32_t object_instance)
{
float value = 0;
unsigned index = 0;
@@ -243,23 +220,22 @@ float Analog_Value_Present_Value(
}
/* note: the object name must be unique within this device */
bool Analog_Value_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Analog_Value_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
if (object_instance < MAX_ANALOG_VALUES) {
sprintf(text_string, "ANALOG VALUE %lu",
(unsigned long) object_instance);
(unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
return status;
}
/**
/**
* For a given object instance-number, determines if the COV flag
* has been triggered.
*
@@ -303,9 +279,8 @@ void Analog_Value_Change_Of_Value_Clear(uint32_t object_instance)
*
* @return true if the value list is encoded
*/
bool Analog_Value_Encode_Value_List(
uint32_t object_instance,
BACNET_PROPERTY_VALUE * value_list)
bool Analog_Value_Encode_Value_List(uint32_t object_instance,
BACNET_PROPERTY_VALUE *value_list)
{
bool status = false;
@@ -328,8 +303,8 @@ bool Analog_Value_Encode_Value_List(
bitstring_init(&value_list->value.type.Bit_String);
bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_FAULT, false);
bitstring_set_bit(&value_list->value.type.Bit_String, STATUS_FLAG_FAULT,
false);
bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_OVERRIDDEN, false);
if (Analog_Value_Out_Of_Service(object_instance)) {
@@ -348,8 +323,7 @@ bool Analog_Value_Encode_Value_List(
return status;
}
float Analog_Value_COV_Increment(
uint32_t object_instance)
float Analog_Value_COV_Increment(uint32_t object_instance)
{
unsigned index = 0;
float value = 0;
@@ -362,9 +336,7 @@ float Analog_Value_COV_Increment(
return value;
}
void Analog_Value_COV_Increment_Set(
uint32_t object_instance,
float value)
void Analog_Value_COV_Increment_Set(uint32_t object_instance, float value)
{
unsigned index = 0;
@@ -375,8 +347,7 @@ void Analog_Value_COV_Increment_Set(
}
}
bool Analog_Value_Out_Of_Service(
uint32_t object_instance)
bool Analog_Value_Out_Of_Service(uint32_t object_instance)
{
unsigned index = 0;
bool value = false;
@@ -389,9 +360,7 @@ bool Analog_Value_Out_Of_Service(
return value;
}
void Analog_Value_Out_Of_Service_Set(
uint32_t object_instance,
bool value)
void Analog_Value_Out_Of_Service_Set(uint32_t object_instance, bool value)
{
unsigned index = 0;
@@ -405,13 +374,12 @@ void Analog_Value_Out_Of_Service_Set(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Analog_Value_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
float real_value = (float) 1.414;
float real_value = (float)1.414;
unsigned object_index = 0;
bool state = false;
uint8_t *apdu = NULL;
@@ -436,9 +404,8 @@ int Analog_Value_Read_Property(
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_ANALOG_VALUE, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
@@ -477,8 +444,7 @@ int Analog_Value_Read_Property(
case PROP_EVENT_STATE:
#if defined(INTRINSIC_REPORTING)
apdu_len =
encode_application_enumerated(&apdu[0],
CurrentAV->Event_State);
encode_application_enumerated(&apdu[0], CurrentAV->Event_State);
#else
apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
@@ -496,8 +462,8 @@ int Analog_Value_Read_Property(
break;
case PROP_COV_INCREMENT:
apdu_len = encode_application_real(&apdu[0],
CurrentAV->COV_Increment);
apdu_len =
encode_application_real(&apdu[0], CurrentAV->COV_Increment);
break;
#if defined(INTRINSIC_REPORTING)
@@ -507,14 +473,12 @@ int Analog_Value_Read_Property(
break;
case PROP_NOTIFICATION_CLASS:
apdu_len =
encode_application_unsigned(&apdu[0],
CurrentAV->Notification_Class);
apdu_len = encode_application_unsigned(
&apdu[0], CurrentAV->Notification_Class);
break;
case PROP_HIGH_LIMIT:
apdu_len =
encode_application_real(&apdu[0], CurrentAV->High_Limit);
apdu_len = encode_application_real(&apdu[0], CurrentAV->High_Limit);
break;
case PROP_LOW_LIMIT:
@@ -528,70 +492,73 @@ int Analog_Value_Read_Property(
case PROP_LIMIT_ENABLE:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, 0,
(CurrentAV->
Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ? true : false);
bitstring_set_bit(&bit_string, 1,
(CurrentAV->
Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true : false);
(CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE)
? true
: false);
bitstring_set_bit(
&bit_string, 1,
(CurrentAV->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true
: false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_ENABLE:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL,
(CurrentAV->
Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false);
bitstring_set_bit(
&bit_string, TRANSITION_TO_OFFNORMAL,
(CurrentAV->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true
: false);
bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT,
(CurrentAV->
Event_Enable & EVENT_ENABLE_TO_FAULT) ? true : false);
(CurrentAV->Event_Enable & EVENT_ENABLE_TO_FAULT)
? true
: false);
bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL,
(CurrentAV->
Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false);
(CurrentAV->Event_Enable & EVENT_ENABLE_TO_NORMAL)
? true
: false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_ACKED_TRANSITIONS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL,
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
bIsAcked);
bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT,
bitstring_set_bit(
&bit_string, TRANSITION_TO_OFFNORMAL,
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked);
bitstring_set_bit(
&bit_string, TRANSITION_TO_FAULT,
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);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_NOTIFY_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0],
CurrentAV->Notify_Type ? NOTIFY_EVENT : NOTIFY_ALARM);
apdu_len = encode_application_enumerated(
&apdu[0], CurrentAV->Notify_Type ? NOTIFY_EVENT : NOTIFY_ALARM);
break;
case PROP_EVENT_TIME_STAMPS:
/* Array element zero is the number of elements in the array */
if (rpdata->array_index == 0)
apdu_len =
encode_application_unsigned(&apdu[0],
MAX_BACNET_EVENT_TRANSITION);
apdu_len = encode_application_unsigned(
&apdu[0], MAX_BACNET_EVENT_TRANSITION);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; i < MAX_BACNET_EVENT_TRANSITION; i++) {
len =
encode_opening_tag(&apdu[apdu_len],
len = encode_opening_tag(&apdu[apdu_len],
TIME_STAMP_DATETIME);
len +=
encode_application_date(&apdu[apdu_len + len],
len += encode_application_date(
&apdu[apdu_len + len],
&CurrentAV->Event_Time_Stamps[i].date);
len +=
encode_application_time(&apdu[apdu_len + len],
len += encode_application_time(
&apdu[apdu_len + len],
&CurrentAV->Event_Time_Stamps[i].time);
len +=
encode_closing_tag(&apdu[apdu_len + len],
len += encode_closing_tag(&apdu[apdu_len + len],
TIME_STAMP_DATETIME);
/* add it if we have room */
@@ -607,11 +574,11 @@ int Analog_Value_Read_Property(
} else if (rpdata->array_index <= MAX_BACNET_EVENT_TRANSITION) {
apdu_len =
encode_opening_tag(&apdu[apdu_len], TIME_STAMP_DATETIME);
apdu_len +=
encode_application_date(&apdu[apdu_len],
apdu_len += encode_application_date(
&apdu[apdu_len],
&CurrentAV->Event_Time_Stamps[rpdata->array_index].date);
apdu_len +=
encode_application_time(&apdu[apdu_len],
apdu_len += encode_application_time(
&apdu[apdu_len],
&CurrentAV->Event_Time_Stamps[rpdata->array_index].time);
apdu_len +=
encode_closing_tag(&apdu[apdu_len], TIME_STAMP_DATETIME);
@@ -642,8 +609,7 @@ int Analog_Value_Read_Property(
}
/* returns true if successful */
bool Analog_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
unsigned int object_index = 0;
@@ -652,8 +618,7 @@ bool Analog_Value_Write_Property(
ANALOG_VALUE_DESCR *CurrentAV;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -683,7 +648,8 @@ bool Analog_Value_Write_Property(
algorithm and may not be used for other purposes in any
object. */
if (Analog_Value_Present_Value_Set(wp_data->object_instance,
value.type.Real, wp_data->priority)) {
value.type.Real,
wp_data->priority)) {
status = true;
} else if (wp_data->priority == 6) {
/* 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);
if (status) {
if (value.type.Real >= 0.0) {
Analog_Value_COV_Increment_Set(
wp_data->object_instance,
Analog_Value_COV_Increment_Set(wp_data->object_instance,
value.type.Real);
} else {
status = false;
@@ -827,7 +792,7 @@ bool Analog_Value_Write_Property(
&wp_data->error_class, &wp_data->error_code);
if (status) {
switch ((BACNET_NOTIFY_TYPE) value.type.Enumerated) {
switch ((BACNET_NOTIFY_TYPE)value.type.Enumerated) {
case NOTIFY_EVENT:
CurrentAV->Notify_Type = 1;
break;
@@ -867,9 +832,7 @@ bool Analog_Value_Write_Property(
return status;
}
void Analog_Value_Intrinsic_Reporting(
uint32_t object_instance)
void Analog_Value_Intrinsic_Reporting(uint32_t object_instance)
{
#if defined(INTRINSIC_REPORTING)
BACNET_EVENT_NOTIFICATION_DATA event_data;
@@ -882,7 +845,6 @@ void Analog_Value_Intrinsic_Reporting(
float PresentVal = 0.0f;
bool SendNotify = false;
object_index = Analog_Value_Instance_To_Index(object_instance);
if (object_index < MAX_ANALOG_VALUES)
CurrentAV = &AV_Descr[object_index];
@@ -893,7 +855,6 @@ void Analog_Value_Intrinsic_Reporting(
if (!CurrentAV->Limit_Enable)
return; /* limits are not configured */
if (CurrentAV->Ack_notify_data.bSendAckNotify) {
/* clean bSendAckNotify flag */
CurrentAV->Ack_notify_data.bSendAckNotify = false;
@@ -919,10 +880,12 @@ void Analog_Value_Intrinsic_Reporting(
switch (CurrentAV->Event_State) {
case EVENT_STATE_NORMAL:
/* A TO-OFFNORMAL event is generated under these conditions:
(a) the Present_Value must exceed the High_Limit for a minimum
period of time, specified in the Time_Delay property, and
(b) the HighLimitEnable flag must be set in the Limit_Enable property, and
(c) the TO-OFFNORMAL flag must be set in the Event_Enable property. */
(a) the Present_Value must exceed the High_Limit for a
minimum period of time, specified in the Time_Delay property,
and (b) the HighLimitEnable flag must be set in the
Limit_Enable property, and
(c) the TO-OFFNORMAL flag must be set in the Event_Enable
property. */
if ((PresentVal > CurrentAV->High_Limit) &&
((CurrentAV->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) the Present_Value must exceed the Low_Limit plus the Deadband
for a minimum period of time, specified in the Time_Delay property, and
(b) the LowLimitEnable flag must be set in the Limit_Enable property, and
(c) the TO-NORMAL flag must be set in the Event_Enable property. */
(a) the Present_Value must exceed the Low_Limit plus the
Deadband for a minimum period of time, specified in the
Time_Delay property, and (b) the LowLimitEnable flag must be
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) &&
((CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ==
EVENT_LOW_LIMIT_ENABLE) &&
@@ -956,14 +921,17 @@ void Analog_Value_Intrinsic_Reporting(
break;
case EVENT_STATE_HIGH_LIMIT:
/* Once exceeded, the Present_Value must fall below the High_Limit minus
the Deadband before a TO-NORMAL event is generated under these conditions:
(a) the Present_Value must fall below the High_Limit minus the Deadband
for a minimum period of time, specified in the Time_Delay property, and
(b) the HighLimitEnable flag must be set in the Limit_Enable property, and
(c) the TO-NORMAL flag must be set in the Event_Enable property. */
if ((PresentVal < CurrentAV->High_Limit - CurrentAV->Deadband)
&& ((CurrentAV->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ==
/* Once exceeded, the Present_Value must fall below the
High_Limit minus the Deadband before a TO-NORMAL event is
generated under these conditions: (a) the Present_Value must
fall below the High_Limit minus the Deadband for a minimum
period of time, specified in the Time_Delay property, and (b)
the HighLimitEnable flag must be set in the Limit_Enable
property, and (c) the TO-NORMAL flag must be set in the
Event_Enable property. */
if ((PresentVal <
CurrentAV->High_Limit - CurrentAV->Deadband) &&
((CurrentAV->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ==
EVENT_HIGH_LIMIT_ENABLE) &&
((CurrentAV->Event_Enable & 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,
the Present_Value must exceed the Low_Limit plus the Deadband
before a TO-NORMAL event is generated under these conditions:
(a) the Present_Value must exceed the Low_Limit plus the Deadband
for a minimum period of time, specified in the Time_Delay property, and
(b) the LowLimitEnable flag must be 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 + CurrentAV->Deadband)
&& ((CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ==
(a) the Present_Value must exceed the Low_Limit plus the
Deadband for a minimum period of time, specified in the
Time_Delay property, and (b) the LowLimitEnable flag must be
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 + CurrentAV->Deadband) &&
((CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ==
EVENT_LOW_LIMIT_ENABLE) &&
((CurrentAV->Event_Enable & EVENT_ENABLE_TO_NORMAL) ==
EVENT_ENABLE_TO_NORMAL)) {
@@ -1025,12 +995,12 @@ void Analog_Value_Intrinsic_Reporting(
case EVENT_STATE_NORMAL:
if (FromState == EVENT_STATE_HIGH_LIMIT) {
ExceededLimit = CurrentAV->High_Limit;
characterstring_init_ansi(&msgText,
"Back to normal state from high limit");
characterstring_init_ansi(
&msgText, "Back to normal state from high limit");
} else {
ExceededLimit = CurrentAV->Low_Limit;
characterstring_init_ansi(&msgText,
"Back to normal state from low limit");
characterstring_init_ansi(
&msgText, "Back to normal state from low limit");
}
break;
@@ -1041,8 +1011,8 @@ void Analog_Value_Intrinsic_Reporting(
#if PRINT_ENABLED
fprintf(stderr, "Event_State for (%s,%d) goes from %s to %s.\n",
bactext_object_type_name(OBJECT_ANALOG_VALUE), object_instance,
bactext_event_state_name(FromState),
bactext_object_type_name(OBJECT_ANALOG_VALUE),
object_instance, bactext_event_state_name(FromState),
bactext_event_state_name(ToState));
#endif /* PRINT_ENABLED */
@@ -1054,7 +1024,6 @@ void Analog_Value_Intrinsic_Reporting(
}
}
if (SendNotify) {
/* Event Object Identifier */
event_data.eventObjectIdentifier.type = OBJECT_ANALOG_VALUE;
@@ -1110,18 +1079,20 @@ void Analog_Value_Intrinsic_Reporting(
event_data.notificationParams.outOfRange.exceedingValue =
PresentVal;
/* Status_Flags of the referenced object. */
bitstring_init(&event_data.notificationParams.outOfRange.
statusFlags);
bitstring_set_bit(&event_data.notificationParams.outOfRange.
statusFlags, STATUS_FLAG_IN_ALARM,
CurrentAV->Event_State ? true : false);
bitstring_set_bit(&event_data.notificationParams.outOfRange.
statusFlags, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&event_data.notificationParams.outOfRange.
statusFlags, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&event_data.notificationParams.outOfRange.
statusFlags, STATUS_FLAG_OUT_OF_SERVICE,
CurrentAV->Out_Of_Service);
bitstring_init(
&event_data.notificationParams.outOfRange.statusFlags);
bitstring_set_bit(
&event_data.notificationParams.outOfRange.statusFlags,
STATUS_FLAG_IN_ALARM, CurrentAV->Event_State ? true : false);
bitstring_set_bit(
&event_data.notificationParams.outOfRange.statusFlags,
STATUS_FLAG_FAULT, false);
bitstring_set_bit(
&event_data.notificationParams.outOfRange.statusFlags,
STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(
&event_data.notificationParams.outOfRange.statusFlags,
STATUS_FLAG_OUT_OF_SERVICE, CurrentAV->Out_Of_Service);
/* Deadband used for limit checking. */
event_data.notificationParams.outOfRange.deadband =
CurrentAV->Deadband;
@@ -1140,24 +1111,24 @@ void Analog_Value_Intrinsic_Reporting(
case EVENT_STATE_OFFNORMAL:
case EVENT_STATE_HIGH_LIMIT:
case EVENT_STATE_LOW_LIMIT:
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
bIsAcked = false;
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
Time_Stamp = event_data.timeStamp.value.dateTime;
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.bIsAcked = false;
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.Time_Stamp = event_data.timeStamp.value.dateTime;
break;
case EVENT_STATE_FAULT:
CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT].
bIsAcked = false;
CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT].
Time_Stamp = event_data.timeStamp.value.dateTime;
CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked =
false;
CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT]
.Time_Stamp = event_data.timeStamp.value.dateTime;
break;
case EVENT_STATE_NORMAL:
CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL].
bIsAcked = false;
CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL].
Time_Stamp = event_data.timeStamp.value.dateTime;
CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL]
.bIsAcked = false;
CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL]
.Time_Stamp = event_data.timeStamp.value.dateTime;
break;
}
}
@@ -1165,17 +1136,14 @@ void Analog_Value_Intrinsic_Reporting(
#endif /* defined(INTRINSIC_REPORTING) */
}
#if defined(INTRINSIC_REPORTING)
int Analog_Value_Event_Information(
unsigned index,
BACNET_GET_EVENT_INFORMATION_DATA * getevent_data)
unsigned index, BACNET_GET_EVENT_INFORMATION_DATA *getevent_data)
{
bool IsNotAckedTransitions;
bool IsActiveEvent;
int i;
/* check index */
if (index < MAX_ANALOG_VALUES) {
/* 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
(TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */
IsNotAckedTransitions =
(AV_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL].
bIsAcked ==
false) | (AV_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].
bIsAcked ==
false) | (AV_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].
bIsAcked == false);
(AV_Descr[index]
.Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.bIsAcked == false) |
(AV_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked ==
false) |
(AV_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked ==
false);
} else
return -1; /* end of list */
@@ -1204,13 +1173,14 @@ int Analog_Value_Event_Information(
bitstring_init(&getevent_data->acknowledgedTransitions);
bitstring_set_bit(&getevent_data->acknowledgedTransitions,
TRANSITION_TO_OFFNORMAL,
AV_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL].
bIsAcked);
bitstring_set_bit(&getevent_data->acknowledgedTransitions,
TRANSITION_TO_FAULT,
AV_Descr[index]
.Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.bIsAcked);
bitstring_set_bit(
&getevent_data->acknowledgedTransitions, TRANSITION_TO_FAULT,
AV_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
bitstring_set_bit(&getevent_data->acknowledgedTransitions,
TRANSITION_TO_NORMAL,
bitstring_set_bit(
&getevent_data->acknowledgedTransitions, TRANSITION_TO_NORMAL,
AV_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked);
/* Event Time Stamps */
for (i = 0; i < 3; i++) {
@@ -1222,15 +1192,18 @@ int Analog_Value_Event_Information(
getevent_data->notifyType = AV_Descr[index].Notify_Type;
/* Event Enable */
bitstring_init(&getevent_data->eventEnable);
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL,
(AV_Descr[index].
Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false);
bitstring_set_bit(
&getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL,
(AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true
: false);
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_FAULT,
(AV_Descr[index].
Event_Enable & EVENT_ENABLE_TO_FAULT) ? true : false);
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_NORMAL,
(AV_Descr[index].
Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false);
(AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_FAULT)
? true
: false);
bitstring_set_bit(
&getevent_data->eventEnable, TRANSITION_TO_NORMAL,
(AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true
: false);
/* Event Priorities */
Notification_Class_Get_Priorities(AV_Descr[index].Notification_Class,
getevent_data->eventPriorities);
@@ -1240,17 +1213,14 @@ int Analog_Value_Event_Information(
return 0; /* no active event at this index */
}
int Analog_Value_Alarm_Ack(
BACNET_ALARM_ACK_DATA * alarmack_data,
BACNET_ERROR_CODE * error_code)
int Analog_Value_Alarm_Ack(BACNET_ALARM_ACK_DATA *alarmack_data,
BACNET_ERROR_CODE *error_code)
{
ANALOG_VALUE_DESCR *CurrentAV;
unsigned int object_index;
object_index =
Analog_Value_Instance_To_Index(alarmack_data->eventObjectIdentifier.
instance);
object_index = Analog_Value_Instance_To_Index(
alarmack_data->eventObjectIdentifier.instance);
if (object_index < MAX_ANALOG_VALUES)
CurrentAV = &AV_Descr[object_index];
@@ -1263,22 +1233,23 @@ int Analog_Value_Alarm_Ack(
case EVENT_STATE_OFFNORMAL:
case EVENT_STATE_HIGH_LIMIT:
case EVENT_STATE_LOW_LIMIT:
if (CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
bIsAcked == false) {
if (CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.bIsAcked == false) {
if (alarmack_data->eventTimeStamp.tag != TIME_STAMP_DATETIME) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1;
}
if (datetime_compare(&CurrentAV->
Acked_Transitions[TRANSITION_TO_OFFNORMAL].Time_Stamp,
if (datetime_compare(
&CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.Time_Stamp,
&alarmack_data->eventTimeStamp.value.dateTime) > 0) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1;
}
/* Clean transitions flag. */
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
bIsAcked = true;
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked =
true;
} else {
*error_code = ERROR_CODE_INVALID_EVENT_STATE;
return -1;
@@ -1292,8 +1263,9 @@ int Analog_Value_Alarm_Ack(
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1;
}
if (datetime_compare(&CurrentAV->
Acked_Transitions[TRANSITION_TO_NORMAL].Time_Stamp,
if (datetime_compare(
&CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL]
.Time_Stamp,
&alarmack_data->eventTimeStamp.value.dateTime) > 0) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1;
@@ -1315,8 +1287,9 @@ int Analog_Value_Alarm_Ack(
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1;
}
if (datetime_compare(&CurrentAV->
Acked_Transitions[TRANSITION_TO_FAULT].Time_Stamp,
if (datetime_compare(
&CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT]
.Time_Stamp,
&alarmack_data->eventTimeStamp.value.dateTime) > 0) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1;
@@ -1343,11 +1316,9 @@ int Analog_Value_Alarm_Ack(
return 1;
}
int Analog_Value_Alarm_Summary(
unsigned index,
BACNET_GET_ALARM_SUMMARY_DATA * getalarm_data)
int Analog_Value_Alarm_Summary(unsigned index,
BACNET_GET_ALARM_SUMMARY_DATA *getalarm_data)
{
/* check index */
if (index < MAX_ANALOG_VALUES) {
/* Event_State is not equal to NORMAL and
@@ -1364,16 +1335,19 @@ int Analog_Value_Alarm_Summary(
bitstring_init(&getalarm_data->acknowledgedTransitions);
bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
TRANSITION_TO_OFFNORMAL,
AV_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL].
bIsAcked);
AV_Descr[index]
.Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.bIsAcked);
bitstring_set_bit(&getalarm_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(&getalarm_data->acknowledgedTransitions,
TRANSITION_TO_NORMAL,
AV_Descr[index].
Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked);
AV_Descr[index]
.Acked_Transitions[TRANSITION_TO_NORMAL]
.bIsAcked);
return 1; /* active alarm */
} else
@@ -1383,17 +1357,14 @@ int Analog_Value_Alarm_Summary(
}
#endif /* defined(INTRINSIC_REPORTING) */
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -1403,11 +1374,10 @@ bool WPValidateArgType(
return false;
}
void testAnalog_Value(
Test * pTest)
void testAnalog_Value(Test *pTest)
{
BACNET_READ_PROPERTY_DATA rpdata;
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -1433,8 +1403,7 @@ void testAnalog_Value(
}
#ifdef TEST_ANALOG_VALUE
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -1446,7 +1415,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+80 -111
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -61,8 +61,7 @@ static BACNET_FILE_LISTING BACnet_File_Listing[] = {
};
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int bacfile_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
static const int bacfile_Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_FILE_TYPE,
@@ -71,21 +70,13 @@ static const int bacfile_Properties_Required[] = {
PROP_ARCHIVE,
PROP_READ_ONLY,
PROP_FILE_ACCESS_METHOD,
-1
};
-1};
static const int bacfile_Properties_Optional[] = {
PROP_DESCRIPTION,
-1
};
static const int bacfile_Properties_Optional[] = {PROP_DESCRIPTION, -1};
static const int bacfile_Properties_Proprietary[] = {
-1
};
static const int bacfile_Properties_Proprietary[] = {-1};
void BACfile_Property_Lists(
const int **pRequired,
const int **pOptional,
void BACfile_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -98,8 +89,7 @@ void BACfile_Property_Lists(
return;
}
static char *bacfile_name(
uint32_t instance)
static char *bacfile_name(uint32_t instance)
{
uint32_t index = 0;
char *filename = NULL;
@@ -116,9 +106,8 @@ static char *bacfile_name(
return filename;
}
bool bacfile_object_name(
uint32_t instance,
BACNET_CHARACTER_STRING * object_name)
bool bacfile_object_name(uint32_t instance,
BACNET_CHARACTER_STRING *object_name)
{
bool status = false;
char *filename = NULL;
@@ -131,14 +120,12 @@ bool bacfile_object_name(
return status;
}
bool bacfile_valid_instance(
uint32_t object_instance)
bool bacfile_valid_instance(uint32_t object_instance)
{
return bacfile_name(object_instance) ? true : false;
}
uint32_t bacfile_count(
void)
uint32_t bacfile_count(void)
{
uint32_t index = 0;
@@ -150,8 +137,7 @@ uint32_t bacfile_count(
return index;
}
uint32_t bacfile_index_to_instance(
unsigned find_index)
uint32_t bacfile_index_to_instance(unsigned find_index)
{
uint32_t instance = BACNET_MAX_INSTANCE + 1;
uint32_t index = 0;
@@ -168,8 +154,7 @@ uint32_t bacfile_index_to_instance(
return instance;
}
static long fsize(
FILE * pFile)
static long fsize(FILE *pFile)
{
long size = 0;
long origin = 0;
@@ -183,8 +168,7 @@ static long fsize(
return (size);
}
unsigned bacfile_file_size(
uint32_t object_instance)
unsigned bacfile_file_size(uint32_t object_instance)
{
char *pFilename = NULL;
FILE *pFile = NULL;
@@ -203,11 +187,10 @@ unsigned bacfile_file_size(
}
/* return the number of bytes used, or -1 on error */
int bacfile_read_property(
BACNET_READ_PROPERTY_DATA * rpdata)
int bacfile_read_property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
char text_string[32] = { "" };
char text_string[32] = {""};
BACNET_CHARACTER_STRING char_string;
BACNET_DATE bdate;
BACNET_TIME btime;
@@ -220,13 +203,12 @@ int bacfile_read_property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_FILE,
apdu_len = encode_application_object_id(&apdu[0], OBJECT_FILE,
rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
sprintf(text_string, "FILE %lu",
(unsigned long) rpdata->object_instance);
(unsigned long)rpdata->object_instance);
characterstring_init_ansi(&char_string, text_string);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
@@ -246,9 +228,8 @@ int bacfile_read_property(
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_FILE_SIZE:
apdu_len =
encode_application_unsigned(&apdu[0],
bacfile_file_size(rpdata->object_instance));
apdu_len = encode_application_unsigned(
&apdu[0], bacfile_file_size(rpdata->object_instance));
break;
case PROP_MODIFICATION_DATE:
/* 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);
break;
case PROP_FILE_ACCESS_METHOD:
apdu_len =
encode_application_enumerated(&apdu[0],
FILE_RECORD_AND_STREAM_ACCESS);
apdu_len = encode_application_enumerated(
&apdu[0], FILE_RECORD_AND_STREAM_ACCESS);
break;
default:
rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -295,8 +275,7 @@ int bacfile_read_property(
}
/* returns true if successful */
bool bacfile_write_property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
@@ -314,8 +293,7 @@ bool bacfile_write_property(
return false;
}
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
if (len < 0) {
/* error while decoding - a value larger than we can handle */
@@ -375,8 +353,7 @@ bool bacfile_write_property(
return status;
}
uint32_t bacfile_instance(
char *filename)
uint32_t bacfile_instance(char *filename)
{
uint32_t index = 0;
uint32_t instance = BACNET_MAX_INSTANCE + 1;
@@ -399,35 +376,32 @@ uint32_t bacfile_instance(
/* Another way would be to store the */
/* invokeID and file instance in a list or table */
/* when the request was sent */
uint32_t bacfile_instance_from_tsm(
uint8_t invokeID)
uint32_t bacfile_instance_from_tsm(uint8_t invokeID)
{
BACNET_NPDU_DATA npdu_data = { 0 }; /* dummy for getting npdu length */
BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 };
BACNET_NPDU_DATA npdu_data = {0}; /* dummy for getting npdu length */
BACNET_CONFIRMED_SERVICE_DATA service_data = {0};
uint8_t service_choice = 0;
uint8_t *service_request = NULL;
uint16_t service_request_len = 0;
BACNET_ADDRESS dest; /* where the original packet was destined */
uint8_t apdu[MAX_PDU] = { 0 }; /* original APDU packet */
uint8_t apdu[MAX_PDU] = {0}; /* original APDU packet */
uint16_t apdu_len = 0; /* original APDU packet length */
int len = 0; /* apdu header length */
BACNET_ATOMIC_READ_FILE_DATA data = { 0 };
BACNET_ATOMIC_READ_FILE_DATA data = {0};
uint32_t object_instance = BACNET_MAX_INSTANCE + 1; /* return value */
bool found = false;
found =
tsm_get_transaction_pdu(invokeID, &dest, &npdu_data, &apdu[0],
found = tsm_get_transaction_pdu(invokeID, &dest, &npdu_data, &apdu[0],
&apdu_len);
if (found) {
if (!npdu_data.network_layer_message && npdu_data.data_expecting_reply
&& (apdu[0] == PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) {
len =
apdu_decode_confirmed_service_request(&apdu[0], apdu_len,
&service_data, &service_choice, &service_request,
&service_request_len);
if (!npdu_data.network_layer_message &&
npdu_data.data_expecting_reply &&
(apdu[0] == PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) {
len = apdu_decode_confirmed_service_request(
&apdu[0], apdu_len, &service_data, &service_choice,
&service_request, &service_request_len);
if (service_choice == SERVICE_CONFIRMED_ATOMIC_READ_FILE) {
len =
arf_decode_service_request(service_request,
len = arf_decode_service_request(service_request,
service_request_len, &data);
if (len > 0) {
if (data.object_type == OBJECT_FILE)
@@ -441,8 +415,7 @@ uint32_t bacfile_instance_from_tsm(
}
#endif
bool bacfile_read_stream_data(
BACNET_ATOMIC_READ_FILE_DATA * data)
bool bacfile_read_stream_data(BACNET_ATOMIC_READ_FILE_DATA *data)
{
char *pFilename = NULL;
bool found = false;
@@ -454,9 +427,8 @@ bool bacfile_read_stream_data(
found = true;
pFile = fopen(pFilename, "rb");
if (pFile) {
(void) fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET);
len =
fread(octetstring_value(&data->fileData[0]), 1,
(void)fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET);
len = fread(octetstring_value(&data->fileData[0]), 1,
data->type.stream.requestedOctetCount, pFile);
if (len < data->type.stream.requestedOctetCount)
data->endOfFile = true;
@@ -476,8 +448,7 @@ bool bacfile_read_stream_data(
return found;
}
bool bacfile_write_stream_data(
BACNET_ATOMIC_WRITE_FILE_DATA * data)
bool bacfile_write_stream_data(BACNET_ATOMIC_WRITE_FILE_DATA *data)
{
char *pFilename = NULL;
bool found = false;
@@ -500,7 +471,7 @@ bool bacfile_write_stream_data(
}
if (pFile) {
if (data->type.stream.fileStartPosition != -1) {
(void) fseek(pFile, data->type.stream.fileStartPosition,
(void)fseek(pFile, data->type.stream.fileStartPosition,
SEEK_SET);
}
if (fwrite(octetstring_value(&data->fileData[0]),
@@ -514,8 +485,7 @@ bool bacfile_write_stream_data(
return found;
}
bool bacfile_write_record_data(
BACNET_ATOMIC_WRITE_FILE_DATA * data)
bool bacfile_write_record_data(BACNET_ATOMIC_WRITE_FILE_DATA *data)
{
char *pFilename = NULL;
bool found = false;
@@ -542,7 +512,8 @@ bool bacfile_write_record_data(
if (pFile) {
if ((data->type.record.fileStartRecord != -1) &&
(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);
if ((pData == NULL) || feof(pFile)) {
break;
@@ -563,9 +534,8 @@ bool bacfile_write_record_data(
return found;
}
bool bacfile_read_ack_stream_data(
uint32_t instance,
BACNET_ATOMIC_READ_FILE_DATA * data)
bool bacfile_read_ack_stream_data(uint32_t instance,
BACNET_ATOMIC_READ_FILE_DATA *data)
{
bool found = false;
FILE *pFile = NULL;
@@ -576,12 +546,12 @@ bool bacfile_read_ack_stream_data(
found = true;
pFile = fopen(pFilename, "rb");
if (pFile) {
(void) fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET);
(void)fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET);
if (fwrite(octetstring_value(&data->fileData[0]),
octetstring_length(&data->fileData[0]), 1, pFile) != 1) {
#if PRINT_ENABLED
fprintf(stderr, "Failed to write to %s (%lu)!\n", pFilename,
(unsigned long) instance);
(unsigned long)instance);
#endif
}
fclose(pFile);
@@ -591,15 +561,14 @@ bool bacfile_read_ack_stream_data(
return found;
}
bool bacfile_read_ack_record_data(
uint32_t instance,
BACNET_ATOMIC_READ_FILE_DATA * data)
bool bacfile_read_ack_record_data(uint32_t instance,
BACNET_ATOMIC_READ_FILE_DATA *data)
{
bool found = false;
FILE *pFile = NULL;
char *pFilename = NULL;
uint32_t i = 0;
char dummy_data[MAX_OCTET_STRING_BYTES] = { 0 };
char dummy_data[MAX_OCTET_STRING_BYTES] = {0};
char *pData = NULL;
pFilename = bacfile_name(instance);
@@ -608,7 +577,8 @@ bool bacfile_read_ack_record_data(
pFile = fopen(pFilename, "rb");
if (pFile) {
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);
if ((pData == NULL) || feof(pFile)) {
break;
@@ -620,8 +590,8 @@ bool bacfile_read_ack_record_data(
octetstring_length(&data->fileData[i]), 1,
pFile) != 1) {
#if PRINT_ENABLED
fprintf(stderr, "Failed to write to %s (%lu)!\n",
pFilename, (unsigned long) instance);
fprintf(stderr, "Failed to write to %s (%lu)!\n", pFilename,
(unsigned long)instance);
#endif
}
}
@@ -632,7 +602,6 @@ bool bacfile_read_ack_record_data(
return found;
}
void bacfile_init(
void)
void bacfile_init(void)
{
}
+71 -109
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Binary Input Objects customize for your use */
@@ -54,29 +54,15 @@ static BACNET_POLARITY Polarity[MAX_BINARY_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Input_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_POLARITY,
-1
};
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE, PROP_POLARITY, -1};
static const int Binary_Input_Properties_Optional[] = {
PROP_DESCRIPTION,
-1
};
static const int Binary_Input_Properties_Optional[] = {PROP_DESCRIPTION, -1};
static const int Binary_Input_Properties_Proprietary[] = {
-1
};
static const int Binary_Input_Properties_Proprietary[] = {-1};
void Binary_Input_Property_Lists(
const int **pRequired,
const int **pOptional,
void Binary_Input_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired) {
@@ -95,8 +81,7 @@ void Binary_Input_Property_Lists(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Binary_Input_Valid_Instance(
uint32_t object_instance)
bool Binary_Input_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_BINARY_INPUTS) {
return true;
@@ -107,8 +92,7 @@ bool Binary_Input_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Binary_Input_Count(
void)
unsigned Binary_Input_Count(void)
{
return MAX_BINARY_INPUTS;
}
@@ -116,14 +100,12 @@ unsigned Binary_Input_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Binary_Input_Index_To_Instance(
unsigned index)
uint32_t Binary_Input_Index_To_Instance(unsigned index)
{
return index;
}
void Binary_Input_Init(
void)
void Binary_Input_Init(void)
{
static bool initialized = false;
unsigned i;
@@ -143,8 +125,7 @@ void Binary_Input_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Binary_Input_Instance_To_Index(
uint32_t object_instance)
unsigned Binary_Input_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_BINARY_INPUTS;
@@ -155,8 +136,7 @@ unsigned Binary_Input_Instance_To_Index(
return index;
}
BACNET_BINARY_PV Binary_Input_Present_Value(
uint32_t object_instance)
BACNET_BINARY_PV Binary_Input_Present_Value(uint32_t object_instance)
{
BACNET_BINARY_PV value = BINARY_INACTIVE;
unsigned index = 0;
@@ -176,8 +156,7 @@ BACNET_BINARY_PV Binary_Input_Present_Value(
return value;
}
bool Binary_Input_Out_Of_Service(
uint32_t object_instance)
bool Binary_Input_Out_Of_Service(uint32_t object_instance)
{
bool value = false;
unsigned index = 0;
@@ -190,8 +169,7 @@ bool Binary_Input_Out_Of_Service(
return value;
}
bool Binary_Input_Change_Of_Value(
uint32_t object_instance)
bool Binary_Input_Change_Of_Value(uint32_t object_instance)
{
bool status = false;
unsigned index;
@@ -204,8 +182,7 @@ bool Binary_Input_Change_Of_Value(
return status;
}
void Binary_Input_Change_Of_Value_Clear(
uint32_t object_instance)
void Binary_Input_Change_Of_Value_Clear(uint32_t object_instance)
{
unsigned index;
@@ -225,9 +202,8 @@ void Binary_Input_Change_Of_Value_Clear(
*
* @return true if the value list is encoded
*/
bool Binary_Input_Encode_Value_List(
uint32_t object_instance,
BACNET_PROPERTY_VALUE * value_list)
bool Binary_Input_Encode_Value_List(uint32_t object_instance,
BACNET_PROPERTY_VALUE *value_list)
{
bool status = false;
@@ -251,8 +227,8 @@ bool Binary_Input_Encode_Value_List(
bitstring_init(&value_list->value.type.Bit_String);
bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_FAULT, false);
bitstring_set_bit(&value_list->value.type.Bit_String, STATUS_FLAG_FAULT,
false);
bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_OVERRIDDEN, false);
if (Binary_Input_Out_Of_Service(object_instance)) {
@@ -270,8 +246,7 @@ bool Binary_Input_Encode_Value_List(
return status;
}
bool Binary_Input_Present_Value_Set(
uint32_t object_instance,
bool Binary_Input_Present_Value_Set(uint32_t object_instance,
BACNET_BINARY_PV value)
{
unsigned index = 0;
@@ -296,9 +271,7 @@ bool Binary_Input_Present_Value_Set(
return status;
}
void Binary_Input_Out_Of_Service_Set(
uint32_t object_instance,
bool value)
void Binary_Input_Out_Of_Service_Set(uint32_t object_instance, bool value)
{
unsigned index = 0;
@@ -313,9 +286,8 @@ void Binary_Input_Out_Of_Service_Set(
return;
}
bool Binary_Input_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Binary_Input_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
@@ -324,15 +296,14 @@ bool Binary_Input_Object_Name(
index = Binary_Input_Instance_To_Index(object_instance);
if (index < MAX_BINARY_INPUTS) {
sprintf(text_string, "BINARY INPUT %lu",
(unsigned long) object_instance);
(unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
return status;
}
BACNET_POLARITY Binary_Input_Polarity(
uint32_t object_instance)
BACNET_POLARITY Binary_Input_Polarity(uint32_t object_instance)
{
BACNET_POLARITY polarity = POLARITY_NORMAL;
unsigned index = 0;
@@ -345,8 +316,7 @@ BACNET_POLARITY Binary_Input_Polarity(
return polarity;
}
bool Binary_Input_Polarity_Set(
uint32_t object_instance,
bool Binary_Input_Polarity_Set(uint32_t object_instance,
BACNET_POLARITY polarity)
{
bool status = false;
@@ -362,8 +332,7 @@ bool Binary_Input_Polarity_Set(
/* return apdu length, or BACNET_STATUS_ERROR on error */
/* assumption - object already exists, and has been bounds checked */
int Binary_Input_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Binary_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
@@ -378,9 +347,8 @@ int Binary_Input_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_BINARY_INPUT, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
@@ -395,9 +363,8 @@ int Binary_Input_Read_Property(
break;
case PROP_PRESENT_VALUE:
/* note: you need to look up the actual value */
apdu_len =
encode_application_enumerated(&apdu[0],
Binary_Input_Present_Value(rpdata->object_instance));
apdu_len = encode_application_enumerated(
&apdu[0], Binary_Input_Present_Value(rpdata->object_instance));
break;
case PROP_STATUS_FLAGS:
/* 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);
break;
case PROP_POLARITY:
apdu_len =
encode_application_enumerated(&apdu[0],
Binary_Input_Polarity(rpdata->object_instance));
apdu_len = encode_application_enumerated(
&apdu[0], Binary_Input_Polarity(rpdata->object_instance));
break;
default:
rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -440,16 +406,14 @@ int Binary_Input_Read_Property(
}
/* returns true if successful */
bool Binary_Input_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Binary_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -471,8 +435,9 @@ bool Binary_Input_Write_Property(
&wp_data->error_class, &wp_data->error_code);
if (status) {
if (value.type.Enumerated <= MAX_BINARY_PV) {
Binary_Input_Present_Value_Set(wp_data->object_instance,
(BACNET_BINARY_PV) value.type.Enumerated);
Binary_Input_Present_Value_Set(
wp_data->object_instance,
(BACNET_BINARY_PV)value.type.Enumerated);
} else {
status = false;
wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -495,8 +460,9 @@ bool Binary_Input_Write_Property(
&wp_data->error_class, &wp_data->error_code);
if (status) {
if (value.type.Enumerated < MAX_POLARITY) {
Binary_Input_Polarity_Set(wp_data->object_instance,
(BACNET_POLARITY) value.type.Enumerated);
Binary_Input_Polarity_Set(
wp_data->object_instance,
(BACNET_POLARITY)value.type.Enumerated);
} else {
status = false;
wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -527,11 +493,9 @@ bool Binary_Input_Write_Property(
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -541,11 +505,10 @@ bool WPValidateArgType(
return false;
}
void testBinaryInput(
Test * pTest)
void testBinaryInput(Test *pTest)
{
BACNET_READ_PROPERTY_DATA rpdata;
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -571,8 +534,7 @@ void testBinaryInput(
}
#ifdef TEST_BINARY_INPUT
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -584,7 +546,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+76 -105
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Binary Output Objects - customize for your use */
@@ -46,15 +46,14 @@
/* the Relinquish Default value */
#define RELINQUISH_DEFAULT BINARY_INACTIVE
/* Here is our Priority Array.*/
static BACNET_BINARY_PV
Binary_Output_Level[MAX_BINARY_OUTPUTS][BACNET_MAX_PRIORITY];
static BACNET_BINARY_PV Binary_Output_Level[MAX_BINARY_OUTPUTS]
[BACNET_MAX_PRIORITY];
/* Writable out-of-service allows others to play with our Present Value */
/* without changing the physical output */
static bool Out_Of_Service[MAX_BINARY_OUTPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Output_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
static const int Binary_Output_Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
@@ -64,23 +63,14 @@ static const int Binary_Output_Properties_Required[] = {
PROP_POLARITY,
PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT,
-1
};
-1};
static const int Binary_Output_Properties_Optional[] = {
PROP_DESCRIPTION,
PROP_ACTIVE_TEXT,
PROP_INACTIVE_TEXT,
-1
};
PROP_DESCRIPTION, PROP_ACTIVE_TEXT, PROP_INACTIVE_TEXT, -1};
static const int Binary_Output_Properties_Proprietary[] = {
-1
};
static const int Binary_Output_Properties_Proprietary[] = {-1};
void Binary_Output_Property_Lists(
const int **pRequired,
const int **pOptional,
void Binary_Output_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -93,8 +83,7 @@ void Binary_Output_Property_Lists(
return;
}
void Binary_Output_Init(
void)
void Binary_Output_Init(void)
{
unsigned i, j;
static bool initialized = false;
@@ -116,8 +105,7 @@ void Binary_Output_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Binary_Output_Valid_Instance(
uint32_t object_instance)
bool Binary_Output_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_BINARY_OUTPUTS)
return true;
@@ -127,8 +115,7 @@ bool Binary_Output_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Binary_Output_Count(
void)
unsigned Binary_Output_Count(void)
{
return MAX_BINARY_OUTPUTS;
}
@@ -136,8 +123,7 @@ unsigned Binary_Output_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Binary_Output_Index_To_Instance(
unsigned index)
uint32_t Binary_Output_Index_To_Instance(unsigned index)
{
return index;
}
@@ -145,8 +131,7 @@ uint32_t Binary_Output_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Binary_Output_Instance_To_Index(
uint32_t object_instance)
unsigned Binary_Output_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_BINARY_OUTPUTS;
@@ -156,8 +141,7 @@ unsigned Binary_Output_Instance_To_Index(
return index;
}
BACNET_BINARY_PV Binary_Output_Present_Value(
uint32_t object_instance)
BACNET_BINARY_PV Binary_Output_Present_Value(uint32_t object_instance)
{
BACNET_BINARY_PV value = RELINQUISH_DEFAULT;
unsigned index = 0;
@@ -176,8 +160,7 @@ BACNET_BINARY_PV Binary_Output_Present_Value(
return value;
}
bool Binary_Output_Out_Of_Service(
uint32_t object_instance)
bool Binary_Output_Out_Of_Service(uint32_t object_instance)
{
bool value = false;
unsigned index = 0;
@@ -191,16 +174,15 @@ bool Binary_Output_Out_Of_Service(
}
/* note: the object name must be unique within this device */
bool Binary_Output_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Binary_Output_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
if (object_instance < MAX_BINARY_OUTPUTS) {
sprintf(text_string, "BINARY OUTPUT %lu",
(unsigned long) object_instance);
(unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
@@ -208,8 +190,7 @@ bool Binary_Output_Object_Name(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Binary_Output_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Binary_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
int apdu_len = 0; /* return value */
@@ -229,9 +210,8 @@ int Binary_Output_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_BINARY_OUTPUT,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_BINARY_OUTPUT, rpdata->object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
@@ -289,8 +269,7 @@ int Binary_Output_Read_Property(
len = encode_application_null(&apdu[apdu_len]);
else {
present_value = Binary_Output_Level[object_index][i];
len =
encode_application_enumerated(&apdu[apdu_len],
len = encode_application_enumerated(&apdu[apdu_len],
present_value);
}
/* add it if we have room */
@@ -311,11 +290,11 @@ int Binary_Output_Read_Property(
1] == BINARY_NULL)
apdu_len = encode_application_null(&apdu[apdu_len]);
else {
present_value = Binary_Output_Level[object_index]
present_value =
Binary_Output_Level[object_index]
[rpdata->array_index - 1];
apdu_len =
encode_application_enumerated(&apdu[apdu_len],
present_value);
apdu_len = encode_application_enumerated(
&apdu[apdu_len], present_value);
}
} else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -357,8 +336,7 @@ int Binary_Output_Read_Property(
}
/* returns true if successful */
bool Binary_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
unsigned int object_index = 0;
@@ -368,8 +346,7 @@ bool Binary_Output_Write_Property(
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -393,19 +370,19 @@ bool Binary_Output_Write_Property(
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(priority != 6 /* reserved */) &&
(value.type.Enumerated <= MAX_BINARY_PV)) {
level = (BACNET_BINARY_PV) value.type.Enumerated;
object_index =
Binary_Output_Instance_To_Index
(wp_data->object_instance);
level = (BACNET_BINARY_PV)value.type.Enumerated;
object_index = Binary_Output_Instance_To_Index(
wp_data->object_instance);
priority--;
Binary_Output_Level[object_index][priority] = level;
/* Note: you could set the physical output here if we
are the highest priority.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
main loop (i.e. check out of service before changing
output) */
status = true;
} else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
@@ -418,24 +395,24 @@ bool Binary_Output_Write_Property(
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class, &wp_data->error_code);
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class,
&wp_data->error_code);
if (status) {
level = BINARY_NULL;
object_index =
Binary_Output_Instance_To_Index
(wp_data->object_instance);
object_index = Binary_Output_Instance_To_Index(
wp_data->object_instance);
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Binary_Output_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
/* Note: you could set the physical output here to the
next highest priority, or to the relinquish default
if no priorities are set. However, if Out of Service
is TRUE, then don't set the physical output. This
comment may apply to the
main loop (i.e. check out of service before changing
output) */
} else {
status = false;
wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -451,8 +428,7 @@ bool Binary_Output_Write_Property(
if (status) {
object_index =
Binary_Output_Instance_To_Index(wp_data->object_instance);
Out_Of_Service[object_index] =
value.type.Boolean;
Out_Of_Service[object_index] = value.type.Boolean;
}
break;
case PROP_OBJECT_IDENTIFIER:
@@ -478,17 +454,14 @@ bool Binary_Output_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -498,10 +471,9 @@ bool WPValidateArgType(
return false;
}
void testBinaryOutput(
Test * pTest)
void testBinaryOutput(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -528,8 +500,7 @@ void testBinaryOutput(
}
#ifdef TEST_BINARY_OUTPUT
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -541,7 +512,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+79 -114
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Binary Output Objects - customize for your use */
@@ -46,38 +46,25 @@
/* the Relinquish Default value */
#define RELINQUISH_DEFAULT BINARY_INACTIVE
/* Here is our Priority Array.*/
static BACNET_BINARY_PV
Binary_Value_Level[MAX_BINARY_VALUES][BACNET_MAX_PRIORITY];
static BACNET_BINARY_PV Binary_Value_Level[MAX_BINARY_VALUES]
[BACNET_MAX_PRIORITY];
/* Writable out-of-service allows others to play with our Present Value */
/* without changing the physical output */
static bool Out_Of_Service[MAX_BINARY_VALUES];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Value_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
-1
};
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS, PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE, -1};
static const int Binary_Value_Properties_Optional[] = {
PROP_DESCRIPTION,
PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT,
-1
};
PROP_DESCRIPTION, PROP_PRIORITY_ARRAY, PROP_RELINQUISH_DEFAULT, -1};
static const int Binary_Value_Properties_Proprietary[] = {
-1
};
static const int Binary_Value_Properties_Proprietary[] = {-1};
void Binary_Value_Property_Lists(
const int **pRequired,
const int **pOptional,
void Binary_Value_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -90,8 +77,7 @@ void Binary_Value_Property_Lists(
return;
}
void Binary_Value_Init(
void)
void Binary_Value_Init(void)
{
unsigned i, j;
static bool initialized = false;
@@ -113,8 +99,7 @@ void Binary_Value_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Binary_Value_Valid_Instance(
uint32_t object_instance)
bool Binary_Value_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_BINARY_VALUES)
return true;
@@ -124,8 +109,7 @@ bool Binary_Value_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Binary_Value_Count(
void)
unsigned Binary_Value_Count(void)
{
return MAX_BINARY_VALUES;
}
@@ -133,8 +117,7 @@ unsigned Binary_Value_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Binary_Value_Index_To_Instance(
unsigned index)
uint32_t Binary_Value_Index_To_Instance(unsigned index)
{
return index;
}
@@ -142,8 +125,7 @@ uint32_t Binary_Value_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Binary_Value_Instance_To_Index(
uint32_t object_instance)
unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_BINARY_VALUES;
@@ -153,8 +135,7 @@ unsigned Binary_Value_Instance_To_Index(
return index;
}
BACNET_BINARY_PV Binary_Value_Present_Value(
uint32_t object_instance)
BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t object_instance)
{
BACNET_BINARY_PV value = RELINQUISH_DEFAULT;
unsigned index = 0;
@@ -174,24 +155,22 @@ BACNET_BINARY_PV Binary_Value_Present_Value(
}
/* note: the object name must be unique within this device */
bool Binary_Value_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Binary_Value_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
if (object_instance < MAX_BINARY_VALUES) {
sprintf(text_string, "BINARY VALUE %lu",
(unsigned long) object_instance);
(unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
return status;
}
bool Binary_Value_Out_Of_Service(
uint32_t instance)
bool Binary_Value_Out_Of_Service(uint32_t instance)
{
unsigned index = 0;
bool oos_flag = false;
@@ -204,9 +183,7 @@ bool Binary_Value_Out_Of_Service(
return oos_flag;
}
void Binary_Value_Out_Of_Service_Set(
uint32_t instance,
bool oos_flag)
void Binary_Value_Out_Of_Service_Set(uint32_t instance, bool oos_flag)
{
unsigned index = 0;
@@ -217,8 +194,7 @@ void Binary_Value_Out_Of_Service_Set(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Binary_Value_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Binary_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
int apdu_len = 0; /* return value */
@@ -237,9 +213,8 @@ int Binary_Value_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_BINARY_VALUE, rpdata->object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
@@ -254,8 +229,7 @@ int Binary_Value_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE);
break;
case PROP_PRESENT_VALUE:
present_value =
Binary_Value_Present_Value(rpdata->object_instance);
present_value = Binary_Value_Present_Value(rpdata->object_instance);
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
case PROP_STATUS_FLAGS:
@@ -293,8 +267,7 @@ int Binary_Value_Read_Property(
len = encode_application_null(&apdu[apdu_len]);
else {
present_value = Binary_Value_Level[object_index][i];
len =
encode_application_enumerated(&apdu[apdu_len],
len = encode_application_enumerated(&apdu[apdu_len],
present_value);
}
/* add it if we have room */
@@ -311,15 +284,14 @@ int Binary_Value_Read_Property(
object_index =
Binary_Value_Instance_To_Index(rpdata->object_instance);
if (rpdata->array_index <= BACNET_MAX_PRIORITY) {
if (Binary_Value_Level[object_index][rpdata->array_index]
== BINARY_NULL)
if (Binary_Value_Level[object_index][rpdata->array_index] ==
BINARY_NULL)
apdu_len = encode_application_null(&apdu[apdu_len]);
else {
present_value = Binary_Value_Level[object_index]
[rpdata->array_index];
apdu_len =
encode_application_enumerated(&apdu[apdu_len],
present_value);
apdu_len = encode_application_enumerated(
&apdu[apdu_len], present_value);
}
} else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -350,8 +322,7 @@ int Binary_Value_Read_Property(
}
/* returns true if successful */
bool Binary_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
unsigned int object_index = 0;
@@ -361,8 +332,7 @@ bool Binary_Value_Write_Property(
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -386,19 +356,19 @@ bool Binary_Value_Write_Property(
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(priority != 6 /* reserved */) &&
(value.type.Enumerated <= MAX_BINARY_PV)) {
level = (BACNET_BINARY_PV) value.type.Enumerated;
object_index =
Binary_Value_Instance_To_Index
(wp_data->object_instance);
level = (BACNET_BINARY_PV)value.type.Enumerated;
object_index = Binary_Value_Instance_To_Index(
wp_data->object_instance);
priority--;
Binary_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here if we
are the highest priority.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
main loop (i.e. check out of service before changing
output) */
status = true;
} else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
@@ -411,24 +381,24 @@ bool Binary_Value_Write_Property(
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class, &wp_data->error_code);
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class,
&wp_data->error_code);
if (status) {
level = BINARY_NULL;
object_index =
Binary_Value_Instance_To_Index
(wp_data->object_instance);
object_index = Binary_Value_Instance_To_Index(
wp_data->object_instance);
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Binary_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
/* Note: you could set the physical output here to the
next highest priority, or to the relinquish default
if no priorities are set. However, if Out of Service
is TRUE, then don't set the physical output. This
comment may apply to the
main loop (i.e. check out of service before changing
output) */
} else {
status = false;
wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -466,17 +436,14 @@ bool Binary_Value_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -486,10 +453,9 @@ bool WPValidateArgType(
return false;
}
void testBinary_Value(
Test * pTest)
void testBinary_Value(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -516,8 +482,7 @@ void testBinary_Value(
}
#ifdef TEST_BINARY_VALUE
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -529,7 +494,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+206 -263
View File
File diff suppressed because it is too large Load Diff
+98 -168
View File
@@ -54,51 +54,44 @@
#include "timestamp.h"
#include "command.h"
/*BACnetActionCommand ::= SEQUENCE {
deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
objectIdentifier [1] BACnetObjectIdentifier,
propertyIdentifier [2] BACnetPropertyIdentifier,
propertyArrayIndex [3] Unsigned OPTIONAL, --used only with array datatype
propertyValue [4] ABSTRACT-SYNTAX.&Type,
priority [5] Unsigned (1..16) OPTIONAL, --used only when property is commandable
postDelay [6] Unsigned OPTIONAL,
quitOnFailure [7] BOOLEAN,
writeSuccessful [8] BOOLEAN
}*/
/*BACnetActionCommand ::= SEQUENCE {
deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL,
objectIdentifier [1] BACnetObjectIdentifier,
propertyIdentifier [2] BACnetPropertyIdentifier,
propertyArrayIndex [3] Unsigned OPTIONAL, --used only with array datatype
propertyValue [4] ABSTRACT-SYNTAX.&Type,
priority [5] Unsigned (1..16) OPTIONAL, --used only when property is commandable
postDelay [6] Unsigned OPTIONAL,
quitOnFailure [7] 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 apdu_len = 0;
if (bcl->Device_Id.instance >= 0 &&
bcl->Device_Id.instance <= BACNET_MAX_INSTANCE) {
len =
encode_context_object_id(&apdu[apdu_len], 0, bcl->Device_Id.type,
len = encode_context_object_id(&apdu[apdu_len], 0, bcl->Device_Id.type,
bcl->Device_Id.instance);
if (len < 0)
return BACNET_STATUS_REJECT;
apdu_len += len;
}
/* TODO: Check for object type and instance limits */
len =
encode_context_object_id(&apdu[apdu_len], 1, bcl->Object_Id.type,
len = encode_context_object_id(&apdu[apdu_len], 1, bcl->Object_Id.type,
bcl->Object_Id.instance);
if (len < 0)
return BACNET_STATUS_REJECT;
apdu_len += len;
len =
encode_context_enumerated(&apdu[apdu_len], 2,
bcl->Property_Identifier);
encode_context_enumerated(&apdu[apdu_len], 2, bcl->Property_Identifier);
if (len < 0)
return BACNET_STATUS_REJECT;
apdu_len += len;
if (bcl->Property_Array_Index != BACNET_ARRAY_ALL) {
len =
encode_context_unsigned(&apdu[apdu_len], 3,
len = encode_context_unsigned(&apdu[apdu_len], 3,
bcl->Property_Array_Index);
if (len < 0)
return BACNET_STATUS_REJECT;
@@ -107,13 +100,12 @@ int cl_encode_apdu(
/* BACnet Testing Observed Incident oi00108
Command Action not correctly formatted
Revealed by BACnet Test Client v1.8.16 ( www.bac-test.com/bacnet-test-client-download )
BITS: BIT00031
BC 135.1: 9.20.1.7
BC 135.1: 9.20.1.9
Any discussions can be directed to edward@bac-test.com
Please feel free to remove this comment when my changes have been reviewed
by all interested parties. Say 6 months -> September 2016 */
Revealed by BACnet Test Client v1.8.16 (
www.bac-test.com/bacnet-test-client-download ) BITS: BIT00031 BC
135.1: 9.20.1.7 BC 135.1: 9.20.1.9 Any discussions can be directed to
edward@bac-test.com Please feel free to remove this comment when my
changes have been reviewed by all interested parties. Say 6 months ->
September 2016 */
len = encode_opening_tag(&apdu[apdu_len], 4);
if (len < 0)
@@ -128,7 +120,6 @@ int cl_encode_apdu(
return BACNET_STATUS_REJECT;
apdu_len += len;
if (bcl->Priority != BACNET_NO_PRIORITY) {
len = encode_context_unsigned(&apdu[apdu_len], 5, bcl->Priority);
if (len < 0)
@@ -153,11 +144,8 @@ int cl_encode_apdu(
return apdu_len;
}
int cl_decode_apdu(
uint8_t * apdu,
unsigned apdu_len,
BACNET_APPLICATION_TAG tag,
BACNET_ACTION_LIST * bcl)
int cl_decode_apdu(uint8_t *apdu, unsigned apdu_len, BACNET_APPLICATION_TAG tag,
BACNET_ACTION_LIST *bcl)
{
int len = 0;
int dec_len = 0;
@@ -167,8 +155,7 @@ int cl_decode_apdu(
if (decode_is_context_tag(&apdu[dec_len], 0)) {
/* Tag 0: Device ID */
dec_len++;
len =
decode_object_id(&apdu[dec_len], &bcl->Device_Id.type,
len = decode_object_id(&apdu[dec_len], &bcl->Device_Id.type,
&bcl->Device_Id.instance);
if (len < 0)
return BACNET_STATUS_REJECT;
@@ -176,33 +163,28 @@ int cl_decode_apdu(
}
if (!decode_is_context_tag(&apdu[dec_len++], 1))
return BACNET_STATUS_REJECT;
len =
decode_object_id(&apdu[dec_len], &bcl->Object_Id.type,
len = decode_object_id(&apdu[dec_len], &bcl->Object_Id.type,
&bcl->Object_Id.instance);
if (len < 0)
return BACNET_STATUS_REJECT;
dec_len += len;
len =
decode_tag_number_and_value(&apdu[dec_len], &tag_number,
len = decode_tag_number_and_value(&apdu[dec_len], &tag_number,
&len_value_type);
if (len < 0)
return BACNET_STATUS_REJECT;
dec_len += len;
if (tag_number != 2)
return BACNET_STATUS_REJECT;
len =
decode_enumerated(&apdu[dec_len], len_value_type,
len = decode_enumerated(&apdu[dec_len], len_value_type,
&bcl->Property_Identifier);
if (len < 0)
return BACNET_STATUS_REJECT;
dec_len += len;
if (decode_is_context_tag(&apdu[dec_len], 3)) {
len =
decode_tag_number_and_value(&apdu[dec_len], &tag_number,
len = decode_tag_number_and_value(&apdu[dec_len], &tag_number,
&len_value_type);
dec_len += len;
len =
decode_unsigned(&apdu[dec_len], len_value_type,
len = decode_unsigned(&apdu[dec_len], len_value_type,
&bcl->Property_Array_Index);
if (len < 0)
return BACNET_STATUS_REJECT;
@@ -220,67 +202,54 @@ int cl_decode_apdu(
len = 1;
break;
case BACNET_APPLICATION_TAG_BOOLEAN:
len =
decode_context_boolean2(&apdu[dec_len], 4,
len = decode_context_boolean2(&apdu[dec_len], 4,
&bcl->Value.type.Boolean);
break;
case BACNET_APPLICATION_TAG_UNSIGNED_INT:
len =
decode_context_unsigned(&apdu[dec_len], 4,
len = decode_context_unsigned(&apdu[dec_len], 4,
&bcl->Value.type.Unsigned_Int);
break;
case BACNET_APPLICATION_TAG_SIGNED_INT:
len =
decode_context_signed(&apdu[dec_len], 4,
len = decode_context_signed(&apdu[dec_len], 4,
&bcl->Value.type.Signed_Int);
break;
case BACNET_APPLICATION_TAG_REAL:
len =
decode_context_real(&apdu[dec_len], 4, &bcl->Value.type.Real);
len = decode_context_real(&apdu[dec_len], 4, &bcl->Value.type.Real);
break;
case BACNET_APPLICATION_TAG_DOUBLE:
len =
decode_context_double(&apdu[dec_len], 4,
len = decode_context_double(&apdu[dec_len], 4,
&bcl->Value.type.Double);
break;
case BACNET_APPLICATION_TAG_OCTET_STRING:
len =
decode_context_octet_string(&apdu[dec_len], 4,
len = decode_context_octet_string(&apdu[dec_len], 4,
&bcl->Value.type.Octet_String);
break;
case BACNET_APPLICATION_TAG_CHARACTER_STRING:
len =
decode_context_character_string(&apdu[dec_len], 4,
&bcl->Value.type.Character_String);
len = decode_context_character_string(
&apdu[dec_len], 4, &bcl->Value.type.Character_String);
break;
case BACNET_APPLICATION_TAG_BIT_STRING:
len =
decode_context_bitstring(&apdu[dec_len], 4,
len = decode_context_bitstring(&apdu[dec_len], 4,
&bcl->Value.type.Bit_String);
break;
case BACNET_APPLICATION_TAG_ENUMERATED:
len =
decode_context_enumerated(&apdu[dec_len], 4,
len = decode_context_enumerated(&apdu[dec_len], 4,
&bcl->Value.type.Enumerated);
break;
case BACNET_APPLICATION_TAG_DATE:
len =
decode_context_date(&apdu[dec_len], 4, &bcl->Value.type.Date);
len = decode_context_date(&apdu[dec_len], 4, &bcl->Value.type.Date);
break;
case BACNET_APPLICATION_TAG_TIME:
len =
decode_context_bacnet_time(&apdu[dec_len], 4,
len = decode_context_bacnet_time(&apdu[dec_len], 4,
&bcl->Value.type.Time);
break;
case BACNET_APPLICATION_TAG_OBJECT_ID:
len =
decode_context_object_id(&apdu[dec_len], 4,
len = decode_context_object_id(&apdu[dec_len], 4,
&bcl->Value.type.Object_Id.type,
&bcl->Value.type.Object_Id.instance);
break;
case BACNET_APPLICATION_TAG_LIGHTING_COMMAND:
len =
lighting_command_decode(&apdu[dec_len], apdu_len - dec_len,
len = lighting_command_decode(&apdu[dec_len], apdu_len - dec_len,
&bcl->Value.type.Lighting_Command);
break;
default:
@@ -291,25 +260,22 @@ int cl_decode_apdu(
dec_len += len;
if (decode_is_context_tag(&apdu[dec_len], 5)) {
uint32_t priority_dec;
len =
decode_tag_number_and_value(&apdu[dec_len], &tag_number,
len = decode_tag_number_and_value(&apdu[dec_len], &tag_number,
&len_value_type);
dec_len += len;
len = decode_unsigned(&apdu[dec_len], len_value_type, &priority_dec);
if (len < 0)
return BACNET_STATUS_REJECT;
bcl->Priority = (uint8_t) priority_dec;
bcl->Priority = (uint8_t)priority_dec;
dec_len += len;
} else {
bcl->Priority = BACNET_NO_PRIORITY;
}
if (decode_is_context_tag(&apdu[dec_len], 6)) {
len =
decode_tag_number_and_value(&apdu[dec_len], &tag_number,
len = decode_tag_number_and_value(&apdu[dec_len], &tag_number,
&len_value_type);
dec_len += len;
len =
decode_unsigned(&apdu[dec_len], len_value_type, &bcl->Post_Delay);
len = decode_unsigned(&apdu[dec_len], len_value_type, &bcl->Post_Delay);
if (len < 0)
return BACNET_STATUS_REJECT;
dec_len += len;
@@ -340,25 +306,18 @@ int cl_decode_apdu(
COMMAND_DESCR Command_Descr[MAX_COMMANDS];
/* These arrays are used by the ReadPropertyMultiple handler */
static const int Command_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
static const int Command_Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_IN_PROCESS,
PROP_ALL_WRITES_SUCCESSFUL,
PROP_ACTION,
-1
};
-1};
static const int Command_Properties_Optional[] = {
PROP_DESCRIPTION,
-1
};
static const int Command_Properties_Optional[] = {PROP_DESCRIPTION, -1};
static const int Command_Properties_Proprietary[] = {
-1
};
static const int Command_Properties_Proprietary[] = {-1};
/**
* 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
* BACnet proprietary properties for this object.
*/
void Command_Property_Lists(
const int **pRequired,
const int **pOptional,
void Command_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -386,12 +343,10 @@ void Command_Property_Lists(
return;
}
/**
* Initializes the Command object data
*/
void Command_Init(
void)
void Command_Init(void)
{
unsigned 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
*/
bool Command_Valid_Instance(
uint32_t object_instance)
bool Command_Valid_Instance(uint32_t object_instance)
{
unsigned int index;
@@ -425,8 +379,7 @@ bool Command_Valid_Instance(
*
* @return Number of objects
*/
unsigned Command_Count(
void)
unsigned Command_Count(void)
{
return MAX_COMMANDS;
}
@@ -439,8 +392,7 @@ unsigned Command_Count(
*
* @return object instance-number for the given index
*/
uint32_t Command_Index_To_Instance(
unsigned index)
uint32_t Command_Index_To_Instance(unsigned index)
{
return index;
}
@@ -454,8 +406,7 @@ uint32_t Command_Index_To_Instance(
* @return index for the given instance-number, or
* the total number of this object instances if not valid.
*/
unsigned Command_Instance_To_Index(
uint32_t object_instance)
unsigned Command_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_COMMANDS;
@@ -472,8 +423,7 @@ unsigned Command_Instance_To_Index(
*
* @return present-value of the object
*/
uint32_t Command_Present_Value(
uint32_t object_instance)
uint32_t Command_Present_Value(uint32_t object_instance)
{
uint32_t value = 0;
unsigned int index;
@@ -494,9 +444,7 @@ uint32_t Command_Present_Value(
*
* @return true if values are within range and present-value is set.
*/
bool Command_Present_Value_Set(
uint32_t object_instance,
uint32_t value)
bool Command_Present_Value_Set(uint32_t object_instance, uint32_t value)
{
bool status = false;
unsigned int index;
@@ -521,8 +469,7 @@ bool Command_Present_Value_Set(
*
* @return true if this object-instance is in-process.
*/
bool Command_In_Process(
uint32_t object_instance)
bool Command_In_Process(uint32_t object_instance)
{
bool value = false;
unsigned int index;
@@ -543,9 +490,7 @@ bool Command_In_Process(
*
* @return true if values are within range and in-process flag is set.
*/
bool Command_In_Process_Set(
uint32_t object_instance,
bool value)
bool Command_In_Process_Set(uint32_t object_instance, bool value)
{
bool status = false;
unsigned int index;
@@ -568,8 +513,7 @@ bool Command_In_Process_Set(
*
* @return true if all writes were successful for this object-instance
*/
bool Command_All_Writes_Successful(
uint32_t object_instance)
bool Command_All_Writes_Successful(uint32_t object_instance)
{
bool value = false;
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.
*/
bool Command_All_Writes_Successful_Set(
uint32_t object_instance,
bool value)
bool Command_All_Writes_Successful_Set(uint32_t object_instance, bool value)
{
bool status = false;
unsigned int index;
@@ -615,9 +557,8 @@ bool Command_All_Writes_Successful_Set(
*
* @return true if object-name was retrieved
*/
bool Command_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Command_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
unsigned int index;
@@ -625,7 +566,7 @@ bool Command_Object_Name(
index = Command_Instance_To_Index(object_instance);
if (index < MAX_COMMANDS) {
sprintf(text_string, "COMMAND %lu", (unsigned long) index);
sprintf(text_string, "COMMAND %lu", (unsigned long)index);
status = characterstring_init_ansi(object_name, text_string);
}
@@ -642,8 +583,7 @@ bool Command_Object_Name(
* @return number of APDU bytes in the response, or
* BACNET_STATUS_ERROR on error.
*/
int Command_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Command_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
int len = 0;
@@ -666,10 +606,9 @@ int Command_Read_Property(
}
apdu = rpdata->application_data;
switch ((int) rpdata->object_property) {
switch ((int)rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_COMMAND,
apdu_len = encode_application_object_id(&apdu[0], OBJECT_COMMAND,
rpdata->object_instance);
break;
@@ -685,24 +624,23 @@ int Command_Read_Property(
break;
case PROP_PRESENT_VALUE:
apdu_len =
encode_application_unsigned(&apdu[0],
Command_Present_Value(rpdata->object_instance));
apdu_len = encode_application_unsigned(
&apdu[0], Command_Present_Value(rpdata->object_instance));
break;
case PROP_IN_PROCESS:
apdu_len =
encode_application_boolean(&apdu[0],
Command_In_Process(rpdata->object_instance));
apdu_len = encode_application_boolean(
&apdu[0], Command_In_Process(rpdata->object_instance));
break;
case PROP_ALL_WRITES_SUCCESSFUL:
apdu_len =
encode_application_boolean(&apdu[0],
apdu_len = encode_application_boolean(
&apdu[0],
Command_All_Writes_Successful(rpdata->object_instance));
break;
case PROP_ACTION:
/* TODO */
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) {
int 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 */
for (; Curr_CL_Member != NULL;
Curr_CL_Member = Curr_CL_Member->next) {
len =
cl_encode_apdu(&apdu[apdu_len],
len = cl_encode_apdu(&apdu[apdu_len],
&CurrentCommand->Action[0]);
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) &&
(apdu_len + len) >= apdu_max) {
rpdata->error_code =
@@ -732,11 +670,11 @@ int Command_Read_Property(
/* another loop, for aditional actions in the list */
for (; Curr_CL_Member != NULL;
Curr_CL_Member = Curr_CL_Member->next) {
len =
cl_encode_apdu(&apdu[apdu_len],
len = cl_encode_apdu(&apdu[apdu_len],
&CurrentCommand->Action[0]);
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) {
rpdata->error_code =
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
@@ -758,8 +696,8 @@ int Command_Read_Property(
break;
}
/* only array properties can have array options */
if ((apdu_len >= 0) && (rpdata->object_property != PROP_ACTION)
&& (rpdata->array_index != BACNET_ARRAY_ALL)) {
if ((apdu_len >= 0) && (rpdata->object_property != PROP_ACTION) &&
(rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR;
@@ -777,16 +715,14 @@ int Command_Read_Property(
*
* @return false if an error is loaded, true if no errors
*/
bool Command_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Command_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
unsigned int object_index = 0;
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -807,7 +743,7 @@ bool Command_Write_Property(
return false;
}
switch ((int) wp_data->object_property) {
switch ((int)wp_data->object_property) {
case PROP_PRESENT_VALUE:
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT,
@@ -846,8 +782,7 @@ bool Command_Write_Property(
return status;
}
void Command_Intrinsic_Reporting(
uint32_t object_instance)
void Command_Intrinsic_Reporting(uint32_t object_instance)
{
}
@@ -856,11 +791,9 @@ void Command_Intrinsic_Reporting(
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
bool bResult;
@@ -878,10 +811,9 @@ bool WPValidateArgType(
return (bResult);
}
void testCommand(
Test * pTest)
void testCommand(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -926,8 +858,7 @@ void testCommand(
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.instance == clist_test.Object_Id.instance);
ct_test(pTest,
clist.Property_Identifier == clist_test.Property_Identifier);
ct_test(pTest, clist.Property_Identifier == clist_test.Property_Identifier);
ct_test(pTest,
clist.Property_Array_Index == clist_test.Property_Array_Index);
ct_test(pTest, clist.Value.tag == clist_test.Value.tag);
@@ -940,8 +871,7 @@ void testCommand(
}
#ifdef TEST_COMMAND
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -953,7 +883,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+85 -117
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2015 Nikola Jelic <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Credential Data Input Objects - customize for your use */
@@ -44,28 +44,17 @@ static CREDENTIAL_DATA_INPUT_DESCR cdi_descr[MAX_CREDENTIAL_DATA_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_RELIABILITY,
PROP_OUT_OF_SERVICE,
PROP_SUPPORTED_FORMATS,
PROP_UPDATE_TIME,
-1
};
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS, PROP_RELIABILITY,
PROP_OUT_OF_SERVICE, PROP_SUPPORTED_FORMATS,
PROP_UPDATE_TIME, -1};
static const int Properties_Optional[] = {
-1
};
static const int Properties_Optional[] = {-1};
static const int Properties_Proprietary[] = {
-1
};
static const int Properties_Proprietary[] = {-1};
void Credential_Data_Input_Property_Lists(
const int **pRequired,
void Credential_Data_Input_Property_Lists(const int **pRequired,
const int **pOptional,
const int **pProprietary)
{
@@ -79,8 +68,7 @@ void Credential_Data_Input_Property_Lists(
return;
}
void Credential_Data_Input_Init(
void)
void Credential_Data_Input_Init(void)
{
unsigned i;
@@ -107,8 +95,7 @@ void Credential_Data_Input_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Credential_Data_Input_Valid_Instance(
uint32_t object_instance)
bool Credential_Data_Input_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_CREDENTIAL_DATA_INPUTS)
return true;
@@ -118,8 +105,7 @@ bool Credential_Data_Input_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Credential_Data_Input_Count(
void)
unsigned Credential_Data_Input_Count(void)
{
return MAX_CREDENTIAL_DATA_INPUTS;
}
@@ -127,8 +113,7 @@ unsigned Credential_Data_Input_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Credential_Data_Input_Index_To_Instance(
unsigned index)
uint32_t Credential_Data_Input_Index_To_Instance(unsigned 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 */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Credential_Data_Input_Instance_To_Index(
uint32_t object_instance)
unsigned Credential_Data_Input_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_CREDENTIAL_DATA_INPUTS;
@@ -148,24 +132,22 @@ unsigned Credential_Data_Input_Instance_To_Index(
}
/* note: the object name must be unique within this device */
bool Credential_Data_Input_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Credential_Data_Input_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
if (object_instance < MAX_CREDENTIAL_DATA_INPUTS) {
sprintf(text_string, "CREDENTIAL DATA INPUT %lu",
(unsigned long) object_instance);
(unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
return status;
}
bool Credential_Data_Input_Out_Of_Service(
uint32_t instance)
bool Credential_Data_Input_Out_Of_Service(uint32_t instance)
{
unsigned index = 0;
bool oos_flag = false;
@@ -178,9 +160,7 @@ bool Credential_Data_Input_Out_Of_Service(
return oos_flag;
}
void Credential_Data_Input_Out_Of_Service_Set(
uint32_t instance,
bool oos_flag)
void Credential_Data_Input_Out_Of_Service_Set(uint32_t instance, bool oos_flag)
{
unsigned index = 0;
@@ -191,8 +171,7 @@ void Credential_Data_Input_Out_Of_Service_Set(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Credential_Data_Input_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Credential_Data_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
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);
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0],
OBJECT_CREDENTIAL_DATA_INPUT, rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_CREDENTIAL_DATA_INPUT,
rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
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);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0],
OBJECT_CREDENTIAL_DATA_INPUT);
apdu_len = encode_application_enumerated(
&apdu[0], OBJECT_CREDENTIAL_DATA_INPUT);
break;
case PROP_PRESENT_VALUE:
apdu_len =
bacapp_encode_authentication_factor(&apdu[apdu_len],
&cdi_descr[object_index].present_value);
apdu_len = bacapp_encode_authentication_factor(
&apdu[apdu_len], &cdi_descr[object_index].present_value);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
@@ -243,9 +220,8 @@ int Credential_Data_Input_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_RELIABILITY:
apdu_len =
encode_application_enumerated(&apdu[0],
cdi_descr[object_index].reliability);
apdu_len = encode_application_enumerated(
&apdu[0], cdi_descr[object_index].reliability);
break;
case PROP_OUT_OF_SERVICE:
state =
@@ -254,14 +230,13 @@ int Credential_Data_Input_Read_Property(
break;
case PROP_SUPPORTED_FORMATS:
if (rpdata->array_index == 0) {
apdu_len =
encode_application_unsigned(&apdu[0],
cdi_descr[object_index].supported_formats_count);
apdu_len = encode_application_unsigned(
&apdu[0], cdi_descr[object_index].supported_formats_count);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; i < cdi_descr[object_index].supported_formats_count;
i++) {
len =
bacapp_encode_authentication_factor_format(&apdu[0],
len = bacapp_encode_authentication_factor_format(
&apdu[0],
&cdi_descr[object_index].supported_formats[i]);
if (apdu_len + len < MAX_APDU)
apdu_len += len;
@@ -275,10 +250,10 @@ int Credential_Data_Input_Read_Property(
} else {
if (rpdata->array_index <=
cdi_descr[object_index].supported_formats_count) {
apdu_len =
bacapp_encode_authentication_factor_format(&apdu[0],
&cdi_descr[object_index].
supported_formats[rpdata->array_index - 1]);
apdu_len = bacapp_encode_authentication_factor_format(
&apdu[0],
&cdi_descr[object_index]
.supported_formats[rpdata->array_index - 1]);
} else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -288,9 +263,8 @@ int Credential_Data_Input_Read_Property(
break;
case PROP_UPDATE_TIME:
apdu_len =
bacapp_encode_timestamp(&apdu[0],
&cdi_descr[object_index].timestamp);
apdu_len = bacapp_encode_timestamp(
&apdu[0], &cdi_descr[object_index].timestamp);
break;
default:
rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -299,8 +273,9 @@ int Credential_Data_Input_Read_Property(
break;
}
/* only array properties can have array options */
if ((apdu_len >= 0) && (rpdata->object_property != PROP_SUPPORTED_FORMATS)
&& (rpdata->array_index != BACNET_ARRAY_ALL)) {
if ((apdu_len >= 0) &&
(rpdata->object_property != PROP_SUPPORTED_FORMATS) &&
(rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR;
@@ -310,8 +285,7 @@ int Credential_Data_Input_Read_Property(
}
/* returns true if successful */
bool Credential_Data_Input_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Credential_Data_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
@@ -319,8 +293,7 @@ bool Credential_Data_Input_Write_Property(
unsigned object_index = 0;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -336,14 +309,15 @@ bool Credential_Data_Input_Write_Property(
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
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) {
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;
len =
bacapp_decode_authentication_factor(wp_data->
application_data, &tmp);
len = bacapp_decode_authentication_factor(
wp_data->application_data, &tmp);
if (len > 0) {
memcpy(&cdi_descr[object_index].present_value, &tmp,
sizeof(BACNET_AUTHENTICATION_FACTOR));
@@ -357,14 +331,13 @@ bool Credential_Data_Input_Write_Property(
}
break;
case PROP_RELIABILITY:
if (Credential_Data_Input_Out_Of_Service(wp_data->object_instance)) {
status =
WPValidateArgType(&value,
BACNET_APPLICATION_TAG_ENUMERATED, &wp_data->error_class,
&wp_data->error_code);
if (Credential_Data_Input_Out_Of_Service(
wp_data->object_instance)) {
status = WPValidateArgType(
&value, BACNET_APPLICATION_TAG_ENUMERATED,
&wp_data->error_class, &wp_data->error_code);
if (status) {
cdi_descr[object_index].reliability =
value.type.Enumerated;
cdi_descr[object_index].reliability = value.type.Enumerated;
}
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -390,17 +363,14 @@ bool Credential_Data_Input_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -410,10 +380,9 @@ bool WPValidateArgType(
return false;
}
void testCredentialDataInput(
Test * pTest)
void testCredentialDataInput(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -440,8 +409,7 @@ void testCredentialDataInput(
}
#ifdef TEST_CREDENTIAL_DATA_INPUT
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -453,7 +421,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+71 -108
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* CharacterString Value Objects */
@@ -52,27 +52,15 @@ static char Object_Description[MAX_CHARACTERSTRING_VALUES][64];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
-1
};
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, -1};
static const int Properties_Optional[] = {
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_DESCRIPTION,
-1
};
static const int Properties_Optional[] = {PROP_EVENT_STATE, PROP_OUT_OF_SERVICE,
PROP_DESCRIPTION, -1};
static const int Properties_Proprietary[] = {
-1
};
static const int Properties_Proprietary[] = {-1};
void CharacterString_Value_Property_Lists(
const int **pRequired,
void CharacterString_Value_Property_Lists(const int **pRequired,
const int **pOptional,
const int **pProprietary)
{
@@ -86,15 +74,14 @@ void CharacterString_Value_Property_Lists(
return;
}
void CharacterString_Value_Init(
void)
void CharacterString_Value_Init(void)
{
unsigned i;
/* initialize all Present Values */
for (i = 0; i < MAX_CHARACTERSTRING_VALUES; i++) {
snprintf(&Object_Name[i][0], sizeof(Object_Name[i]),
"CHARACTER STRING VALUE %u", i+1);
"CHARACTER STRING VALUE %u", i + 1);
snprintf(&Object_Description[i][0], sizeof(Object_Description[i]),
"A Character String Value Example");
characterstring_init_ansi(&Present_Value[i], "");
@@ -106,8 +93,7 @@ void CharacterString_Value_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned CharacterString_Value_Instance_To_Index(
uint32_t object_instance)
unsigned CharacterString_Value_Instance_To_Index(uint32_t object_instance)
{
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 */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t CharacterString_Value_Index_To_Instance(
unsigned index)
uint32_t CharacterString_Value_Index_To_Instance(unsigned index)
{
return index;
}
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned CharacterString_Value_Count(
void)
unsigned CharacterString_Value_Count(void)
{
return MAX_CHARACTERSTRING_VALUES;
}
bool CharacterString_Value_Valid_Instance(
uint32_t object_instance)
bool CharacterString_Value_Valid_Instance(uint32_t object_instance)
{
unsigned index = 0; /* offset from instance lookup */
@@ -148,9 +131,8 @@ bool CharacterString_Value_Valid_Instance(
return false;
}
bool CharacterString_Value_Present_Value(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool CharacterString_Value_Present_Value(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
bool status = false;
unsigned index = 0; /* offset from instance lookup */
@@ -164,8 +146,7 @@ bool CharacterString_Value_Present_Value(
}
bool CharacterString_Value_Present_Value_Set(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
{
bool status = false;
unsigned index = 0; /* offset from instance lookup */
@@ -178,8 +159,7 @@ bool CharacterString_Value_Present_Value_Set(
return status;
}
bool CharacterString_Value_Out_Of_Service(
uint32_t object_instance)
bool CharacterString_Value_Out_Of_Service(uint32_t object_instance)
{
bool value = false;
unsigned index = 0;
@@ -192,8 +172,7 @@ bool CharacterString_Value_Out_Of_Service(
return value;
}
static void CharacterString_Value_Out_Of_Service_Set(
uint32_t object_instance,
static void CharacterString_Value_Out_Of_Service_Set(uint32_t object_instance,
bool value)
{
unsigned index = 0;
@@ -206,8 +185,7 @@ static void CharacterString_Value_Out_Of_Service_Set(
return;
}
static char *CharacterString_Value_Description(
uint32_t object_instance)
static char *CharacterString_Value_Description(uint32_t object_instance)
{
unsigned index = 0; /* offset from instance lookup */
char *pName = NULL; /* return value */
@@ -220,8 +198,7 @@ static char *CharacterString_Value_Description(
return pName;
}
bool CharacterString_Value_Description_Set(
uint32_t object_instance,
bool CharacterString_Value_Description_Set(uint32_t object_instance,
char *new_name)
{
unsigned index = 0; /* offset from instance lookup */
@@ -248,9 +225,8 @@ bool CharacterString_Value_Description_Set(
return status;
}
bool CharacterString_Value_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool CharacterString_Value_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
unsigned index = 0; /* offset from instance lookup */
bool status = false;
@@ -264,9 +240,7 @@ bool CharacterString_Value_Object_Name(
}
/* note: the object name must be unique within this device */
bool CharacterString_Value_Name_Set(
uint32_t object_instance,
char *new_name)
bool CharacterString_Value_Name_Set(uint32_t object_instance, char *new_name)
{
unsigned index = 0; /* offset from instance lookup */
size_t i = 0; /* loop counter */
@@ -294,8 +268,7 @@ bool CharacterString_Value_Name_Set(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int CharacterString_Value_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int CharacterString_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
@@ -311,9 +284,9 @@ int CharacterString_Value_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0],
OBJECT_CHARACTERSTRING_VALUE, rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_CHARACTERSTRING_VALUE,
rpdata->object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
@@ -324,15 +297,15 @@ int CharacterString_Value_Read_Property(
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
characterstring_init_ansi(
&char_string,
CharacterString_Value_Description(rpdata->object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0],
OBJECT_CHARACTERSTRING_VALUE);
apdu_len = encode_application_enumerated(
&apdu[0], OBJECT_CHARACTERSTRING_VALUE);
break;
case PROP_PRESENT_VALUE:
CharacterString_Value_Present_Value(rpdata->object_instance,
@@ -361,9 +334,8 @@ int CharacterString_Value_Read_Property(
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index =
CharacterString_Value_Instance_To_Index
(rpdata->object_instance);
object_index = CharacterString_Value_Instance_To_Index(
rpdata->object_instance);
state = Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
@@ -385,16 +357,14 @@ int CharacterString_Value_Read_Property(
}
/* returns true if successful */
bool CharacterString_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool CharacterString_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -405,14 +375,12 @@ bool CharacterString_Value_Write_Property(
}
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
status =
WPValidateArgType(&value,
BACNET_APPLICATION_TAG_CHARACTER_STRING, &wp_data->error_class,
&wp_data->error_code);
status = WPValidateArgType(
&value, BACNET_APPLICATION_TAG_CHARACTER_STRING,
&wp_data->error_class, &wp_data->error_code);
if (status) {
status =
CharacterString_Value_Present_Value_Set
(wp_data->object_instance, &value.type.Character_String);
status = CharacterString_Value_Present_Value_Set(
wp_data->object_instance, &value.type.Character_String);
if (!status) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
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,
&wp_data->error_class, &wp_data->error_code);
if (status) {
CharacterString_Value_Out_Of_Service_Set
(wp_data->object_instance, value.type.Boolean);
CharacterString_Value_Out_Of_Service_Set(
wp_data->object_instance, value.type.Boolean);
}
break;
case PROP_OBJECT_IDENTIFIER:
@@ -446,17 +414,14 @@ bool CharacterString_Value_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -466,10 +431,9 @@ bool WPValidateArgType(
return false;
}
void testCharacterStringValue(
Test * pTest)
void testCharacterStringValue(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -496,8 +460,7 @@ void testCharacterStringValue(
}
#ifdef TEST_CHARACTERSTRING_VALUE
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -509,7 +472,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+129 -206
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/** @file device-client.c Lightweight base "class" for handling all
* BACnet objects belonging to a BACnet device, as well as
@@ -112,68 +112,40 @@ static uint32_t Database_Revision = 0;
/* Profile_Name */
/* local forward (semi-private) and external prototypes */
int Device_Read_Property_Local(
BACNET_READ_PROPERTY_DATA * rpdata);
extern int Routed_Device_Read_Property_Local(
BACNET_READ_PROPERTY_DATA * rpdata);
int 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(
BACNET_WRITE_PROPERTY_DATA * wp_data);
BACNET_WRITE_PROPERTY_DATA *wp_data);
/* All included BACnet objects */
static object_functions_t Object_Table[] = {
{OBJECT_DEVICE,
NULL /* Init - don't init Device or it will recourse! */ ,
Device_Count,
Device_Index_To_Instance,
Device_Valid_Object_Instance_Number,
Device_Object_Name,
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 */ },
{OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */,
Device_Count, Device_Index_To_Instance,
Device_Valid_Object_Instance_Number, Device_Object_Name,
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 */},
#if (BACNET_PROTOCOL_REVISION >= 17)
{OBJECT_NETWORK_PORT,
Network_Port_Init,
Network_Port_Count,
Network_Port_Index_To_Instance,
Network_Port_Valid_Instance,
Network_Port_Object_Name,
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 */ },
{OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count,
Network_Port_Index_To_Instance, Network_Port_Valid_Instance,
Network_Port_Object_Name, 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
{MAX_BACNET_OBJECT_TYPE,
NULL /* Init */ ,
NULL /* Count */ ,
NULL /* Index_To_Instance */ ,
NULL /* Valid_Instance */ ,
NULL /* Object_Name */ ,
NULL /* Read_Property */ ,
NULL /* Write_Property */ ,
NULL /* Property_Lists */ ,
NULL /* ReadRangeInfo */ ,
NULL /* Iterator */ ,
NULL /* Value_Lists */ ,
NULL /* COV */ ,
NULL /* COV Clear */ ,
NULL /* Intrinsic Reporting */ }
};
{MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */,
NULL /* Index_To_Instance */, NULL /* Valid_Instance */,
NULL /* Object_Name */, 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,
* lookup which Object type needs to be invoked.
* @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
* type of Object.
*/
@@ -195,14 +167,12 @@ static struct object_functions *Device_Objects_Find_Functions(
return (NULL);
}
unsigned Device_Count(
void)
unsigned Device_Count(void)
{
return 1;
}
uint32_t Device_Index_To_Instance(
unsigned index)
uint32_t Device_Index_To_Instance(unsigned index)
{
index = index;
return Object_Instance_Number;
@@ -216,8 +186,7 @@ uint32_t Device_Index_To_Instance(
* @ingroup ObjIntf
* @return The Instance number used in the BACNET_OBJECT_ID for the Device.
*/
uint32_t Device_Object_Instance_Number(
void)
uint32_t Device_Object_Instance_Number(void)
{
#ifdef BAC_ROUTING
return Routed_Device_Object_Instance_Number();
@@ -226,8 +195,7 @@ uint32_t Device_Object_Instance_Number(
#endif
}
bool Device_Set_Object_Instance_Number(
uint32_t object_id)
bool Device_Set_Object_Instance_Number(uint32_t object_id)
{
bool status = true; /* return value */
@@ -241,15 +209,13 @@ bool Device_Set_Object_Instance_Number(
return status;
}
bool Device_Valid_Object_Instance_Number(
uint32_t object_id)
bool Device_Valid_Object_Instance_Number(uint32_t object_id)
{
return (Object_Instance_Number == object_id);
}
bool Device_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Device_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
bool status = false;
@@ -260,8 +226,7 @@ bool Device_Object_Name(
return status;
}
bool Device_Set_Object_Name(
BACNET_CHARACTER_STRING * object_name)
bool Device_Set_Object_Name(BACNET_CHARACTER_STRING *object_name)
{
bool status = false; /*return value */
@@ -274,15 +239,12 @@ bool Device_Set_Object_Name(
return status;
}
BACNET_DEVICE_STATUS Device_System_Status(
void)
BACNET_DEVICE_STATUS Device_System_Status(void)
{
return System_Status;
}
int Device_Set_System_Status(
BACNET_DEVICE_STATUS status,
bool local)
int Device_Set_System_Status(BACNET_DEVICE_STATUS status, bool local)
{
int result = 0; /*return value - 0 = ok, -1 = bad value, -2 = not allowed */
@@ -345,37 +307,32 @@ int Device_Set_System_Status(
return (result);
}
const char *Device_Vendor_Name(
void)
const char *Device_Vendor_Name(void)
{
return Vendor_Name;
}
/** 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.
*/
uint16_t Device_Vendor_Identifier(
void)
uint16_t Device_Vendor_Identifier(void)
{
return Vendor_Identifier;
}
void Device_Set_Vendor_Identifier(
uint16_t vendor_id)
void Device_Set_Vendor_Identifier(uint16_t vendor_id)
{
Vendor_Identifier = vendor_id;
}
const char *Device_Model_Name(
void)
const char *Device_Model_Name(void)
{
return Model_Name;
}
bool Device_Set_Model_Name(
const char *name,
size_t length)
bool Device_Set_Model_Name(const char *name, size_t length)
{
bool status = false; /*return value */
@@ -388,21 +345,17 @@ bool Device_Set_Model_Name(
return status;
}
const char *Device_Firmware_Revision(
void)
const char *Device_Firmware_Revision(void)
{
return BACnet_Version;
}
const char *Device_Application_Software_Version(
void)
const char *Device_Application_Software_Version(void)
{
return Application_Software_Version;
}
bool Device_Set_Application_Software_Version(
const char *name,
size_t length)
bool Device_Set_Application_Software_Version(const char *name, size_t length)
{
bool status = false; /*return value */
@@ -415,15 +368,12 @@ bool Device_Set_Application_Software_Version(
return status;
}
const char *Device_Description(
void)
const char *Device_Description(void)
{
return Description;
}
bool Device_Set_Description(
const char *name,
size_t length)
bool Device_Set_Description(const char *name, size_t length)
{
bool status = false; /*return value */
@@ -436,15 +386,12 @@ bool Device_Set_Description(
return status;
}
const char *Device_Location(
void)
const char *Device_Location(void)
{
return Location;
}
bool Device_Set_Location(
const char *name,
size_t length)
bool Device_Set_Location(const char *name, size_t length)
{
bool status = false; /*return value */
@@ -457,32 +404,27 @@ bool Device_Set_Location(
return status;
}
uint8_t Device_Protocol_Version(
void)
uint8_t Device_Protocol_Version(void)
{
return BACNET_PROTOCOL_VERSION;
}
uint8_t Device_Protocol_Revision(
void)
uint8_t Device_Protocol_Revision(void)
{
return BACNET_PROTOCOL_REVISION;
}
BACNET_SEGMENTATION Device_Segmentation_Supported(
void)
BACNET_SEGMENTATION Device_Segmentation_Supported(void)
{
return SEGMENTATION_NONE;
}
uint32_t Device_Database_Revision(
void)
uint32_t Device_Database_Revision(void)
{
return Database_Revision;
}
void Device_Set_Database_Revision(
uint32_t revision)
void Device_Set_Database_Revision(uint32_t revision)
{
Database_Revision = revision;
}
@@ -492,8 +434,7 @@ void Device_Set_Database_Revision(
* the most common operation if changing object names and ids is
* implemented.
*/
void Device_Inc_Database_Revision(
void)
void Device_Inc_Database_Revision(void)
{
Database_Revision++;
}
@@ -503,8 +444,7 @@ void Device_Inc_Database_Revision(
* for discovery, it must be consistent!
* @return The count of objects, for all supported Object types.
*/
unsigned Device_Object_List_Count(
void)
unsigned Device_Object_List_Count(void)
{
unsigned count = 0; /* number of objects */
struct object_functions *pObject = NULL;
@@ -531,10 +471,8 @@ unsigned Device_Object_List_Count(
* @param instance [out] The object's instance number, if found.
* @return True if found, else false.
*/
bool Device_Object_List_Identifier(
uint32_t array_index,
int *object_type,
uint32_t * instance)
bool Device_Object_List_Identifier(uint32_t array_index, int *object_type,
uint32_t *instance)
{
bool status = false;
unsigned count = 0;
@@ -558,19 +496,19 @@ bool Device_Object_List_Identifier(
* look for the index to instance to get the ID */
if (pObject->Object_Iterator) {
/* First find the first object */
temp_index = pObject->Object_Iterator(~(unsigned) 0);
temp_index = pObject->Object_Iterator(~(unsigned)0);
/* Then step through the objects to find the nth */
while (object_index != 0) {
temp_index = pObject->Object_Iterator(temp_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;
}
if (pObject->Object_Index_To_Instance) {
*object_type = pObject->Object_Type;
*instance =
pObject->Object_Index_To_Instance(object_index);
*instance = pObject->Object_Index_To_Instance(object_index);
status = true;
break;
}
@@ -587,13 +525,12 @@ bool Device_Object_List_Identifier(
* and the lookup succeeds, they will be given the resulting values.
* @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_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.
*/
bool Device_Valid_Object_Name(
BACNET_CHARACTER_STRING * object_name1,
int *object_type,
uint32_t * object_instance)
bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1,
int *object_type, uint32_t *object_instance)
{
bool found = false;
int type = 0;
@@ -631,9 +568,7 @@ bool Device_Valid_Object_Name(
* @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.
*/
bool Device_Valid_Object_Id(
int object_type,
uint32_t object_instance)
bool Device_Valid_Object_Id(int object_type, uint32_t object_instance)
{
bool status = false; /* return value */
struct object_functions *pObject = NULL;
@@ -652,10 +587,9 @@ bool Device_Valid_Object_Id(
* @param object_name [out] The Object Name found for this child Object.
* @return True on success or else False if not found.
*/
bool Device_Object_Name_Copy(
BACNET_OBJECT_TYPE object_type,
bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
BACNET_CHARACTER_STRING *object_name)
{
struct object_functions *pObject = NULL;
bool found = false;
@@ -668,8 +602,7 @@ bool Device_Object_Name_Copy(
return found;
}
static void Update_Current_Time(
void)
static void Update_Current_Time(void)
{
struct tm *tblock = NULL;
#if defined(_MSC_VER)
@@ -700,15 +633,16 @@ int tm_isdst Daylight Savings flag.
#endif
if (tblock) {
datetime_set_date(&Local_Date, (uint16_t) tblock->tm_year + 1900,
(uint8_t) tblock->tm_mon + 1, (uint8_t) tblock->tm_mday);
datetime_set_date(&Local_Date, (uint16_t)tblock->tm_year + 1900,
(uint8_t)tblock->tm_mon + 1,
(uint8_t)tblock->tm_mday);
#if !defined(_MSC_VER)
datetime_set_time(&Local_Time, (uint8_t) tblock->tm_hour,
(uint8_t) tblock->tm_min, (uint8_t) tblock->tm_sec,
(uint8_t) (tv.tv_usec / 10000));
datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour,
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec,
(uint8_t)(tv.tv_usec / 10000));
#else
datetime_set_time(&Local_Time, (uint8_t) tblock->tm_hour,
(uint8_t) tblock->tm_min, (uint8_t) tblock->tm_sec, 0);
datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour,
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, 0);
#endif
if (tblock->tm_isdst) {
Daylight_Savings_Status = true;
@@ -724,8 +658,7 @@ int tm_isdst Daylight Savings flag.
}
}
void Device_getCurrentDateTime(
BACNET_DATE_TIME * DateTime)
void Device_getCurrentDateTime(BACNET_DATE_TIME *DateTime)
{
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
BACNET_STATUS_ABORT for abort message */
int Device_Read_Property_Local(
BACNET_READ_PROPERTY_DATA * rpdata)
int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
int len = 0; /* apdu len intermediate value */
@@ -843,8 +775,7 @@ int Device_Read_Property_Local(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_DEVICE,
apdu_len = encode_application_object_id(&apdu[0], OBJECT_DEVICE,
Object_Instance_Number);
break;
case PROP_OBJECT_NAME:
@@ -868,8 +799,7 @@ int Device_Read_Property_Local(
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_VENDOR_IDENTIFIER:
apdu_len =
encode_application_unsigned(&apdu[0], Vendor_Identifier);
apdu_len = encode_application_unsigned(&apdu[0], Vendor_Identifier);
break;
case PROP_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);
break;
case PROP_PROTOCOL_VERSION:
apdu_len =
encode_application_unsigned(&apdu[0],
apdu_len = encode_application_unsigned(&apdu[0],
Device_Protocol_Version());
break;
case PROP_PROTOCOL_REVISION:
apdu_len =
encode_application_unsigned(&apdu[0],
apdu_len = encode_application_unsigned(&apdu[0],
Device_Protocol_Revision());
break;
case PROP_PROTOCOL_SERVICES_SUPPORTED:
@@ -907,8 +835,9 @@ int Device_Read_Property_Local(
bitstring_init(&bit_string);
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
/* automatic lookup based on handlers set */
bitstring_set_bit(&bit_string, (uint8_t) i,
apdu_service_supported((BACNET_SERVICES_SUPPORTED) i));
bitstring_set_bit(
&bit_string, (uint8_t)i,
apdu_service_supported((BACNET_SERVICES_SUPPORTED)i));
}
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
@@ -918,7 +847,7 @@ int Device_Read_Property_Local(
bitstring_init(&bit_string);
for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) {
/* initialize all the object types to not-supported */
bitstring_set_bit(&bit_string, (uint8_t) i, false);
bitstring_set_bit(&bit_string, (uint8_t)i, false);
}
/* set the object types with objects to supported */
@@ -942,16 +871,15 @@ int Device_Read_Property_Local(
/* your maximum APDU size. */
else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 1; i <= count; i++) {
found =
Device_Object_List_Identifier(i, &object_type,
found = Device_Object_List_Identifier(i, &object_type,
&instance);
if (found) {
len =
encode_application_object_id(&apdu[apdu_len],
object_type, instance);
len = encode_application_object_id(
&apdu[apdu_len], object_type, instance);
apdu_len += len;
/* 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) {
/* Abort response */
rpdata->error_code =
@@ -968,13 +896,11 @@ int Device_Read_Property_Local(
}
}
} else {
found =
Device_Object_List_Identifier(rpdata->array_index,
found = Device_Object_List_Identifier(rpdata->array_index,
&object_type, &instance);
if (found) {
apdu_len =
encode_application_object_id(&apdu[0], object_type,
instance);
apdu_len = encode_application_object_id(
&apdu[0], object_type, instance);
} else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
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);
break;
case PROP_SEGMENTATION_SUPPORTED:
apdu_len =
encode_application_enumerated(&apdu[0],
Device_Segmentation_Supported());
apdu_len = encode_application_enumerated(
&apdu[0], Device_Segmentation_Supported());
break;
case PROP_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());
break;
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);
break;
case PROP_DATABASE_REVISION:
apdu_len =
encode_application_unsigned(&apdu[0], Database_Revision);
apdu_len = encode_application_unsigned(&apdu[0], Database_Revision);
break;
#if defined(BACDL_MSTP)
case PROP_MAX_INFO_FRAMES:
apdu_len =
encode_application_unsigned(&apdu[0],
dlmstp_max_info_frames());
encode_application_unsigned(&apdu[0], dlmstp_max_info_frames());
break;
case PROP_MAX_MASTER:
apdu_len =
@@ -1034,7 +958,8 @@ int Device_Read_Property_Local(
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
* 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.
* @return The length of the APDU on success, else BACNET_STATUS_ERROR
*/
int Device_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = BACNET_STATUS_ERROR;
struct object_functions *pObject = NULL;
@@ -1078,14 +1002,13 @@ int Device_Read_Property(
* Each Child Object must provide some implementation of each of these
* functions in order to properly support the default handlers.
*/
void Device_Init(
object_functions_t * object_table)
void Device_Init(object_functions_t *object_table)
{
struct object_functions *pObject = NULL;
characterstring_init_ansi(&My_Object_Name, "SimpleClient");
/* we don't use the object table passed in */
(void) object_table;
(void)object_table;
pObject = &Object_Table[0];
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
if (pObject->Object_Init) {
+337 -644
View File
File diff suppressed because it is too large Load Diff
+87 -126
View File
@@ -1,29 +1,30 @@
/**************************************************************************
*
* Copyright (C) 2005,2010 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005,2010 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/** @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 <stdint.h>
@@ -68,19 +69,15 @@ long int timezone;
#endif
/* local forward and external prototypes */
extern int Device_Read_Property_Local(
BACNET_READ_PROPERTY_DATA * rpdata);
extern bool 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);
extern int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata);
extern bool 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)
#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
#warning This file should not be included in the build unless BAC_ROUTING is enabled.
#endif
@@ -118,9 +115,8 @@ uint16_t iCurrent_Device_Idx = 0;
* @return The index of this instance in the Devices[] array,
* or -1 if there isn't enough room to add this Device.
*/
uint16_t Add_Routed_Device(
uint32_t Object_Instance,
BACNET_CHARACTER_STRING * sObject_Name,
uint16_t Add_Routed_Device(uint32_t Object_Instance,
BACNET_CHARACTER_STRING *sObject_Name,
const char *sDescription)
{
int i = Num_Managed_Devices;
@@ -132,7 +128,8 @@ uint16_t Add_Routed_Device(
pDev->bacObj.Object_Instance_Number = Object_Instance;
if (sObject_Name != NULL)
Routed_Device_Set_Object_Name(sObject_Name->encoding,
sObject_Name->value, sObject_Name->length);
sObject_Name->value,
sObject_Name->length);
else
Routed_Device_Set_Object_Name(CHARACTER_UTF8, "No Name",
strlen("No Name"));
@@ -146,7 +143,6 @@ uint16_t Add_Routed_Device(
return -1;
}
/** Return the Device Object descriptive data for the indicated entry.
* @param idx [in] Index into Devices[] array being requested.
* 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
* is for an invalid row entry (eg, after the last good Device).
*/
DEVICE_OBJECT_DATA *Get_Routed_Device_Object(
int idx)
DEVICE_OBJECT_DATA *Get_Routed_Device_Object(int idx)
{
if (idx == -1)
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
* is currently set to"
* 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
* is for an invalid row entry (eg, after the last good Device).
* @return Pointer to the requested Device Object BACnet address, or NULL if the
* idx is for an invalid row entry (eg, after the last good Device).
*/
BACNET_ADDRESS *Get_Routed_Device_Address(
int idx)
BACNET_ADDRESS *Get_Routed_Device_Address(int idx)
{
if (idx == -1)
return &Devices[iCurrent_Device_Idx].bacDevAddr;
@@ -189,8 +183,6 @@ BACNET_ADDRESS *Get_Routed_Device_Address(
return NULL;
}
/** Get the currently active BACnet address.
* This is an implementation of the datalink_get_my_address() template for
* 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
* BACnet address.
*/
void routed_get_my_address(
BACNET_ADDRESS * my_address)
void routed_get_my_address(BACNET_ADDRESS *my_address)
{
if (my_address) {
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
* the given MAC address.
* Has the desirable side-effect of setting iCurrent_Device_Idx to the
@@ -225,10 +215,8 @@ void routed_get_my_address(
* meaning MAC broadcast, so it's an automatic match).
* Else False if no match or invalid idx is given.
*/
bool Routed_Device_Address_Lookup(
int idx,
uint8_t address_len,
uint8_t * mac_adress)
bool Routed_Device_Address_Lookup(int idx, uint8_t address_len,
uint8_t *mac_adress)
{
bool result = false;
DEVICE_OBJECT_DATA *pDev = &Devices[idx];
@@ -253,7 +241,6 @@ bool Routed_Device_Address_Lookup(
return result;
}
/** Find the next Gateway or Routed Device at the given MAC address,
* starting the search at the "cursor".
* Has the desirable side-effect of setting internal iCurrent_Device_Idx
@@ -261,29 +248,25 @@ bool Routed_Device_Address_Lookup(
* functions.
*
* @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
* broadcast. Otherwise, size is determined
* by the DLL type (eg, 6 for BIP and 2 for MSTP).
* @param DNET_list [in] List of our reachable downstream BACnet Network numbers.
* Normally just one valid entry; terminated with a -1 value.
* If the Length of the mac_adress[] field is 0, then this is a
* MAC broadcast. Otherwise, size is determined by the DLL type (eg, 6 for BIP
* and 2 for MSTP).
* @param DNET_list [in] List of our reachable downstream BACnet Network
* 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
* "hint" for the search; on return, it is updated to provide the
* cursor value to use with a subsequent GetNext call, or it
* equals -1 if there are no further matches.
* Set it to 0 on entry to access the main, gateway Device entry, or
* to start looping through the routed devices.
* "hint" for the search; on return, it is updated to provide
* the cursor value to use with a subsequent GetNext call, or it equals -1 if
* there are no further matches. Set it to 0 on entry to access the main,
* gateway Device entry, or to start looping through the routed devices.
* Otherwise, its returned value is implementation-dependent and the
* calling function should not alter or interpret it.
*
* @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).
* Else False if no match or invalid idx is given; the cursor will
* be returned as -1 in these cases.
* the dest->len is 0, meaning MAC bcast, so it's an automatic
* match). Else False if no match or invalid idx is given; the cursor will be
* returned as -1 in these cases.
*/
bool Routed_Device_GetNext(
BACNET_ADDRESS * dest,
int *DNET_list,
int *cursor)
bool Routed_Device_GetNext(BACNET_ADDRESS *dest, int *DNET_list, int *cursor)
{
int dnet = DNET_list[0]; /* Get the DNET of our virtual network */
int idx = *cursor;
@@ -338,23 +321,19 @@ bool Routed_Device_GetNext(
return bSuccess;
}
/** Check if the destination network is reachable - is it our virtual network,
* or local or else broadcast.
*
* @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
* gateway, or 0xFFFF for a broadcast network number.
* @param DNET_list [in] List of our reachable downstream BACnet Network numbers.
* Normally just one valid entry; terminated with a -1 value.
* Success if it is our virtual network number, or 0 (local for
* the gateway, or 0xFFFF for a broadcast network number.
* @param DNET_list [in] List of our reachable downstream BACnet Network
* numbers. Normally just one valid entry; terminated with a -1 value.
* @return True if matches our virtual network, or is for the local network
* Device (the gateway), or is BACNET_BROADCAST_NETWORK, which is
* an automatic match.
* Else False if not a reachable network.
* Device (the gateway), or is BACNET_BROADCAST_NETWORK,
* which is an automatic match. Else False if not a reachable network.
*/
bool Routed_Device_Is_Valid_Network(
uint16_t dest_net,
int *DNET_list)
bool Routed_Device_Is_Valid_Network(uint16_t dest_net, int *DNET_list)
{
int dnet = DNET_list[0]; /* Get the DNET of our virtual network */
bool bSuccess = false;
@@ -374,11 +353,9 @@ bool Routed_Device_Is_Valid_Network(
return bSuccess;
}
/* methods to override the normal Device objection functions */
uint32_t Routed_Device_Index_To_Instance(
unsigned index)
uint32_t Routed_Device_Index_To_Instance(unsigned index)
{
index = index;
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
* before this function is called.
* @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.
*/
bool Routed_Device_Valid_Object_Instance_Number(
uint32_t object_id)
bool Routed_Device_Valid_Object_Instance_Number(uint32_t object_id)
{
bool bResult = false;
DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx];
@@ -404,14 +381,12 @@ bool Routed_Device_Valid_Object_Instance_Number(
return bResult;
}
bool Routed_Device_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Routed_Device_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx];
if (object_instance == pDev->bacObj.Object_Instance_Number) {
return characterstring_init_ansi(object_name,
pDev->bacObj.Object_Name);
return characterstring_init_ansi(object_name, pDev->bacObj.Object_Name);
}
return false;
@@ -423,8 +398,7 @@ bool Routed_Device_Name(
* @return The length of the apdu encoded, or BACNET_STATUS_ERROR for error or
* BACNET_STATUS_ABORT for abort message.
*/
int Routed_Device_Read_Property_Local(
BACNET_READ_PROPERTY_DATA * rpdata)
int Routed_Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
BACNET_CHARACTER_STRING char_string;
@@ -438,9 +412,8 @@ int Routed_Device_Read_Property_Local(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_DEVICE,
pDev->bacObj.Object_Instance_Number);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_DEVICE, pDev->bacObj.Object_Instance_Number);
break;
case PROP_OBJECT_NAME:
characterstring_init_ansi(&char_string, pDev->bacObj.Object_Name);
@@ -464,16 +437,14 @@ int Routed_Device_Read_Property_Local(
return (apdu_len);
}
bool Routed_Device_Write_Property_Local(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Routed_Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
if (len < 0) {
/* 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);
if (status) {
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
(Routed_Device_Set_Object_Instance_Number(value.type.
Object_Id.instance))) {
/* FIXME: we could send an I-Am broadcast to let the world know */
(Routed_Device_Set_Object_Instance_Number(
value.type.Object_Id.instance))) {
/* FIXME: we could send an I-Am broadcast to let the world
* know */
} else {
status = false;
wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -511,8 +483,8 @@ bool Routed_Device_Write_Property_Local(
WPValidateString(&value, MAX_DEV_NAME_LEN, false,
&wp_data->error_class, &wp_data->error_code);
if (status) {
Routed_Device_Set_Object_Name(characterstring_encoding(&value.
type.Character_String),
Routed_Device_Set_Object_Name(
characterstring_encoding(&value.type.Character_String),
characterstring_value(&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.
*/
uint32_t Routed_Device_Object_Instance_Number(
void)
uint32_t Routed_Device_Object_Instance_Number(void)
{
return Devices[iCurrent_Device_Idx].bacObj.Object_Instance_Number;
}
bool Routed_Device_Set_Object_Instance_Number(
uint32_t object_id)
bool Routed_Device_Set_Object_Instance_Number(uint32_t object_id)
{
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.
* @return True if succeed in updating Object Name, else False.
*/
bool Routed_Device_Set_Object_Name(
uint8_t encoding,
const char *value,
bool Routed_Device_Set_Object_Name(uint8_t encoding, const char *value,
size_t length)
{
bool status = false; /*return value */
@@ -578,9 +546,7 @@ bool Routed_Device_Set_Object_Name(
return status;
}
bool Routed_Device_Set_Description(
const char *name,
size_t length)
bool Routed_Device_Set_Description(const char *name, size_t length)
{
bool status = false; /*return value */
DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx];
@@ -594,20 +560,17 @@ bool Routed_Device_Set_Description(
return status;
}
/*
* Shortcut for incrementing database revision as this is potentially
* the most common operation if changing object names and ids is
* implemented.
*/
void Routed_Device_Inc_Database_Revision(
void)
void Routed_Device_Inc_Database_Revision(void)
{
DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx];
pDev->Database_Revision++;
}
/** Check to see if the current Device supports this service.
* Presently checks for RD and DCC and only allows them if the current
* 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,
* else 0 if service is approved for the current device.
*/
int Routed_Device_Service_Approval(
BACNET_CONFIRMED_SERVICE service,
int service_argument,
uint8_t * apdu_buff,
int Routed_Device_Service_Approval(BACNET_CONFIRMED_SERVICE service,
int service_argument, uint8_t *apdu_buff,
uint8_t invoke_id)
{
int len = 0;
+33 -58
View File
@@ -52,31 +52,25 @@
#endif
struct integer_object {
bool Out_Of_Service:1;
bool Out_Of_Service : 1;
int32_t Present_Value;
uint16_t Units;
};
struct integer_object Integer_Value[MAX_INTEGER_VALUES];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Integer_Value_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
static const int Integer_Value_Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_UNITS,
-1
};
-1};
static const int Integer_Value_Properties_Optional[] = {
PROP_OUT_OF_SERVICE,
-1
};
static const int Integer_Value_Properties_Optional[] = {PROP_OUT_OF_SERVICE,
-1};
static const int Integer_Value_Properties_Proprietary[] = {
-1
};
static const int Integer_Value_Properties_Proprietary[] = {-1};
/**
* 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
* BACnet proprietary properties for this object.
*/
void Integer_Value_Property_Lists(
const int **pRequired,
const int **pOptional,
void Integer_Value_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -111,8 +103,7 @@ void Integer_Value_Property_Lists(
*
* @return true if the instance is valid, and false if not
*/
bool Integer_Value_Valid_Instance(
uint32_t object_instance)
bool Integer_Value_Valid_Instance(uint32_t object_instance)
{
unsigned int index;
@@ -129,8 +120,7 @@ bool Integer_Value_Valid_Instance(
*
* @return Number of Analog Value objects
*/
unsigned Integer_Value_Count(
void)
unsigned Integer_Value_Count(void)
{
return MAX_INTEGER_VALUES;
}
@@ -143,8 +133,7 @@ unsigned Integer_Value_Count(
*
* @return object instance-number for the given index
*/
uint32_t Integer_Value_Index_To_Instance(
unsigned index)
uint32_t Integer_Value_Index_To_Instance(unsigned index)
{
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
* if not valid.
*/
unsigned Integer_Value_Instance_To_Index(
uint32_t object_instance)
unsigned Integer_Value_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_INTEGER_VALUES;
@@ -184,8 +172,7 @@ unsigned Integer_Value_Instance_To_Index(
*
* @return present-value of the object
*/
int32_t Integer_Value_Present_Value(
uint32_t object_instance)
int32_t Integer_Value_Present_Value(uint32_t object_instance)
{
int32_t value = 0;
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.
*/
bool Integer_Value_Present_Value_Set(
uint32_t object_instance,
int32_t value,
bool Integer_Value_Present_Value_Set(uint32_t object_instance, int32_t value,
uint8_t priority)
{
bool status = false;
@@ -234,9 +219,8 @@ bool Integer_Value_Present_Value_Set(
*
* @return true if object-name was retrieved
*/
bool Integer_Value_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Integer_Value_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
char text_string[32] = "";
unsigned int index;
@@ -244,7 +228,8 @@ bool Integer_Value_Object_Name(
index = Integer_Value_Instance_To_Index(object_instance);
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);
}
@@ -258,8 +243,7 @@ bool Integer_Value_Object_Name(
*
* @return units property value
*/
uint16_t Integer_Value_Units(
uint32_t instance)
uint16_t Integer_Value_Units(uint32_t instance)
{
unsigned int index;
uint16_t units = UNITS_NO_UNITS;
@@ -280,9 +264,7 @@ uint16_t Integer_Value_Units(
*
* @return true if the units property value was set
*/
bool Integer_Value_Units_Set(
uint32_t instance,
uint16_t units)
bool Integer_Value_Units_Set(uint32_t instance, uint16_t units)
{
unsigned int index = 0;
bool status = false;
@@ -304,15 +286,14 @@ bool Integer_Value_Units_Set(
*
* @return out-of-service property value
*/
bool Integer_Value_Out_Of_Service(
uint32_t instance)
bool Integer_Value_Out_Of_Service(uint32_t instance)
{
unsigned int index = 0;
bool value = false;
index = Integer_Value_Instance_To_Index(instance);
if (index < MAX_INTEGER_VALUES) {
value= Integer_Value[index].Out_Of_Service;
value = Integer_Value[index].Out_Of_Service;
}
return value;
@@ -326,9 +307,7 @@ bool Integer_Value_Out_Of_Service(
*
* @return true if the out-of-service property value was set
*/
void Integer_Value_Out_Of_Service_Set(
uint32_t instance,
bool value)
void Integer_Value_Out_Of_Service_Set(uint32_t instance, bool value)
{
unsigned int index = 0;
@@ -348,8 +327,7 @@ void Integer_Value_Out_Of_Service_Set(
* @return number of APDU bytes in the response, or
* BACNET_STATUS_ERROR on error.
*/
int Integer_Value_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Integer_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
@@ -367,9 +345,8 @@ int Integer_Value_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_INTEGER_VALUE,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_INTEGER_VALUE, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
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);
break;
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);
break;
case PROP_STATUS_FLAGS:
@@ -428,16 +406,14 @@ int Integer_Value_Read_Property(
*
* @return false if an error is loaded, true if no errors
*/
bool Integer_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Integer_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -461,7 +437,8 @@ bool Integer_Value_Write_Property(
&wp_data->error_class, &wp_data->error_code);
if (status) {
Integer_Value_Present_Value_Set(wp_data->object_instance,
value.type.Signed_Int, wp_data->priority);
value.type.Signed_Int,
wp_data->priority);
}
break;
case PROP_OUT_OF_SERVICE:
@@ -469,8 +446,7 @@ bool Integer_Value_Write_Property(
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class, &wp_data->error_code);
if (status) {
Integer_Value_Out_Of_Service_Set(
wp_data->object_instance,
Integer_Value_Out_Of_Service_Set(wp_data->object_instance,
value.type.Boolean);
}
break;
@@ -494,8 +470,7 @@ bool Integer_Value_Write_Property(
/**
* Initializes the Integer Value object data
*/
void Integer_Value_Init(
void)
void Integer_Value_Init(void)
{
unsigned index = 0;
+140 -198
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Load Control Objects - customize for your use */
/* from 135-2004-Addendum e */
@@ -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
all the load control objects in this example device. */
static char *Shed_Level_Descriptions[MAX_SHED_LEVELS] = {
"dim lights 10%",
"dim lights 20%",
"dim lights 30%"
};
static float Shed_Level_Values[MAX_SHED_LEVELS] = {
90.0,
80.0,
70.0
};
"dim lights 10%", "dim lights 20%", "dim lights 30%"};
static float Shed_Level_Values[MAX_SHED_LEVELS] = {90.0, 80.0, 70.0};
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Load_Control_Properties_Required[] = {
@@ -155,22 +147,14 @@ static const int Load_Control_Properties_Required[] = {
PROP_ACTUAL_SHED_LEVEL,
PROP_SHED_LEVELS,
PROP_SHED_LEVEL_DESCRIPTIONS,
-1
};
-1};
static const int Load_Control_Properties_Optional[] = {
PROP_DESCRIPTION,
PROP_FULL_DUTY_BASELINE,
-1
};
PROP_DESCRIPTION, PROP_FULL_DUTY_BASELINE, -1};
static const int Load_Control_Properties_Proprietary[] = {
-1
};
static const int Load_Control_Properties_Proprietary[] = {-1};
void Load_Control_Property_Lists(
const int **pRequired,
const int **pOptional,
void Load_Control_Property_Lists(const int **pRequired, const int **pOptional,
const int **pProprietary)
{
if (pRequired)
@@ -183,8 +167,7 @@ void Load_Control_Property_Lists(
return;
}
void Load_Control_Init(
void)
void Load_Control_Init(void)
{
unsigned i, j;
@@ -217,8 +200,7 @@ void Load_Control_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Load_Control_Valid_Instance(
uint32_t object_instance)
bool Load_Control_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_LOAD_CONTROLS)
return true;
@@ -228,8 +210,7 @@ bool Load_Control_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Load_Control_Count(
void)
unsigned Load_Control_Count(void)
{
return MAX_LOAD_CONTROLS;
}
@@ -237,8 +218,7 @@ unsigned Load_Control_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Load_Control_Index_To_Instance(
unsigned index)
uint32_t Load_Control_Index_To_Instance(unsigned index)
{
return index;
}
@@ -246,8 +226,7 @@ uint32_t Load_Control_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Load_Control_Instance_To_Index(
uint32_t object_instance)
unsigned Load_Control_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_LOAD_CONTROLS;
@@ -257,8 +236,7 @@ unsigned Load_Control_Instance_To_Index(
return index;
}
static BACNET_SHED_STATE Load_Control_Present_Value(
uint32_t object_instance)
static BACNET_SHED_STATE Load_Control_Present_Value(uint32_t object_instance)
{
BACNET_SHED_STATE value = BACNET_SHED_INACTIVE;
unsigned index = 0;
@@ -272,9 +250,8 @@ static BACNET_SHED_STATE Load_Control_Present_Value(
}
/* note: the object name must be unique within this device */
bool Load_Control_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Load_Control_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
@@ -287,14 +264,13 @@ bool Load_Control_Object_Name(
return status;
}
static void Update_Current_Time(
BACNET_DATE_TIME * bdatetime)
static void Update_Current_Time(BACNET_DATE_TIME *bdatetime)
{
time_t timer;
struct tm *tblock;
/*
struct tm {
/*
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
@@ -304,20 +280,19 @@ struct tm {
int tm_wday;
int tm_yday;
int tm_isdst;
};
*/
};
*/
timer = time(NULL);
tblock = localtime(&timer);
datetime_set_values(bdatetime, (uint16_t) tblock->tm_year,
(uint8_t) tblock->tm_mon, (uint8_t) tblock->tm_mday,
(uint8_t) tblock->tm_hour, (uint8_t) tblock->tm_min,
(uint8_t) tblock->tm_sec, 0);
datetime_set_values(bdatetime, (uint16_t)tblock->tm_year,
(uint8_t)tblock->tm_mon, (uint8_t)tblock->tm_mday,
(uint8_t)tblock->tm_hour, (uint8_t)tblock->tm_min,
(uint8_t)tblock->tm_sec, 0);
}
/* convert the shed level request into an Analog Output Present_Value */
static float Requested_Shed_Level_Value(
int object_index)
static float Requested_Shed_Level_Value(int object_index)
{
unsigned shed_level_index = 0;
unsigned i = 0;
@@ -326,12 +301,11 @@ static float Requested_Shed_Level_Value(
switch (Requested_Shed_Level[object_index].type) {
case BACNET_SHED_TYPE_PERCENT:
requested_level =
(float) Requested_Shed_Level[object_index].value.percent;
(float)Requested_Shed_Level[object_index].value.percent;
break;
case BACNET_SHED_TYPE_AMOUNT:
/* Assumptions: wattage is linear with analog output level */
requested_level =
Full_Duty_Baseline[object_index] -
requested_level = Full_Duty_Baseline[object_index] -
Requested_Shed_Level[object_index].value.amount;
requested_level /= Full_Duty_Baseline[object_index];
requested_level *= 100.0;
@@ -350,9 +324,7 @@ static float Requested_Shed_Level_Value(
return requested_level;
}
static void Shed_Level_Copy(
BACNET_SHED_LEVEL * dest,
BACNET_SHED_LEVEL * src)
static void Shed_Level_Copy(BACNET_SHED_LEVEL *dest, BACNET_SHED_LEVEL *src)
{
if (dest && src) {
dest->type = src->type;
@@ -371,8 +343,7 @@ static void Shed_Level_Copy(
}
}
static void Shed_Level_Default_Set(
BACNET_SHED_LEVEL * dest,
static void Shed_Level_Default_Set(BACNET_SHED_LEVEL *dest,
BACNET_SHED_LEVEL_TYPE type)
{
if (dest) {
@@ -392,8 +363,7 @@ static void Shed_Level_Default_Set(
}
}
static bool Able_To_Meet_Shed_Request(
int object_index)
static bool Able_To_Meet_Shed_Request(int object_index)
{
float 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];
#if PRINT_ENABLED_DEBUG
static void Print_Load_Control_State(
int object_index)
static void Print_Load_Control_State(int object_index)
{
char *Load_Control_State_Text[MAX_LOAD_CONTROLS] = {
"SHED_INACTIVE",
"SHED_REQUEST_PENDING",
"SHED_NON_COMPLIANT",
"SHED_COMPLIANT"
};
"SHED_INACTIVE", "SHED_REQUEST_PENDING", "SHED_NON_COMPLIANT",
"SHED_COMPLIANT"};
if (object_index < MAX_LOAD_CONTROLS) {
if (Load_Control_State[object_index] < MAX_LOAD_CONTROL_STATE) {
@@ -447,8 +413,7 @@ static void Print_Load_Control_State(
}
#endif
void Load_Control_State_Machine(
int object_index)
void Load_Control_State_Machine(int object_index)
{
unsigned i = 0; /* loop counter */
int diff = 0; /* used for datetime comparison */
@@ -512,8 +477,10 @@ void Load_Control_State_Machine(
/* CancelShed */
/* FIXME: stop shedding! i.e. relinquish */
#if PRINT_ENABLED_DEBUG
printf("Load Control[%d]:Current Time"
" is after Start Time + Duration\n", object_index);
printf(
"Load Control[%d]:Current Time"
" is after Start Time + Duration\n",
object_index);
#endif
Load_Control_State[object_index] = SHED_INACTIVE;
break;
@@ -529,23 +496,28 @@ void Load_Control_State_Machine(
} else if (diff > 0) {
/* current time after to start time */
#if PRINT_ENABLED_DEBUG
printf("Load Control[%d]:Current Time"
" is after Start Time\n", object_index);
printf(
"Load Control[%d]:Current Time"
" is after Start Time\n",
object_index);
#endif
/* AbleToMeetShed */
if (Able_To_Meet_Shed_Request(object_index)) {
Shed_Level_Copy(&Expected_Shed_Level[object_index],
&Requested_Shed_Level[object_index]);
Analog_Output_Present_Value_Set(object_index,
Requested_Shed_Level_Value(object_index), 4);
Analog_Output_Present_Value_Set(
object_index, Requested_Shed_Level_Value(object_index),
4);
Shed_Level_Copy(&Actual_Shed_Level[object_index],
&Requested_Shed_Level[object_index]);
Load_Control_State[object_index] = SHED_COMPLIANT;
} else {
/* 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);
Shed_Level_Default_Set(&Actual_Shed_Level[object_index],
Shed_Level_Default_Set(
&Actual_Shed_Level[object_index],
Requested_Shed_Level[object_index].type);
Load_Control_State[object_index] = SHED_NON_COMPLIANT;
}
@@ -559,8 +531,9 @@ void Load_Control_State_Machine(
if (diff < 0) {
/* FinishedUnsuccessfulShed */
#if PRINT_ENABLED_DEBUG
printf
("Load Control[%d]:Current Time is after Start Time + Duration\n",
printf(
"Load Control[%d]:Current Time is after Start Time + "
"Duration\n",
object_index);
#endif
Load_Control_State[object_index] = SHED_INACTIVE;
@@ -585,8 +558,8 @@ void Load_Control_State_Machine(
#endif
Shed_Level_Copy(&Expected_Shed_Level[object_index],
&Requested_Shed_Level[object_index]);
Analog_Output_Present_Value_Set(object_index,
Requested_Shed_Level_Value(object_index), 4);
Analog_Output_Present_Value_Set(
object_index, Requested_Shed_Level_Value(object_index), 4);
Shed_Level_Copy(&Actual_Shed_Level[object_index],
&Requested_Shed_Level[object_index]);
Load_Control_State[object_index] = SHED_COMPLIANT;
@@ -600,8 +573,9 @@ void Load_Control_State_Machine(
if (diff < 0) {
/* FinishedSuccessfulShed */
#if PRINT_ENABLED_DEBUG
printf
("Load Control[%d]:Current Time is after Start Time + Duration\n",
printf(
"Load Control[%d]:Current Time is after Start Time + "
"Duration\n",
object_index);
#endif
datetime_wildcard_set(&Start_Time[i]);
@@ -653,8 +627,7 @@ void Load_Control_State_Machine(
}
/* call every second or so */
void Load_Control_State_Machine_Handler(
void)
void Load_Control_State_Machine_Handler(void)
{
unsigned i = 0;
static bool initialized = false;
@@ -675,14 +648,11 @@ void Load_Control_State_Machine_Handler(
#endif
Load_Control_State_Previously[i] = Load_Control_State[i];
}
}
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Load_Control_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Load_Control_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
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);
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_LOAD_CONTROL,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_LOAD_CONTROL, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
@@ -744,41 +713,37 @@ int Load_Control_Read_Property(
case PROP_REQUESTED_SHED_LEVEL:
switch (Requested_Shed_Level[object_index].type) {
case BACNET_SHED_TYPE_PERCENT:
apdu_len =
encode_context_unsigned(&apdu[0], 0,
apdu_len = encode_context_unsigned(
&apdu[0], 0,
Requested_Shed_Level[object_index].value.percent);
break;
case BACNET_SHED_TYPE_AMOUNT:
apdu_len =
encode_context_real(&apdu[0], 2,
apdu_len = encode_context_real(
&apdu[0], 2,
Requested_Shed_Level[object_index].value.amount);
break;
case BACNET_SHED_TYPE_LEVEL:
default:
apdu_len =
encode_context_unsigned(&apdu[0], 1,
apdu_len = encode_context_unsigned(
&apdu[0], 1,
Requested_Shed_Level[object_index].value.level);
break;
}
break;
case PROP_START_TIME:
len =
encode_application_date(&apdu[0],
len = encode_application_date(&apdu[0],
&Start_Time[object_index].date);
apdu_len = len;
len =
encode_application_time(&apdu[apdu_len],
len = encode_application_time(&apdu[apdu_len],
&Start_Time[object_index].time);
apdu_len += len;
break;
case PROP_SHED_DURATION:
apdu_len =
encode_application_unsigned(&apdu[0],
apdu_len = encode_application_unsigned(&apdu[0],
Shed_Duration[object_index]);
break;
case PROP_DUTY_WINDOW:
apdu_len =
encode_application_unsigned(&apdu[0],
apdu_len = encode_application_unsigned(&apdu[0],
Duty_Window[object_index]);
break;
case PROP_ENABLE:
@@ -786,26 +751,25 @@ int Load_Control_Read_Property(
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_FULL_DUTY_BASELINE: /* optional */
apdu_len =
encode_application_real(&apdu[0],
Full_Duty_Baseline[object_index]);
apdu_len = encode_application_real(
&apdu[0], Full_Duty_Baseline[object_index]);
break;
case PROP_EXPECTED_SHED_LEVEL:
switch (Expected_Shed_Level[object_index].type) {
case BACNET_SHED_TYPE_PERCENT:
apdu_len =
encode_context_unsigned(&apdu[0], 0,
apdu_len = encode_context_unsigned(
&apdu[0], 0,
Expected_Shed_Level[object_index].value.percent);
break;
case BACNET_SHED_TYPE_AMOUNT:
apdu_len =
encode_context_real(&apdu[0], 2,
apdu_len = encode_context_real(
&apdu[0], 2,
Expected_Shed_Level[object_index].value.amount);
break;
case BACNET_SHED_TYPE_LEVEL:
default:
apdu_len =
encode_context_unsigned(&apdu[0], 1,
apdu_len = encode_context_unsigned(
&apdu[0], 1,
Expected_Shed_Level[object_index].value.level);
break;
}
@@ -813,19 +777,19 @@ int Load_Control_Read_Property(
case PROP_ACTUAL_SHED_LEVEL:
switch (Actual_Shed_Level[object_index].type) {
case BACNET_SHED_TYPE_PERCENT:
apdu_len =
encode_context_unsigned(&apdu[0], 0,
apdu_len = encode_context_unsigned(
&apdu[0], 0,
Actual_Shed_Level[object_index].value.percent);
break;
case BACNET_SHED_TYPE_AMOUNT:
apdu_len =
encode_context_real(&apdu[0], 2,
apdu_len = encode_context_real(
&apdu[0], 2,
Actual_Shed_Level[object_index].value.amount);
break;
case BACNET_SHED_TYPE_LEVEL:
default:
apdu_len =
encode_context_unsigned(&apdu[0], 1,
apdu_len = encode_context_unsigned(
&apdu[0], 1,
Actual_Shed_Level[object_index].value.level);
break;
}
@@ -841,9 +805,8 @@ int Load_Control_Read_Property(
apdu_len = 0;
for (i = 0; i < MAX_SHED_LEVELS; i++) {
/* FIXME: check if we have room before adding it to APDU */
len =
encode_application_unsigned(&apdu[apdu_len],
Shed_Levels[object_index][i]);
len = encode_application_unsigned(
&apdu[apdu_len], Shed_Levels[object_index][i]);
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
@@ -856,8 +819,8 @@ int Load_Control_Read_Property(
}
} else {
if (rpdata->array_index <= MAX_SHED_LEVELS) {
apdu_len =
encode_application_unsigned(&apdu[0],
apdu_len = encode_application_unsigned(
&apdu[0],
Shed_Levels[object_index][rpdata->array_index - 1]);
} else {
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 */
characterstring_init_ansi(&char_string,
Shed_Level_Descriptions[i]);
len =
encode_application_character_string(&apdu[apdu_len],
len = encode_application_character_string(&apdu[apdu_len],
&char_string);
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
@@ -894,11 +856,11 @@ int Load_Control_Read_Property(
}
} else {
if (rpdata->array_index <= MAX_SHED_LEVELS) {
characterstring_init_ansi(&char_string,
characterstring_init_ansi(
&char_string,
Shed_Level_Descriptions[rpdata->array_index - 1]);
apdu_len =
encode_application_character_string(&apdu[0],
&char_string);
apdu_len = encode_application_character_string(
&apdu[0], &char_string);
} else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -926,18 +888,17 @@ int Load_Control_Read_Property(
}
/* returns true if successful */
bool Load_Control_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
unsigned int object_index = 0;
int len = 0;
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 */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -956,10 +917,9 @@ bool Load_Control_Write_Property(
object_index = Load_Control_Instance_To_Index(wp_data->object_instance);
switch (wp_data->object_property) {
case PROP_REQUESTED_SHED_LEVEL:
len =
bacapp_decode_context_data(wp_data->application_data,
wp_data->application_data_len, &value,
PROP_REQUESTED_SHED_LEVEL);
len = bacapp_decode_context_data(wp_data->application_data,
wp_data->application_data_len,
&value, PROP_REQUESTED_SHED_LEVEL);
if (value.context_tag == 0) {
/* percent - Unsigned */
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 */
TempDate = value.type.Date;
len =
bacapp_decode_application_data(wp_data->application_data + len,
len = bacapp_decode_application_data(
wp_data->application_data + len,
wp_data->application_data_len - len, &value);
if (len) {
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_TIME,
&wp_data->error_class, &wp_data->error_code);
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_TIME,
&wp_data->error_class,
&wp_data->error_code);
if (status) {
/* Write time and date and set written flag */
Start_Time[object_index].date = TempDate;
@@ -1117,8 +1077,7 @@ static void Load_Control_WriteProperty_Request_Shed_Percent(
}
#endif
static void Load_Control_WriteProperty_Request_Shed_Level(
Test * pTest,
static void Load_Control_WriteProperty_Request_Shed_Level(Test *pTest,
int instance,
unsigned level)
{
@@ -1169,9 +1128,7 @@ static void Load_Control_WriteProperty_Request_Shed_Amount(
}
#endif
static void Load_Control_WriteProperty_Enable(
Test * pTest,
int instance,
static void Load_Control_WriteProperty_Enable(Test *pTest, int instance,
bool enable)
{
bool status = false;
@@ -1195,9 +1152,7 @@ static void Load_Control_WriteProperty_Enable(
ct_test(pTest, status == true);
}
static void Load_Control_WriteProperty_Shed_Duration(
Test * pTest,
int instance,
static void Load_Control_WriteProperty_Shed_Duration(Test *pTest, int instance,
unsigned duration)
{
bool status = false;
@@ -1220,9 +1175,7 @@ static void Load_Control_WriteProperty_Shed_Duration(
ct_test(pTest, status == true);
}
static void Load_Control_WriteProperty_Duty_Window(
Test * pTest,
int instance,
static void Load_Control_WriteProperty_Duty_Window(Test *pTest, int instance,
unsigned duration)
{
bool status = false;
@@ -1245,8 +1198,7 @@ static void Load_Control_WriteProperty_Duty_Window(
ct_test(pTest, status == true);
}
static void Load_Control_WriteProperty_Start_Time_Wildcards(
Test * pTest,
static void Load_Control_WriteProperty_Start_Time_Wildcards(Test *pTest,
int instance)
{
int len = 0;
@@ -1278,15 +1230,8 @@ static void Load_Control_WriteProperty_Start_Time_Wildcards(
}
static void Load_Control_WriteProperty_Start_Time(
Test * pTest,
int instance,
uint16_t year,
uint8_t month,
uint8_t day,
uint8_t hour,
uint8_t minute,
uint8_t seconds,
uint8_t hundredths)
Test *pTest, int instance, uint16_t year, uint8_t month, uint8_t day,
uint8_t hour, uint8_t minute, uint8_t seconds, uint8_t hundredths)
{
int len = 0;
bool status = false;
@@ -1316,8 +1261,7 @@ static void Load_Control_WriteProperty_Start_Time(
ct_test(pTest, status == true);
}
void testLoadControlStateMachine(
Test * pTest)
void testLoadControlStateMachine(Test *pTest)
{
unsigned i = 0, j = 0;
uint8_t level = 0;
@@ -1456,10 +1400,9 @@ void testLoadControlStateMachine(
ct_test(pTest, level == 100);
}
void testLoadControl(
Test * pTest)
void testLoadControl(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -1487,8 +1430,7 @@ void testLoadControl(
}
#ifdef TEST_LOAD_CONTROL
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -1502,7 +1444,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+134 -208
View File
@@ -1,31 +1,31 @@
/**
* @file
* @author Steve Karg
* @date 2013
* @brief Lighting Output object
*
* @section LICENSE
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
* @file
* @author Steve Karg
* @date 2013
* @brief Lighting Output object
*
* @section LICENSE
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <stdbool.h>
#include <stdint.h>
@@ -53,9 +53,9 @@ struct lighting_output_object {
float Physical_Value;
BACNET_LIGHTING_COMMAND Lighting_Command;
BACNET_LIGHTING_IN_PROGRESS In_Progress;
bool Out_Of_Service:1;
bool Blink_Warn_Enable:1;
bool Egress_Active:1;
bool Out_Of_Service : 1;
bool Blink_Warn_Enable : 1;
bool Egress_Active : 1;
uint32_t Egress_Time;
uint32_t Default_Fade_Time;
float Default_Ramp_Rate;
@@ -94,15 +94,10 @@ static const int Lighting_Output_Properties_Required[] = {
PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT,
PROP_LIGHTING_COMMAND_DEFAULT_PRIORITY,
-1
};
static const int Lighting_Output_Properties_Optional[] = {
-1
};
-1};
static const int Lighting_Output_Properties_Optional[] = {-1};
static const int Lighting_Output_Properties_Proprietary[] = {
-1
};
static const int Lighting_Output_Properties_Proprietary[] = {-1};
/**
* Returns the list of required, optional, and proprietary properties.
@@ -115,8 +110,7 @@ static const int Lighting_Output_Properties_Proprietary[] = {
* @param pProprietary - pointer to list of int terminated by -1, of
* BACnet proprietary properties for this object.
*/
void Lighting_Output_Property_Lists(
const int **pRequired,
void Lighting_Output_Property_Lists(const int **pRequired,
const int **pOptional,
const int **pProprietary)
{
@@ -137,8 +131,7 @@ void Lighting_Output_Property_Lists(
*
* @return true if the instance is valid, and false if not
*/
bool Lighting_Output_Valid_Instance(
uint32_t object_instance)
bool Lighting_Output_Valid_Instance(uint32_t object_instance)
{
unsigned int index;
@@ -155,8 +148,7 @@ bool Lighting_Output_Valid_Instance(
*
* @return Number of Lighting Output objects
*/
unsigned Lighting_Output_Count(
void)
unsigned Lighting_Output_Count(void)
{
return MAX_LIGHTING_OUTPUTS;
}
@@ -169,8 +161,7 @@ unsigned Lighting_Output_Count(
*
* @return object instance-number for the given index
*/
uint32_t Lighting_Output_Index_To_Instance(
unsigned index)
uint32_t Lighting_Output_Index_To_Instance(unsigned index)
{
uint32_t instance = 1;
@@ -188,8 +179,7 @@ uint32_t Lighting_Output_Index_To_Instance(
* @return index for the given instance-number, or MAX_LIGHTING_OUTPUTS
* if not valid.
*/
unsigned Lighting_Output_Instance_To_Index(
uint32_t object_instance)
unsigned Lighting_Output_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_LIGHTING_OUTPUTS;
@@ -210,8 +200,7 @@ unsigned Lighting_Output_Instance_To_Index(
*
* @return present-value of the object
*/
float Lighting_Output_Present_Value(
uint32_t object_instance)
float Lighting_Output_Present_Value(uint32_t object_instance)
{
float value = 0.0;
unsigned index = 0;
@@ -240,8 +229,7 @@ float Lighting_Output_Present_Value(
*
* @return priority-value of the object
*/
static float Lighting_Output_Priority_Value(
uint32_t object_instance,
static float Lighting_Output_Priority_Value(uint32_t object_instance,
unsigned priority)
{
float value = 0.0;
@@ -267,8 +255,7 @@ static float Lighting_Output_Priority_Value(
*
* @return true if the priority slot is active
*/
static bool Lighting_Output_Priority_Active(
uint32_t object_instance,
static bool Lighting_Output_Priority_Active(uint32_t object_instance,
unsigned priority)
{
bool status = false;
@@ -278,7 +265,8 @@ static bool Lighting_Output_Priority_Active(
if (index < MAX_LIGHTING_OUTPUTS) {
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
if (BIT_CHECK(Lighting_Output[index].Priority_Active_Bits, priority)) {
if (BIT_CHECK(Lighting_Output[index].Priority_Active_Bits,
priority)) {
status = true;
}
}
@@ -294,8 +282,7 @@ static bool Lighting_Output_Priority_Active(
*
* @return active priority 1..16, or 0 if no priority is active
*/
unsigned Lighting_Output_Present_Value_Priority(
uint32_t object_instance)
unsigned Lighting_Output_Present_Value_Priority(uint32_t object_instance)
{
unsigned index = 0; /* instance to index conversion */
unsigned p = 0; /* loop counter */
@@ -324,9 +311,7 @@ unsigned Lighting_Output_Present_Value_Priority(
*
* @return true if values are within range and present-value is set.
*/
bool Lighting_Output_Present_Value_Set(
uint32_t object_instance,
float value,
bool Lighting_Output_Present_Value_Set(uint32_t object_instance, float value,
unsigned priority)
{
unsigned index = 0;
@@ -335,7 +320,7 @@ bool Lighting_Output_Present_Value_Set(
index = Lighting_Output_Instance_To_Index(object_instance);
if (index < MAX_LIGHTING_OUTPUTS) {
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ )) {
(priority != 6 /* reserved */)) {
priority--;
BIT_SET(Lighting_Output[index].Priority_Active_Bits, priority);
Lighting_Output[index].Priority_Array[priority] = value;
@@ -355,8 +340,7 @@ bool Lighting_Output_Present_Value_Set(
*
* @return true if values are within range and present-value is set.
*/
bool Lighting_Output_Present_Value_Relinquish(
uint32_t object_instance,
bool Lighting_Output_Present_Value_Relinquish(uint32_t object_instance,
unsigned priority)
{
unsigned index = 0;
@@ -365,7 +349,7 @@ bool Lighting_Output_Present_Value_Relinquish(
index = Lighting_Output_Instance_To_Index(object_instance);
if (index < MAX_LIGHTING_OUTPUTS) {
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ )) {
(priority != 6 /* reserved */)) {
priority--;
BIT_CLEAR(Lighting_Output[index].Priority_Active_Bits, priority);
Lighting_Output[index].Priority_Array[priority] = 0.0;
@@ -386,9 +370,8 @@ bool Lighting_Output_Present_Value_Relinquish(
*
* @return true if object-name was retrieved
*/
bool Lighting_Output_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Lighting_Output_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
char text_string[32] = "";
bool status = false;
@@ -397,7 +380,7 @@ bool Lighting_Output_Object_Name(
index = Lighting_Output_Instance_To_Index(object_instance);
if (index < MAX_LIGHTING_OUTPUTS) {
sprintf(text_string, "LIGHTING OUTPUT %lu",
(unsigned long) object_instance);
(unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
@@ -412,8 +395,7 @@ bool Lighting_Output_Object_Name(
*
* @return true if lighting command was set
*/
bool Lighting_Output_Lighting_Command_Set(
uint32_t object_instance,
bool Lighting_Output_Lighting_Command_Set(uint32_t object_instance,
BACNET_LIGHTING_COMMAND *value)
{
bool status = false;
@@ -422,8 +404,7 @@ bool Lighting_Output_Lighting_Command_Set(
index = Lighting_Output_Instance_To_Index(object_instance);
if (index < MAX_LIGHTING_OUTPUTS) {
// FIXME: check lighting command member values
status = lighting_command_copy(
&Lighting_Output[index].Lighting_Command,
status = lighting_command_copy(&Lighting_Output[index].Lighting_Command,
value);
// FIXME: set all the other values, and get the light levels moving
}
@@ -439,8 +420,7 @@ bool Lighting_Output_Lighting_Command_Set(
*
* @return true if lighting command was retrieved
*/
bool Lighting_Output_Lighting_Command(
uint32_t object_instance,
bool Lighting_Output_Lighting_Command(uint32_t object_instance,
BACNET_LIGHTING_COMMAND *value)
{
bool status = false;
@@ -448,8 +428,8 @@ bool Lighting_Output_Lighting_Command(
index = Lighting_Output_Instance_To_Index(object_instance);
if (index < MAX_LIGHTING_OUTPUTS) {
status = lighting_command_copy(value,
&Lighting_Output[index].Lighting_Command);
status = lighting_command_copy(
value, &Lighting_Output[index].Lighting_Command);
}
return status;
@@ -485,8 +465,7 @@ BACNET_LIGHTING_IN_PROGRESS Lighting_Output_In_Progress(
*
* @return true if value was set
*/
bool Lighting_Output_In_Progress_Set(
uint32_t object_instance,
bool Lighting_Output_In_Progress_Set(uint32_t object_instance,
BACNET_LIGHTING_IN_PROGRESS in_progress)
{
bool status = false;
@@ -495,7 +474,6 @@ bool Lighting_Output_In_Progress_Set(
index = Lighting_Output_Instance_To_Index(object_instance);
if (index < MAX_LIGHTING_OUTPUTS) {
Lighting_Output[index].In_Progress = in_progress;
}
return status;
@@ -508,8 +486,7 @@ bool Lighting_Output_In_Progress_Set(
*
* @return the tracking-value of this object instance.
*/
float Lighting_Output_Tracking_Value(
uint32_t object_instance)
float Lighting_Output_Tracking_Value(uint32_t object_instance)
{
float value = 0.0;
unsigned index = 0;
@@ -531,9 +508,7 @@ float Lighting_Output_Tracking_Value(
*
* @return true if value was set
*/
bool Lighting_Output_Tracking_Value_Set(
uint32_t object_instance,
float value)
bool Lighting_Output_Tracking_Value_Set(uint32_t object_instance, float value)
{
bool status = false;
unsigned int index = 0;
@@ -555,8 +530,7 @@ bool Lighting_Output_Tracking_Value_Set(
*
* @return the blink-warn-enable property value of this object
*/
bool Lighting_Output_Blink_Warn_Enable(
uint32_t object_instance)
bool Lighting_Output_Blink_Warn_Enable(uint32_t object_instance)
{
bool value = false;
unsigned index = 0;
@@ -578,8 +552,7 @@ bool Lighting_Output_Blink_Warn_Enable(
*
* @return true if value was set
*/
bool Lighting_Output_Blink_Warn_Enable_Set(
uint32_t object_instance,
bool Lighting_Output_Blink_Warn_Enable_Set(uint32_t object_instance,
bool enable)
{
bool status = false;
@@ -602,8 +575,7 @@ bool Lighting_Output_Blink_Warn_Enable_Set(
*
* @return the egress-time property value of this object
*/
uint32_t Lighting_Output_Egress_Time(
uint32_t object_instance)
uint32_t Lighting_Output_Egress_Time(uint32_t object_instance)
{
uint32_t value = 0;
unsigned int index = 0;
@@ -625,9 +597,7 @@ uint32_t Lighting_Output_Egress_Time(
*
* @return true if value was set
*/
bool Lighting_Output_Egress_Time_Set(
uint32_t object_instance,
uint32_t seconds)
bool Lighting_Output_Egress_Time_Set(uint32_t object_instance, uint32_t seconds)
{
bool status = false;
unsigned int index = 0;
@@ -649,8 +619,7 @@ bool Lighting_Output_Egress_Time_Set(
*
* @return the egress-active property value of this object
*/
bool Lighting_Output_Egress_Active(
uint32_t object_instance)
bool Lighting_Output_Egress_Active(uint32_t object_instance)
{
bool value = false;
unsigned int index = 0;
@@ -671,8 +640,7 @@ bool Lighting_Output_Egress_Active(
*
* @return the fade-time property value of this object
*/
uint32_t Lighting_Output_Default_Fade_Time(
uint32_t object_instance)
uint32_t Lighting_Output_Default_Fade_Time(uint32_t object_instance)
{
uint32_t value = 0;
unsigned int index = 0;
@@ -694,16 +662,14 @@ uint32_t Lighting_Output_Default_Fade_Time(
*
* @return true if value was set
*/
bool Lighting_Output_Default_Fade_Time_Set(
uint32_t object_instance,
bool Lighting_Output_Default_Fade_Time_Set(uint32_t object_instance,
uint32_t milliseconds)
{
bool status = false;
unsigned int index = 0;
index = Lighting_Output_Instance_To_Index(object_instance);
if ((index < MAX_LIGHTING_OUTPUTS) &&
(milliseconds >= 100) &&
if ((index < MAX_LIGHTING_OUTPUTS) && (milliseconds >= 100) &&
(milliseconds <= 86400000)) {
Lighting_Output[index].Default_Fade_Time = milliseconds;
status = true;
@@ -720,8 +686,7 @@ bool Lighting_Output_Default_Fade_Time_Set(
*
* @return the ramp-rate property value of this object
*/
float Lighting_Output_Default_Ramp_Rate(
uint32_t object_instance)
float Lighting_Output_Default_Ramp_Rate(uint32_t object_instance)
{
float value = 0.0;
unsigned int index = 0;
@@ -743,16 +708,14 @@ float Lighting_Output_Default_Ramp_Rate(
*
* @return true if value was set
*/
bool Lighting_Output_Default_Ramp_Rate_Set(
uint32_t object_instance,
bool Lighting_Output_Default_Ramp_Rate_Set(uint32_t object_instance,
float percent_per_second)
{
bool status = false;
unsigned int index = 0;
index = Lighting_Output_Instance_To_Index(object_instance);
if ((index < MAX_LIGHTING_OUTPUTS) &&
(percent_per_second >= 0.1) &&
if ((index < MAX_LIGHTING_OUTPUTS) && (percent_per_second >= 0.1) &&
(percent_per_second <= 100.0)) {
Lighting_Output[index].Default_Ramp_Rate = percent_per_second;
status = true;
@@ -769,8 +732,7 @@ bool Lighting_Output_Default_Ramp_Rate_Set(
*
* @return the default-step-increment property value of this object
*/
float Lighting_Output_Default_Step_Increment(
uint32_t object_instance)
float Lighting_Output_Default_Step_Increment(uint32_t object_instance)
{
float value = 0.0;
unsigned int index = 0;
@@ -792,16 +754,14 @@ float Lighting_Output_Default_Step_Increment(
*
* @return true if value was set
*/
bool Lighting_Output_Default_Step_Increment_Set(
uint32_t object_instance,
bool Lighting_Output_Default_Step_Increment_Set(uint32_t object_instance,
float step_increment)
{
bool status = false;
unsigned int index = 0;
index = Lighting_Output_Instance_To_Index(object_instance);
if ((index < MAX_LIGHTING_OUTPUTS) &&
(step_increment >= 0.1) &&
if ((index < MAX_LIGHTING_OUTPUTS) && (step_increment >= 0.1) &&
(step_increment <= 100.0)) {
Lighting_Output[index].Default_Step_Increment = step_increment;
status = true;
@@ -820,8 +780,7 @@ bool Lighting_Output_Default_Step_Increment_Set(
* @return the lighting-command-default-priority property value of
* this object
*/
unsigned Lighting_Output_Default_Priority(
uint32_t object_instance)
unsigned Lighting_Output_Default_Priority(uint32_t object_instance)
{
unsigned value = 0;
unsigned int index = 0;
@@ -843,16 +802,14 @@ unsigned Lighting_Output_Default_Priority(
*
* @return true if value was set
*/
bool Lighting_Output_Default_Priority_Set(
uint32_t object_instance,
bool Lighting_Output_Default_Priority_Set(uint32_t object_instance,
unsigned priority)
{
bool status = false;
unsigned int index = 0;
index = Lighting_Output_Instance_To_Index(object_instance);
if ((index < MAX_LIGHTING_OUTPUTS) &&
(priority >= BACNET_MIN_PRIORITY) &&
if ((index < MAX_LIGHTING_OUTPUTS) && (priority >= BACNET_MIN_PRIORITY) &&
(priority <= BACNET_MAX_PRIORITY)) {
Lighting_Output[index].Lighting_Command_Default_Priority = priority;
status = true;
@@ -869,8 +826,7 @@ bool Lighting_Output_Default_Priority_Set(
*
* @return out-of-service property value
*/
bool Lighting_Output_Out_Of_Service(
uint32_t object_instance)
bool Lighting_Output_Out_Of_Service(uint32_t object_instance)
{
bool value = false;
unsigned int index = 0;
@@ -891,9 +847,7 @@ bool Lighting_Output_Out_Of_Service(
*
* @return true if the out-of-service property value was set
*/
void Lighting_Output_Out_Of_Service_Set(
uint32_t object_instance,
bool value)
void Lighting_Output_Out_Of_Service_Set(uint32_t object_instance, bool value)
{
unsigned int index = 0;
@@ -911,8 +865,7 @@ void Lighting_Output_Out_Of_Service_Set(
*
* @return relinquish-default property value
*/
float Lighting_Output_Relinquish_Default(
uint32_t object_instance)
float Lighting_Output_Relinquish_Default(uint32_t object_instance)
{
float value = 0.0;
unsigned int index = 0;
@@ -934,8 +887,7 @@ float Lighting_Output_Relinquish_Default(
*
* @return true if the relinquish-default property value was set
*/
bool Lighting_Output_Relinquish_Default_Set(
uint32_t object_instance,
bool Lighting_Output_Relinquish_Default_Set(uint32_t object_instance,
float value)
{
bool status = false;
@@ -959,15 +911,14 @@ bool Lighting_Output_Relinquish_Default_Set(
* @return number of APDU bytes in the response, or
* BACNET_STATUS_ERROR on error.
*/
int Lighting_Output_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Lighting_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
BACNET_LIGHTING_COMMAND lighting_command;
float real_value = (float) 1.414;
float real_value = (float)1.414;
uint32_t unsigned_value = 0;
unsigned i = 0;
bool state = false;
@@ -980,9 +931,8 @@ int Lighting_Output_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_LIGHTING_OUTPUT,
rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_LIGHTING_OUTPUT, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
Lighting_Output_Object_Name(rpdata->object_instance, &char_string);
@@ -1003,17 +953,14 @@ int Lighting_Output_Read_Property(
apdu_len = encode_application_real(&apdu[0], real_value);
break;
case PROP_LIGHTING_COMMAND:
Lighting_Output_Lighting_Command(
rpdata->object_instance,
&lighting_command);
apdu_len = lighting_command_encode(&apdu[0],
Lighting_Output_Lighting_Command(rpdata->object_instance,
&lighting_command);
apdu_len = lighting_command_encode(&apdu[0], &lighting_command);
break;
case PROP_IN_PROGRESS:
unsigned_value = Lighting_Output_In_Progress(
rpdata->object_instance);
apdu_len = encode_application_enumerated(&apdu[0],
unsigned_value);
unsigned_value =
Lighting_Output_In_Progress(rpdata->object_instance);
apdu_len = encode_application_enumerated(&apdu[0], unsigned_value);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
@@ -1033,20 +980,18 @@ int Lighting_Output_Read_Property(
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_EGRESS_TIME:
unsigned_value = Lighting_Output_Egress_Time(
rpdata->object_instance);
apdu_len = encode_application_unsigned(&apdu[0],
unsigned_value);
unsigned_value =
Lighting_Output_Egress_Time(rpdata->object_instance);
apdu_len = encode_application_unsigned(&apdu[0], unsigned_value);
break;
case PROP_EGRESS_ACTIVE:
state = Lighting_Output_Egress_Active(rpdata->object_instance);
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_DEFAULT_FADE_TIME:
unsigned_value = Lighting_Output_Default_Fade_Time(
rpdata->object_instance);
apdu_len = encode_application_unsigned(&apdu[0],
unsigned_value);
unsigned_value =
Lighting_Output_Default_Fade_Time(rpdata->object_instance);
apdu_len = encode_application_unsigned(&apdu[0], unsigned_value);
break;
case PROP_DEFAULT_RAMP_RATE:
real_value =
@@ -1063,16 +1008,16 @@ int Lighting_Output_Read_Property(
if (rpdata->array_index == 0) {
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* if no index was specified, then try to encode the entire list
*/
/* into one packet. */
} else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 1; i <= BACNET_MAX_PRIORITY; i++) {
if (Lighting_Output_Priority_Active(
rpdata->object_instance, i)) {
if (Lighting_Output_Priority_Active(rpdata->object_instance,
i)) {
real_value = Lighting_Output_Priority_Value(
rpdata->object_instance, i);
len =
encode_application_real(&apdu[apdu_len],
len = encode_application_real(&apdu[apdu_len],
real_value);
} else {
len = encode_application_null(&apdu[apdu_len]);
@@ -1089,14 +1034,11 @@ int Lighting_Output_Read_Property(
}
} else {
if (rpdata->array_index <= BACNET_MAX_PRIORITY) {
if (Lighting_Output_Priority_Active(
rpdata->object_instance,
if (Lighting_Output_Priority_Active(rpdata->object_instance,
rpdata->array_index)) {
real_value = Lighting_Output_Priority_Value(
rpdata->object_instance,
rpdata->array_index);
len =
encode_application_real(&apdu[apdu_len],
rpdata->object_instance, rpdata->array_index);
len = encode_application_real(&apdu[apdu_len],
real_value);
} else {
len = encode_application_null(&apdu[apdu_len]);
@@ -1109,15 +1051,14 @@ int Lighting_Output_Read_Property(
}
break;
case PROP_RELINQUISH_DEFAULT:
real_value = Lighting_Output_Relinquish_Default(
rpdata->object_instance);
real_value =
Lighting_Output_Relinquish_Default(rpdata->object_instance);
apdu_len = encode_application_real(&apdu[0], real_value);
break;
case PROP_LIGHTING_COMMAND_DEFAULT_PRIORITY:
unsigned_value = Lighting_Output_Default_Priority(
rpdata->object_instance);
apdu_len = encode_application_unsigned(&apdu[0],
unsigned_value);
unsigned_value =
Lighting_Output_Default_Priority(rpdata->object_instance);
apdu_len = encode_application_unsigned(&apdu[0], unsigned_value);
break;
default:
rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -1145,16 +1086,14 @@ int Lighting_Output_Read_Property(
*
* @return false if an error is loaded, true if no errors
*/
bool Lighting_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Lighting_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -1176,9 +1115,9 @@ bool Lighting_Output_Write_Property(
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
status =
Lighting_Output_Present_Value_Set(wp_data->object_instance,
value.type.Real, wp_data->priority);
status = Lighting_Output_Present_Value_Set(
wp_data->object_instance, value.type.Real,
wp_data->priority);
if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
@@ -1190,14 +1129,15 @@ bool Lighting_Output_Write_Property(
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class, &wp_data->error_code);
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class,
&wp_data->error_code);
if (status) {
if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. - Note Lighting_Output_Present_Value_Relinquish()
/* Command priority 6 is reserved for use by Minimum
On/Off algorithm and may not be used for other
purposes in any object. - Note
Lighting_Output_Present_Value_Relinquish()
will have returned false because of this */
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
@@ -1215,8 +1155,7 @@ bool Lighting_Output_Write_Property(
case PROP_LIGHTING_COMMAND:
if (value.tag == BACNET_APPLICATION_TAG_LIGHTING_COMMAND) {
status = Lighting_Output_Lighting_Command_Set(
wp_data->object_instance,
&value.type.Lighting_Command);
wp_data->object_instance, &value.type.Lighting_Command);
if (!status) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
@@ -1231,8 +1170,7 @@ bool Lighting_Output_Write_Property(
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class, &wp_data->error_code);
if (status) {
Lighting_Output_Out_Of_Service_Set(
wp_data->object_instance,
Lighting_Output_Out_Of_Service_Set(wp_data->object_instance,
value.type.Boolean);
}
break;
@@ -1270,13 +1208,11 @@ bool Lighting_Output_Write_Property(
* @param milliseconds - number of milliseconds elapsed since previously
* called. Works best when called about every 10 milliseconds.
*/
static void Lighting_Output_Ramp_Handler(
struct lighting_output_object *pLight,
static void Lighting_Output_Ramp_Handler(struct lighting_output_object *pLight,
BACNET_LIGHTING_COMMAND *pCommand,
uint16_t milliseconds)
{
if (pLight && pCommand) {
}
}
@@ -1288,13 +1224,11 @@ static void Lighting_Output_Ramp_Handler(
* @param milliseconds - number of milliseconds elapsed since previously
* called. Works best when called about every 10 milliseconds.
*/
static void Lighting_Output_Fade_Handler(
struct lighting_output_object *pLight,
static void Lighting_Output_Fade_Handler(struct lighting_output_object *pLight,
BACNET_LIGHTING_COMMAND *pCommand,
uint16_t milliseconds)
{
if (pLight && pCommand) {
}
}
@@ -1305,9 +1239,7 @@ static void Lighting_Output_Fade_Handler(
* @param milliseconds - number of milliseconds elapsed since previously
* called. Works best when called about every 10 milliseconds.
*/
static void Lighting_Output_Timer_Handler(
unsigned index,
uint16_t milliseconds)
static void Lighting_Output_Timer_Handler(unsigned index, uint16_t milliseconds)
{
struct lighting_output_object *pLight = NULL;
BACNET_LIGHTING_COMMAND *pCommand = NULL;
@@ -1352,8 +1284,7 @@ static void Lighting_Output_Timer_Handler(
* @param milliseconds - number of milliseconds elapsed since previously
* called. Works best when called about every 10 milliseconds.
*/
void Lighting_Output_Timer(
uint16_t milliseconds)
void Lighting_Output_Timer(uint16_t milliseconds)
{
unsigned i = 0;
@@ -1365,8 +1296,7 @@ void Lighting_Output_Timer(
/**
* Initializes the Lighting Output object data
*/
void Lighting_Output_Init(
void)
void Lighting_Output_Init(void)
{
unsigned i, p;
@@ -1410,11 +1340,9 @@ void Lighting_Output_Init(
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -1424,10 +1352,9 @@ bool WPValidateArgType(
return false;
}
void testLightingOutput(
Test * pTest)
void testLightingOutput(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -1454,8 +1381,7 @@ void testLightingOutput(
}
#ifdef TEST_LIGHTING_OUTPUT
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -1467,7 +1393,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+59 -93
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Life Safety Point Objects - customize for your use */
@@ -45,8 +45,7 @@
/* Here are our stored levels.*/
static BACNET_LIFE_SAFETY_MODE Life_Safety_Point_Mode[MAX_LIFE_SAFETY_POINTS];
static BACNET_LIFE_SAFETY_STATE
Life_Safety_Point_State[MAX_LIFE_SAFETY_POINTS];
static BACNET_LIFE_SAFETY_STATE Life_Safety_Point_State[MAX_LIFE_SAFETY_POINTS];
static BACNET_SILENCED_STATE
Life_Safety_Point_Silenced_State[MAX_LIFE_SAFETY_POINTS];
static BACNET_LIFE_SAFETY_OPERATION
@@ -57,30 +56,18 @@ static bool Life_Safety_Point_Out_Of_Service[MAX_LIFE_SAFETY_POINTS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Life_Safety_Point_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_TRACKING_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_RELIABILITY,
PROP_MODE,
PROP_ACCEPTED_MODES,
PROP_SILENCED,
PROP_OPERATION_EXPECTED,
-1
};
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_PRESENT_VALUE,
PROP_TRACKING_VALUE, PROP_STATUS_FLAGS,
PROP_EVENT_STATE, PROP_OUT_OF_SERVICE,
PROP_RELIABILITY, PROP_MODE,
PROP_ACCEPTED_MODES, PROP_SILENCED,
PROP_OPERATION_EXPECTED, -1};
static const int Life_Safety_Point_Properties_Optional[] = {
PROP_DESCRIPTION,
-1
};
static const int Life_Safety_Point_Properties_Optional[] = {PROP_DESCRIPTION,
-1};
static const int Life_Safety_Point_Properties_Proprietary[] = {
-1
};
static const int Life_Safety_Point_Properties_Proprietary[] = {-1};
/**
* Returns the list of required, optional, and proprietary properties.
@@ -93,8 +80,7 @@ static const int Life_Safety_Point_Properties_Proprietary[] = {
* @param pProprietary - pointer to list of int terminated by -1, of
* BACnet proprietary properties for this object.
*/
void Life_Safety_Point_Property_Lists(
const int **pRequired,
void Life_Safety_Point_Property_Lists(const int **pRequired,
const int **pOptional,
const int **pProprietary)
{
@@ -111,8 +97,7 @@ void Life_Safety_Point_Property_Lists(
return;
}
void Life_Safety_Point_Init(
void)
void Life_Safety_Point_Init(void)
{
static bool initialized = false;
unsigned i;
@@ -135,8 +120,7 @@ void Life_Safety_Point_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Life_Safety_Point_Valid_Instance(
uint32_t object_instance)
bool Life_Safety_Point_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_LIFE_SAFETY_POINTS)
return true;
@@ -146,8 +130,7 @@ bool Life_Safety_Point_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Life_Safety_Point_Count(
void)
unsigned Life_Safety_Point_Count(void)
{
return MAX_LIFE_SAFETY_POINTS;
}
@@ -155,8 +138,7 @@ unsigned Life_Safety_Point_Count(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Life_Safety_Point_Index_To_Instance(
unsigned index)
uint32_t Life_Safety_Point_Index_To_Instance(unsigned index)
{
return index;
}
@@ -164,8 +146,7 @@ uint32_t Life_Safety_Point_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Life_Safety_Point_Instance_To_Index(
uint32_t object_instance)
unsigned Life_Safety_Point_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_LIFE_SAFETY_POINTS;
@@ -189,9 +170,8 @@ static BACNET_LIFE_SAFETY_STATE Life_Safety_Point_Present_Value(
}
/* note: the object name must be unique within this device */
bool Life_Safety_Point_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Life_Safety_Point_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
static char text_string[32] = ""; /* okay for single thread */
bool status = false;
@@ -205,8 +185,7 @@ bool Life_Safety_Point_Object_Name(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Life_Safety_Point_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Life_Safety_Point_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
int apdu_len = 0; /* return value */
@@ -228,9 +207,8 @@ int Life_Safety_Point_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0],
OBJECT_LIFE_SAFETY_POINT, rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_LIFE_SAFETY_POINT, rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
@@ -240,8 +218,7 @@ int Life_Safety_Point_Read_Property(
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0],
apdu_len = encode_application_enumerated(&apdu[0],
OBJECT_LIFE_SAFETY_POINT);
break;
case PROP_PRESENT_VALUE:
@@ -320,8 +297,7 @@ int Life_Safety_Point_Read_Property(
}
/* returns true if successful */
bool Life_Safety_Point_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
unsigned int object_index = 0;
@@ -329,8 +305,7 @@ bool Life_Safety_Point_Write_Property(
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
@@ -352,9 +327,8 @@ bool Life_Safety_Point_Write_Property(
&wp_data->error_class, &wp_data->error_code);
if (status) {
if (value.type.Enumerated <= MAX_LIFE_SAFETY_MODE) {
object_index =
Life_Safety_Point_Instance_To_Index
(wp_data->object_instance);
object_index = Life_Safety_Point_Instance_To_Index(
wp_data->object_instance);
Life_Safety_Point_Mode[object_index] =
value.type.Enumerated;
} else {
@@ -369,16 +343,13 @@ bool Life_Safety_Point_Write_Property(
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class, &wp_data->error_code);
if (status) {
object_index =
Life_Safety_Point_Instance_To_Index
(wp_data->object_instance);
object_index = Life_Safety_Point_Instance_To_Index(
wp_data->object_instance);
Life_Safety_Point_Out_Of_Service[object_index] =
value.type.Boolean;
}
break;
case PROP_OBJECT_IDENTIFIER:
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
@@ -403,17 +374,14 @@ bool Life_Safety_Point_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -423,10 +391,9 @@ bool WPValidateArgType(
return false;
}
void testLifeSafetyPoint(
Test * pTest)
void testLifeSafetyPoint(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -453,8 +420,7 @@ void testLifeSafetyPoint(
}
#ifdef TEST_LIFE_SAFETY_POINT
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -466,7 +432,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
+110 -168
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Multi-state Input Objects */
@@ -59,29 +59,16 @@ static char State_Text[MAX_MULTISTATE_INPUTS][MULTISTATE_NUMBER_OF_STATES][64];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_NUMBER_OF_STATES,
-1
};
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1};
static const int Properties_Optional[] = {
PROP_DESCRIPTION,
PROP_STATE_TEXT,
-1
};
static const int Properties_Optional[] = {PROP_DESCRIPTION, PROP_STATE_TEXT,
-1};
static const int Properties_Proprietary[] = {
-1
};
static const int Properties_Proprietary[] = {-1};
void Multistate_Input_Property_Lists(
const int **pRequired,
void Multistate_Input_Property_Lists(const int **pRequired,
const int **pOptional,
const int **pProprietary)
{
@@ -95,8 +82,7 @@ void Multistate_Input_Property_Lists(
return;
}
void Multistate_Input_Init(
void)
void Multistate_Input_Init(void)
{
unsigned i;
@@ -113,8 +99,7 @@ void Multistate_Input_Init(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Multistate_Input_Instance_To_Index(
uint32_t object_instance)
unsigned Multistate_Input_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_MULTISTATE_INPUTS;
@@ -127,22 +112,19 @@ unsigned Multistate_Input_Instance_To_Index(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Multistate_Input_Index_To_Instance(
unsigned index)
uint32_t Multistate_Input_Index_To_Instance(unsigned index)
{
return index;
}
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Multistate_Input_Count(
void)
unsigned Multistate_Input_Count(void)
{
return MAX_MULTISTATE_INPUTS;
}
bool Multistate_Input_Valid_Instance(
uint32_t object_instance)
bool Multistate_Input_Valid_Instance(uint32_t object_instance)
{
unsigned index = 0; /* offset from instance lookup */
@@ -154,14 +136,12 @@ bool Multistate_Input_Valid_Instance(
return false;
}
static uint32_t Multistate_Input_Max_States(
uint32_t instance)
static uint32_t Multistate_Input_Max_States(uint32_t instance)
{
return MULTISTATE_NUMBER_OF_STATES;
}
uint32_t Multistate_Input_Present_Value(
uint32_t object_instance)
uint32_t Multistate_Input_Present_Value(uint32_t object_instance)
{
uint32_t value = 1;
unsigned index = 0; /* offset from instance lookup */
@@ -174,8 +154,7 @@ uint32_t Multistate_Input_Present_Value(
return value;
}
bool Multistate_Input_Present_Value_Set(
uint32_t object_instance,
bool Multistate_Input_Present_Value_Set(uint32_t object_instance,
uint32_t value)
{
bool status = false;
@@ -184,7 +163,7 @@ bool Multistate_Input_Present_Value_Set(
index = Multistate_Input_Instance_To_Index(object_instance);
if (index < MAX_MULTISTATE_INPUTS) {
if ((value > 0) && (value <= MULTISTATE_NUMBER_OF_STATES)) {
Present_Value[index] = (uint8_t) value;
Present_Value[index] = (uint8_t)value;
status = true;
}
}
@@ -192,8 +171,7 @@ bool Multistate_Input_Present_Value_Set(
return status;
}
bool Multistate_Input_Out_Of_Service(
uint32_t object_instance)
bool Multistate_Input_Out_Of_Service(uint32_t object_instance)
{
bool value = false;
unsigned index = 0;
@@ -206,9 +184,7 @@ bool Multistate_Input_Out_Of_Service(
return value;
}
void Multistate_Input_Out_Of_Service_Set(
uint32_t object_instance,
bool value)
void Multistate_Input_Out_Of_Service_Set(uint32_t object_instance, bool value)
{
unsigned index = 0;
@@ -220,8 +196,7 @@ void Multistate_Input_Out_Of_Service_Set(
return;
}
char *Multistate_Input_Description(
uint32_t object_instance)
char *Multistate_Input_Description(uint32_t object_instance)
{
unsigned index = 0; /* offset from instance lookup */
char *pName = NULL; /* return value */
@@ -234,9 +209,7 @@ char *Multistate_Input_Description(
return pName;
}
bool Multistate_Input_Description_Set(
uint32_t object_instance,
char *new_name)
bool Multistate_Input_Description_Set(uint32_t object_instance, char *new_name)
{
unsigned index = 0; /* offset from instance lookup */
size_t i = 0; /* loop counter */
@@ -263,10 +236,8 @@ bool Multistate_Input_Description_Set(
}
static bool Multistate_Input_Description_Write(
uint32_t object_instance,
BACNET_CHARACTER_STRING * char_string,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
uint32_t object_instance, BACNET_CHARACTER_STRING *char_string,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CODE *error_code)
{
unsigned index = 0; /* offset from instance lookup */
size_t length = 0;
@@ -279,8 +250,8 @@ static bool Multistate_Input_Description_Write(
if (length <= sizeof(Object_Description[index])) {
encoding = characterstring_encoding(char_string);
if (encoding == CHARACTER_UTF8) {
status =
characterstring_ansi_copy(Object_Description[index],
status = characterstring_ansi_copy(
Object_Description[index],
sizeof(Object_Description[index]), char_string);
if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
@@ -299,10 +270,8 @@ static bool Multistate_Input_Description_Write(
return status;
}
bool Multistate_Input_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
bool Multistate_Input_Object_Name(uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name)
{
unsigned index = 0; /* offset from instance lookup */
bool status = false;
@@ -316,9 +285,7 @@ bool Multistate_Input_Object_Name(
}
/* note: the object name must be unique within this device */
bool Multistate_Input_Name_Set(
uint32_t object_instance,
char *new_name)
bool Multistate_Input_Name_Set(uint32_t object_instance, char *new_name)
{
unsigned index = 0; /* offset from instance lookup */
size_t i = 0; /* loop counter */
@@ -346,10 +313,8 @@ bool Multistate_Input_Name_Set(
}
static bool Multistate_Input_Object_Name_Write(
uint32_t object_instance,
BACNET_CHARACTER_STRING * char_string,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
uint32_t object_instance, BACNET_CHARACTER_STRING *char_string,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CODE *error_code)
{
unsigned index = 0; /* offset from instance lookup */
size_t length = 0;
@@ -362,9 +327,9 @@ static bool Multistate_Input_Object_Name_Write(
if (length <= sizeof(Object_Name[index])) {
encoding = characterstring_encoding(char_string);
if (encoding == CHARACTER_UTF8) {
status =
characterstring_ansi_copy(Object_Name[index],
sizeof(Object_Name[index]), char_string);
status = characterstring_ansi_copy(Object_Name[index],
sizeof(Object_Name[index]),
char_string);
if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
@@ -382,8 +347,7 @@ static bool Multistate_Input_Object_Name_Write(
return status;
}
char *Multistate_Input_State_Text(
uint32_t object_instance,
char *Multistate_Input_State_Text(uint32_t object_instance,
uint32_t state_index)
{
unsigned index = 0; /* offset from instance lookup */
@@ -400,10 +364,8 @@ char *Multistate_Input_State_Text(
}
/* note: the object name must be unique within this device */
bool Multistate_Input_State_Text_Set(
uint32_t object_instance,
uint32_t state_index,
char *new_name)
bool Multistate_Input_State_Text_Set(uint32_t object_instance,
uint32_t state_index, char *new_name)
{
unsigned index = 0; /* offset from instance lookup */
size_t i = 0; /* loop counter */
@@ -428,15 +390,14 @@ bool Multistate_Input_State_Text_Set(
}
}
return status;;
return status;
;
}
static bool Multistate_Input_State_Text_Write(
uint32_t object_instance,
uint32_t state_index,
BACNET_CHARACTER_STRING * char_string,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
uint32_t object_instance, uint32_t state_index,
BACNET_CHARACTER_STRING *char_string, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code)
{
unsigned index = 0; /* offset from instance lookup */
size_t length = 0;
@@ -451,8 +412,8 @@ static bool Multistate_Input_State_Text_Write(
if (length <= sizeof(State_Text[index][state_index])) {
encoding = characterstring_encoding(char_string);
if (encoding == CHARACTER_UTF8) {
status =
characterstring_ansi_copy(State_Text[index][state_index],
status = characterstring_ansi_copy(
State_Text[index][state_index],
sizeof(State_Text[index][state_index]), char_string);
if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
@@ -475,8 +436,7 @@ static bool Multistate_Input_State_Text_Write(
}
/* return apdu len, or BACNET_STATUS_ERROR on error */
int Multistate_Input_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
int Multistate_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
{
int len = 0;
int apdu_len = 0; /* return value */
@@ -495,27 +455,25 @@ int Multistate_Input_Read_Property(
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0],
OBJECT_MULTI_STATE_INPUT, rpdata->object_instance);
apdu_len = encode_application_object_id(
&apdu[0], OBJECT_MULTI_STATE_INPUT, rpdata->object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
Multistate_Input_Object_Name(rpdata->object_instance,
&char_string);
Multistate_Input_Object_Name(rpdata->object_instance, &char_string);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
characterstring_init_ansi(
&char_string,
Multistate_Input_Description(rpdata->object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0],
apdu_len = encode_application_enumerated(&apdu[0],
OBJECT_MULTI_STATE_INPUT);
break;
case PROP_PRESENT_VALUE:
@@ -548,28 +506,28 @@ int Multistate_Input_Read_Property(
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_NUMBER_OF_STATES:
apdu_len =
encode_application_unsigned(&apdu[apdu_len],
apdu_len = encode_application_unsigned(
&apdu[apdu_len],
Multistate_Input_Max_States(rpdata->object_instance));
break;
case PROP_STATE_TEXT:
if (rpdata->array_index == 0) {
/* Array element zero is the number of elements in the array */
apdu_len =
encode_application_unsigned(&apdu[0],
apdu_len = encode_application_unsigned(
&apdu[0],
Multistate_Input_Max_States(rpdata->object_instance));
} 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. */
max_states =
Multistate_Input_Max_States(rpdata->object_instance);
for (i = 1; i <= max_states; i++) {
characterstring_init_ansi(&char_string,
Multistate_Input_State_Text(rpdata->object_instance,
i));
Multistate_Input_State_Text(
rpdata->object_instance, i));
/* FIXME: this might go beyond MAX_APDU length! */
len =
encode_application_character_string(&apdu[apdu_len],
len = encode_application_character_string(&apdu[apdu_len],
&char_string);
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU) {
@@ -585,12 +543,12 @@ int Multistate_Input_Read_Property(
max_states =
Multistate_Input_Max_States(rpdata->object_instance);
if (rpdata->array_index <= max_states) {
characterstring_init_ansi(&char_string,
characterstring_init_ansi(
&char_string,
Multistate_Input_State_Text(rpdata->object_instance,
rpdata->array_index));
apdu_len =
encode_application_character_string(&apdu[0],
&char_string);
apdu_len = encode_application_character_string(
&apdu[0], &char_string);
} else {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -616,8 +574,7 @@ int Multistate_Input_Read_Property(
}
/* returns true if successful */
bool Multistate_Input_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
bool Multistate_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
bool status = false; /* return value */
int len = 0;
@@ -629,8 +586,7 @@ bool Multistate_Input_Write_Property(
uint32_t object_instance = 0;
/* decode the first chunk of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* len < application_data_len: extra data for arrays only */
if (len < 0) {
@@ -662,9 +618,8 @@ bool Multistate_Input_Write_Property(
wp_data->error_code = ERROR_CODE_DUPLICATE_NAME;
}
} else {
status =
Multistate_Input_Object_Name_Write(wp_data->
object_instance, &value.type.Character_String,
status = Multistate_Input_Object_Name_Write(
wp_data->object_instance, &value.type.Character_String,
&wp_data->error_class, &wp_data->error_code);
}
} else {
@@ -674,9 +629,8 @@ bool Multistate_Input_Write_Property(
break;
case PROP_DESCRIPTION:
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
status =
Multistate_Input_Description_Write(wp_data->
object_instance, &value.type.Character_String,
status = Multistate_Input_Description_Write(
wp_data->object_instance, &value.type.Character_String,
&wp_data->error_class, &wp_data->error_code);
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -688,9 +642,8 @@ bool Multistate_Input_Write_Property(
WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT,
&wp_data->error_class, &wp_data->error_code);
if (status) {
status =
Multistate_Input_Present_Value_Set
(wp_data->object_instance, value.type.Unsigned_Int);
status = Multistate_Input_Present_Value_Set(
wp_data->object_instance, value.type.Unsigned_Int);
if (!status) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
@@ -721,18 +674,16 @@ bool Multistate_Input_Write_Property(
element_len = len;
do {
if (element_len) {
status =
Multistate_Input_State_Text_Write(wp_data->
object_instance, array_index,
status = Multistate_Input_State_Text_Write(
wp_data->object_instance, array_index,
&value.type.Character_String,
&wp_data->error_class, &wp_data->error_code);
}
max_states--;
array_index++;
if (max_states) {
element_len =
bacapp_decode_application_data(&wp_data->
application_data[len],
element_len = bacapp_decode_application_data(
&wp_data->application_data[len],
wp_data->application_data_len - len, &value);
if (element_len < 0) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -747,11 +698,10 @@ bool Multistate_Input_Write_Property(
max_states =
Multistate_Input_Max_States(wp_data->object_instance);
if (wp_data->array_index <= max_states) {
status =
Multistate_Input_State_Text_Write(wp_data->
object_instance, wp_data->array_index,
&value.type.Character_String,
&wp_data->error_class, &wp_data->error_code);
status = Multistate_Input_State_Text_Write(
wp_data->object_instance, wp_data->array_index,
&value.type.Character_String, &wp_data->error_class,
&wp_data->error_code);
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
@@ -779,26 +729,20 @@ bool Multistate_Input_Write_Property(
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
bool Device_Valid_Object_Name(
BACNET_CHARACTER_STRING * object_name,
int *object_type,
uint32_t * object_instance)
bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name,
int *object_type, uint32_t *object_instance)
{
return true;
}
bool WPValidateArgType(
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE * pErrorCode)
bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode)
{
pValue = pValue;
ucExpectedTag = ucExpectedTag;
@@ -808,10 +752,9 @@ bool WPValidateArgType(
return false;
}
void testMultistateInput(
Test * pTest)
void testMultistateInput(Test *pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
uint8_t apdu[MAX_APDU] = {0};
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
@@ -838,8 +781,7 @@ void testMultistateInput(
}
#ifdef TEST_MULTISTATE_INPUT
int main(
void)
int main(void)
{
Test *pTest;
bool rc;
@@ -851,7 +793,7 @@ int main(
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;

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