added clang format C and H files.
This commit is contained in:
+50
-58
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
¤t_date_time->date,
|
||||
¤t_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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+70
-102
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+98
-168
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+87
-126
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
Reference in New Issue
Block a user