cb243c36a8
* Change MIT license texts to SPDX-License-Identifier SPDX-License-Identifier is much easier to understand and grep than license text so use that instead. * Change GPL exception license texts to SPDX-License-Identifier SPDX-License-Identifier is much easier to understand and grep than license text so use that instead. * Change misc license texts to SPDX-License-Identifier There are some external code in repo which are not licenses as most of the stuff in this repo. We still want every file to have SPDX identifier to easily grep licenses. * Add currently used license files Even though Bacnet-Stack is using SPDX identifiers we still need to give those license files with source. For this reason add all license files to license/ folder. SPDX has also files which would make same thing but this is style which example Linux kernel is using and it is quite clear so I choose that one for now. I choosed not yet bring CC-PDDC as that is not right license for those files. --------- Co-authored-by: Kari Argillander <kari.argillander@fidelix.com>
111 lines
3.8 KiB
C
111 lines
3.8 KiB
C
/**************************************************************************
|
|
*
|
|
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
*********************************************************************/
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
/* BACnet Stack defines - first */
|
|
#include "bacnet/bacdef.h"
|
|
/* BACnet Stack API */
|
|
#include "bacnet/bacdcode.h"
|
|
#include "bacnet/npdu.h"
|
|
#include "bacnet/apdu.h"
|
|
#include "bacnet/dcc.h"
|
|
/* some demo stuff needed */
|
|
#include "bacnet/basic/binding/address.h"
|
|
#include "bacnet/basic/tsm/tsm.h"
|
|
#include "bacnet/basic/object/device.h"
|
|
#include "bacnet/datalink/datalink.h"
|
|
#include "bacnet/basic/services.h"
|
|
|
|
/** @file s_dcc.c Send a Device Communication Control (DCC) request. */
|
|
|
|
/** Sends a Device Communication Control (DCC) request.
|
|
* @ingroup DMDCC
|
|
*
|
|
* @param device_id [in] The index to the device address in our address cache.
|
|
* @param timeDuration [in] If non-zero, the minutes that the remote device
|
|
* shall ignore all APDUs except DCC and, if supported, RD APDUs.
|
|
* @param state [in] Choice to Enable or Disable communication.
|
|
* @param password [in] Optional password, up to 20 chars.
|
|
* @return The invokeID of the transmitted message, or 0 on failure.
|
|
*/
|
|
|
|
uint8_t Send_Device_Communication_Control_Request(uint32_t device_id,
|
|
uint16_t timeDuration, /* 0=optional */
|
|
BACNET_COMMUNICATION_ENABLE_DISABLE state,
|
|
char *password)
|
|
{ /* NULL=optional */
|
|
BACNET_ADDRESS dest;
|
|
BACNET_ADDRESS my_address;
|
|
unsigned max_apdu = 0;
|
|
uint8_t invoke_id = 0;
|
|
bool status = false;
|
|
int len = 0;
|
|
int pdu_len = 0;
|
|
#if PRINT_ENABLED
|
|
int bytes_sent = 0;
|
|
#endif
|
|
BACNET_CHARACTER_STRING password_string;
|
|
BACNET_NPDU_DATA npdu_data;
|
|
|
|
/* if we are forbidden to send, don't send! */
|
|
if (!dcc_communication_enabled()) {
|
|
return 0;
|
|
}
|
|
|
|
/* is the device bound? */
|
|
status = address_get_by_device(device_id, &max_apdu, &dest);
|
|
/* is there a tsm available? */
|
|
if (status) {
|
|
invoke_id = tsm_next_free_invokeID();
|
|
}
|
|
if (invoke_id) {
|
|
/* 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);
|
|
/* 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);
|
|
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);
|
|
#if PRINT_ENABLED
|
|
bytes_sent =
|
|
#endif
|
|
datalink_send_pdu(
|
|
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
|
#if PRINT_ENABLED
|
|
if (bytes_sent <= 0)
|
|
fprintf(stderr,
|
|
"Failed to Send DeviceCommunicationControl Request (%s)!\n",
|
|
strerror(errno));
|
|
#endif
|
|
} else {
|
|
tsm_free_invoke_id(invoke_id);
|
|
invoke_id = 0;
|
|
#if PRINT_ENABLED
|
|
fprintf(stderr,
|
|
"Failed to Send DeviceCommunicationControl Request "
|
|
"(exceeds destination maximum APDU)!\n");
|
|
#endif
|
|
}
|
|
}
|
|
|
|
return invoke_id;
|
|
}
|