Issue 2 move folders and use deep path include file names to prevent collisions (#4)

* moving folders and files and adjust server demo build

* Fix Makefile for apps/server on Linux

* fix unit test source file folders

* fix datetime convert UTC functions. Add Code::Blocks project for datetime testing

* added some ignore extensions

* disable parallel make option

* fix build for abort, dcc, and epics apps

* fix build for dcc, epics, error, and getevent apps.

* Fixed building of all apps

* fix the ipv4 to ipv6 router app build

* Change indent style from Google to Webkit

* make pretty to re-format style

* removed common Makefile since we already had one and two was too many

* remove scripts from root folder that are no longer maintained or used

* remove mercurial EOL and ignore files for git repo

* remove .vscodeconfig files from repo

* tweak clang-format style

* clang-format src and apps with tweaked style

* added clang-tidy to fix readability if braces in src

* result of make tidy for src and apps

* fix clang-tidy mangling

* Added code::blocks project for BACnet server simulation

* added code::blocks linux project for WhoIs app

* update text files for EOL

* fix EOL in some files

* fixed make win32 apps for older gcc

* Removed Borland C++ Makefile in apps. Unable to maintain support for Borland C++ compiler.

* created codeblocks project for apps/epics for Windows

* fixing ports/xplained to work with new data structure.

* fix ports/xplained example for Atmel Studio compile

* fix ports/stm32f10x example for gcc Makefile compile

* fix ports/stm32f10x example for IAR EWARM compile

* fix ports/xplained timer callback

* fix ports/bdk_atxx_mspt build with subdirs

* fix ports/bdk_atxx_mspt build with subdirs

* updated git ignore for IAR build artifacts

* updated gitignore for non-tracked files and folders

* fixed bdk-atxx4-mstp port for Rowley Crossworks project file

* fixed bdk-atxx4-mstp port for GCC AVR Makefile

* fixed atmega168 port for IAR AVR and GCC AVR Makefile

* fixed at91sam7s port for IAR ARM and GCC ARM Makefile

* removed unmaintainable DOS, RTOS32, and atmega8 ports.  Updated rx62n (untested).

* changed arm7 to uip port
This commit is contained in:
Steve Karg
2019-12-13 15:19:10 -06:00
committed by GitHub
parent 8a38dbe2cf
commit d50c190957
912 changed files with 36206 additions and 52502 deletions
+400
View File
@@ -0,0 +1,400 @@
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2005 Steve Karg
Corrections by Ferran Arumi, 2007, Barcelona, Spain
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based
on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However
the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public
License.
-------------------------------------------
####COPYRIGHTEND####*/
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include "bacnet/bits.h"
#include "bacnet/apdu.h"
#include "bacnet/bacaddr.h"
#include "bacnet/bacdef.h"
#include "bacnet/bacdcode.h"
#include "bacnet/bacenum.h"
#include "bacnet/config.h"
#include "bacnet/basic/tsm/tsm.h"
#include "bacnet/datalink/datalink.h"
#include "bacnet/basic/services.h"
#include "bacnet/basic/binding/address.h"
/** @file tsm.c BACnet Transaction State Machine operations */
/* FIXME: modify basic service handlers to use TSM rather than this buffer! */
uint8_t Handler_Transmit_Buffer[MAX_PDU] = { 0 };
#if (MAX_TSM_TRANSACTIONS)
/* Really only needed for segmented messages */
/* and a little for sending confirmed messages */
/* If we are only a server and only initiate broadcasts, */
/* then we don't need a TSM layer. */
/* FIXME: not coded for segmentation */
/* declare space for the TSM transactions, and set it up in the init. */
/* table rules: an Invoke ID = 0 is an unused spot in the table */
static BACNET_TSM_DATA TSM_List[MAX_TSM_TRANSACTIONS];
/* invoke ID for incrementing between subsequent calls. */
static uint8_t Current_Invoke_ID = 1;
static tsm_timeout_function Timeout_Function;
void tsm_set_timeout_handler(tsm_timeout_function pFunction)
{
Timeout_Function = pFunction;
}
/* returns MAX_TSM_TRANSACTIONS if not found */
static uint8_t tsm_find_invokeID_index(uint8_t invokeID)
{
unsigned i = 0; /* counter */
uint8_t index = MAX_TSM_TRANSACTIONS; /* return value */
for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) {
if (TSM_List[i].InvokeID == invokeID) {
index = (uint8_t)i;
break;
}
}
return index;
}
static uint8_t tsm_find_first_free_index(void)
{
unsigned i = 0; /* counter */
uint8_t index = MAX_TSM_TRANSACTIONS; /* return value */
for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) {
if (TSM_List[i].InvokeID == 0) {
index = (uint8_t)i;
break;
}
}
return index;
}
bool tsm_transaction_available(void)
{
bool status = false; /* return value */
unsigned i = 0; /* counter */
for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) {
if (TSM_List[i].InvokeID == 0) {
/* one is available! */
status = true;
break;
}
}
return status;
}
uint8_t tsm_transaction_idle_count(void)
{
uint8_t count = 0; /* return value */
unsigned i = 0; /* counter */
for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) {
if ((TSM_List[i].InvokeID == 0) &&
(TSM_List[i].state == TSM_STATE_IDLE)) {
/* one is available! */
count++;
}
}
return count;
}
/* sets the invokeID */
void tsm_invokeID_set(uint8_t invokeID)
{
if (invokeID == 0) {
invokeID = 1;
}
Current_Invoke_ID = invokeID;
}
/* gets the next free invokeID,
and reserves a spot in the table
returns 0 if none are available */
uint8_t tsm_next_free_invokeID(void)
{
uint8_t index = 0;
uint8_t invokeID = 0;
bool found = false;
/* is there even space available? */
if (tsm_transaction_available()) {
while (!found) {
index = tsm_find_invokeID_index(Current_Invoke_ID);
if (index == MAX_TSM_TRANSACTIONS) {
/* Not found, so this invokeID is not used */
found = true;
/* set this id into the table */
index = tsm_find_first_free_index();
if (index != MAX_TSM_TRANSACTIONS) {
TSM_List[index].InvokeID = invokeID = Current_Invoke_ID;
TSM_List[index].state = TSM_STATE_IDLE;
TSM_List[index].RequestTimer = apdu_timeout();
/* update for the next call or check */
Current_Invoke_ID++;
/* skip zero - we treat that internally as invalid or no
* free */
if (Current_Invoke_ID == 0) {
Current_Invoke_ID = 1;
}
}
} else {
/* found! This invokeID is already used */
/* try next one */
Current_Invoke_ID++;
/* skip zero - we treat that internally as invalid or no free */
if (Current_Invoke_ID == 0) {
Current_Invoke_ID = 1;
}
}
}
}
return invokeID;
}
void tsm_set_confirmed_unsegmented_transaction(uint8_t invokeID,
BACNET_ADDRESS *dest,
BACNET_NPDU_DATA *ndpu_data,
uint8_t *apdu,
uint16_t apdu_len)
{
uint16_t j = 0;
uint8_t index;
if (invokeID) {
index = tsm_find_invokeID_index(invokeID);
if (index < MAX_TSM_TRANSACTIONS) {
/* SendConfirmedUnsegmented */
TSM_List[index].state = TSM_STATE_AWAIT_CONFIRMATION;
TSM_List[index].RetryCount = 0;
/* start the timer */
TSM_List[index].RequestTimer = apdu_timeout();
/* copy the data */
for (j = 0; j < apdu_len; j++) {
TSM_List[index].apdu[j] = apdu[j];
}
TSM_List[index].apdu_len = apdu_len;
npdu_copy_data(&TSM_List[index].npdu_data, ndpu_data);
bacnet_address_copy(&TSM_List[index].dest, dest);
}
}
return;
}
/* used to retrieve the transaction payload */
/* if we wanted to find out what we sent (i.e. when we get an ack) */
bool tsm_get_transaction_pdu(uint8_t invokeID,
BACNET_ADDRESS *dest,
BACNET_NPDU_DATA *ndpu_data,
uint8_t *apdu,
uint16_t *apdu_len)
{
uint16_t j = 0;
uint8_t index;
bool found = false;
if (invokeID) {
index = tsm_find_invokeID_index(invokeID);
/* how much checking is needed? state? dest match? just invokeID? */
if (index < MAX_TSM_TRANSACTIONS) {
/* FIXME: we may want to free the transaction so it doesn't timeout
*/
/* retrieve the transaction */
/* FIXME: bounds check the pdu_len? */
*apdu_len = (uint16_t)TSM_List[index].apdu_len;
for (j = 0; j < *apdu_len; j++) {
apdu[j] = TSM_List[index].apdu[j];
}
npdu_copy_data(ndpu_data, &TSM_List[index].npdu_data);
bacnet_address_copy(dest, &TSM_List[index].dest);
found = true;
}
}
return found;
}
/* called once a millisecond or slower */
void tsm_timer_milliseconds(uint16_t milliseconds)
{
unsigned i = 0; /* counter */
for (i = 0; i < MAX_TSM_TRANSACTIONS; i++) {
if (TSM_List[i].state == TSM_STATE_AWAIT_CONFIRMATION) {
if (TSM_List[i].RequestTimer > milliseconds) {
TSM_List[i].RequestTimer -= milliseconds;
} else {
TSM_List[i].RequestTimer = 0;
}
/* AWAIT_CONFIRMATION */
if (TSM_List[i].RequestTimer == 0) {
if (TSM_List[i].RetryCount < apdu_retries()) {
TSM_List[i].RequestTimer = apdu_timeout();
TSM_List[i].RetryCount++;
datalink_send_pdu(&TSM_List[i].dest, &TSM_List[i].npdu_data,
&TSM_List[i].apdu[0], TSM_List[i].apdu_len);
} else {
/* note: the invoke id has not been cleared yet
and this indicates a failed message:
IDLE and a valid invoke id */
TSM_List[i].state = TSM_STATE_IDLE;
if (TSM_List[i].InvokeID != 0) {
if (Timeout_Function) {
Timeout_Function(TSM_List[i].InvokeID);
}
}
}
}
}
}
}
/* frees the invokeID and sets its state to IDLE */
void tsm_free_invoke_id(uint8_t invokeID)
{
uint8_t index;
index = tsm_find_invokeID_index(invokeID);
if (index < MAX_TSM_TRANSACTIONS) {
TSM_List[index].state = TSM_STATE_IDLE;
TSM_List[index].InvokeID = 0;
}
}
/** Check if the invoke ID has been made free by the Transaction State Machine.
* @param invokeID [in] The invokeID to be checked, normally of last message
* sent.
* @return True if it is free (done with), False if still pending in the TSM.
*/
bool tsm_invoke_id_free(uint8_t invokeID)
{
bool status = true;
uint8_t index;
index = tsm_find_invokeID_index(invokeID);
if (index < MAX_TSM_TRANSACTIONS) {
status = false;
}
return status;
}
/** See if we failed get a confirmation for the message associated
* with this invoke ID.
* @param invokeID [in] The invokeID to be checked, normally of last message
* sent.
* @return True if already failed, False if done or segmented or still waiting
* for a confirmation.
*/
bool tsm_invoke_id_failed(uint8_t invokeID)
{
bool status = false;
uint8_t index;
index = tsm_find_invokeID_index(invokeID);
if (index < MAX_TSM_TRANSACTIONS) {
/* a valid invoke ID and the state is IDLE is a
message that failed to confirm */
if (TSM_List[index].state == TSM_STATE_IDLE) {
status = true;
}
}
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
/* flag to send an I-Am */
bool I_Am_Request = true;
/* dummy function stubs */
int datalink_send_pdu(BACNET_ADDRESS *dest,
BACNET_NPDU_DATA *npdu_data,
uint8_t *pdu,
unsigned pdu_len)
{
(void)dest;
(void)npdu_data;
(void)pdu;
(void)pdu_len;
return 0;
}
/* dummy function stubs */
void datalink_get_broadcast_address(BACNET_ADDRESS *dest)
{
(void)dest;
}
void testTSM(Test *pTest)
{
/* FIXME: add some unit testing... */
return;
}
#ifdef TEST_TSM
int main(void)
{
Test *pTest;
bool rc;
pTest = ct_create("BACnet TSM", NULL);
/* individual tests */
rc = ct_addTestFunction(pTest, testTSM);
assert(rc);
ct_setStream(pTest, stdout);
ct_run(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
}
#endif /* TEST_TSM */
#endif /* TEST */
#endif /* MAX_TSM_TRANSACTIONS */
+139
View File
@@ -0,0 +1,139 @@
/**************************************************************************
*
* 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.
*********************************************************************/
#ifndef TSM_H
#define TSM_H
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include "bacnet/config.h"
#include "bacnet/bacdef.h"
#include "bacnet/npdu.h"
/* note: TSM functionality is optional - only needed if we are
doing client requests */
/* FIXME: modify basic service handlers to use TSM rather than this buffer! */
extern uint8_t Handler_Transmit_Buffer[MAX_PDU];
#if (!MAX_TSM_TRANSACTIONS)
#define tsm_free_invoke_id(x) (void)x;
#else
typedef enum {
TSM_STATE_IDLE,
TSM_STATE_AWAIT_CONFIRMATION,
TSM_STATE_AWAIT_RESPONSE,
TSM_STATE_SEGMENTED_REQUEST,
TSM_STATE_SEGMENTED_CONFIRMATION
} BACNET_TSM_STATE;
/* 5.4.1 Variables And Parameters */
/* The following variables are defined for each instance of */
/* Transaction State Machine: */
typedef struct BACnet_TSM_Data {
/* used to count APDU retries */
uint8_t RetryCount;
/* used to count segment retries */
/*uint8_t SegmentRetryCount; */
/* used to control APDU retries and the acceptance of server replies */
/*bool SentAllSegments; */
/* stores the sequence number of the last segment received in order */
/*uint8_t LastSequenceNumber; */
/* stores the sequence number of the first segment of */
/* a sequence of segments that fill a window */
/*uint8_t InitialSequenceNumber; */
/* stores the current window size */
/*uint8_t ActualWindowSize; */
/* stores the window size proposed by the segment sender */
/*uint8_t ProposedWindowSize; */
/* used to perform timeout on PDU segments */
/*uint8_t SegmentTimer; */
/* used to perform timeout on Confirmed Requests */
/* in milliseconds */
uint16_t RequestTimer;
/* unique id */
uint8_t InvokeID;
/* state that the TSM is in */
BACNET_TSM_STATE state;
/* the address we sent it to */
BACNET_ADDRESS dest;
/* the network layer info */
BACNET_NPDU_DATA npdu_data;
/* copy of the APDU, should we need to send it again */
uint8_t apdu[MAX_PDU];
unsigned apdu_len;
} BACNET_TSM_DATA;
typedef void (
*tsm_timeout_function) (
uint8_t invoke_id);
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void tsm_set_timeout_handler(
tsm_timeout_function pFunction);
bool tsm_transaction_available(
void);
uint8_t tsm_transaction_idle_count(
void);
void tsm_timer_milliseconds(
uint16_t milliseconds);
/* free the invoke ID when the reply comes back */
void tsm_free_invoke_id(
uint8_t invokeID);
/* use these in tandem */
uint8_t tsm_next_free_invokeID(
void);
void tsm_invokeID_set(
uint8_t invokeID);
/* returns the same invoke ID that was given */
void tsm_set_confirmed_unsegmented_transaction(
uint8_t invokeID,
BACNET_ADDRESS * dest,
BACNET_NPDU_DATA * ndpu_data,
uint8_t * apdu,
uint16_t apdu_len);
/* returns true if transaction is found */
bool tsm_get_transaction_pdu(
uint8_t invokeID,
BACNET_ADDRESS * dest,
BACNET_NPDU_DATA * ndpu_data,
uint8_t * apdu,
uint16_t * apdu_len);
bool tsm_invoke_id_free(
uint8_t invokeID);
bool tsm_invoke_id_failed(
uint8_t invokeID);
#ifdef __cplusplus
}
#endif /* __cplusplus */
/* define out any functions necessary for compile */
#endif
#endif