Bugfix/compiler warning (#172)

* Fix compiler and static analysis warning

* revise to use for loop pattern

Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2021-05-21 09:00:40 -05:00
committed by GitHub
parent cea8c0e64c
commit b38d975f35
2 changed files with 146 additions and 138 deletions
-1
View File
@@ -49,7 +49,6 @@
/* some demo stuff needed */ /* some demo stuff needed */
#include "bacnet/basic/sys/filename.h" #include "bacnet/basic/sys/filename.h"
#include "bacnet/basic/services.h" #include "bacnet/basic/services.h"
#include "bacnet/basic/services.h"
#include "bacnet/basic/tsm/tsm.h" #include "bacnet/basic/tsm/tsm.h"
#include "bacnet/datalink/dlenv.h" #include "bacnet/datalink/dlenv.h"
+146 -137
View File
@@ -36,12 +36,14 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "bacnet/bits.h"
#include "bacnet/config.h" #include "bacnet/config.h"
#include "bacnet/bacaddr.h" #include "bacnet/bacaddr.h"
#include "bacnet/bacdef.h" #include "bacnet/bacdef.h"
#include "bacnet/bacdcode.h" #include "bacnet/bacdcode.h"
#include "bacnet/readrange.h" #include "bacnet/readrange.h"
#include "bacnet/basic/binding/address.h" #include "bacnet/basic/binding/address.h"
#include "bacnet/basic/binding/address.h"
/* we are likely compiling the demo command line tools if print enabled */ /* we are likely compiling the demo command line tools if print enabled */
#if !defined(BACNET_ADDRESS_CACHE_FILE) #if !defined(BACNET_ADDRESS_CACHE_FILE)
@@ -59,6 +61,15 @@
static uint32_t Top_Protected_Entry; static uint32_t Top_Protected_Entry;
static uint32_t Own_Device_ID = 0xFFFFFFFF; static uint32_t Own_Device_ID = 0xFFFFFFFF;
/* The address cache is used for binding to BACnet devices */
/* The number of entries corresponds to the number of */
/* devices that might respond to an I-Am on the network. */
/* If your device is a simple server and does not need to bind, */
/* then you don't need to use this. */
#if !defined(MAX_ADDRESS_CACHE)
#define MAX_ADDRESS_CACHE 255
#endif
static struct Address_Cache_Entry { static struct Address_Cache_Entry {
uint8_t Flags; uint8_t Flags;
uint32_t device_id; uint32_t device_id;
@@ -69,13 +80,16 @@ static struct Address_Cache_Entry {
/* State flags for cache entries */ /* State flags for cache entries */
#define BAC_ADDR_IN_USE 1 /* Address cache entry in use */ /* Address cache entry in use */
#define BAC_ADDR_BIND_REQ 2 /* Bind request outstanding for entry */ #define BAC_ADDR_IN_USE BIT(0)
#define BAC_ADDR_STATIC 4 /* Static address mapping - does not expire */ /* Bind request outstanding for entry */
#define BAC_ADDR_SHORT_TTL \ #define BAC_ADDR_BIND_REQ BIT(1)
8 /* Oppertunistaclly added address with short TTL \ /* Static address mapping - does not expire */
*/ #define BAC_ADDR_STATIC BIT(2)
#define BAC_ADDR_RESERVED 128 /* Freed up but held for caller to fill */ /* Opportunistically added address with short TTL */
#define BAC_ADDR_SHORT_TTL BIT(3)
/* Freed up but held for caller to fill */
#define BAC_ADDR_RESERVED BIT(7)
#define BAC_ADDR_SECS_1HOUR 3600 /* 60x60 */ #define BAC_ADDR_SECS_1HOUR 3600 /* 60x60 */
#define BAC_ADDR_SECS_1DAY 86400 /* 60x60x24 */ #define BAC_ADDR_SECS_1DAY 86400 /* 60x60x24 */
@@ -170,8 +184,8 @@ void address_remove_device(uint32_t device_id)
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
uint32_t index = 0; uint32_t index = 0;
pMatch = Address_Cache; for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
if (((pMatch->Flags & BAC_ADDR_IN_USE) != 0) && if (((pMatch->Flags & BAC_ADDR_IN_USE) != 0) &&
(pMatch->device_id == device_id)) { (pMatch->device_id == device_id)) {
pMatch->Flags = 0; pMatch->Flags = 0;
@@ -180,8 +194,6 @@ void address_remove_device(uint32_t device_id)
} }
break; break;
} }
pMatch++;
index++;
} }
return; return;
@@ -201,39 +213,41 @@ static struct Address_Cache_Entry *address_remove_oldest(void)
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
struct Address_Cache_Entry *pCandidate; struct Address_Cache_Entry *pCandidate;
uint32_t ulTime; uint32_t ulTime;
unsigned index;
pCandidate = NULL; pCandidate = NULL;
if (Top_Protected_Entry > (MAX_ADDRESS_CACHE - 1)) { if (Top_Protected_Entry > (MAX_ADDRESS_CACHE - 1)) {
return pCandidate; return pCandidate;
} }
ulTime = /* Longest possible non static time to live */
BAC_ADDR_FOREVER - 1; /* Longest possible non static time to live */ ulTime = BAC_ADDR_FOREVER - 1;
/* First pass - try only in use and bound entries */ /* First pass - try only in use and bound entries */
pMatch = &Address_Cache[Top_Protected_Entry]; for (index = Top_Protected_Entry; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
if ((pMatch->Flags & if ((pMatch->Flags &
(BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ | BAC_ADDR_STATIC)) == (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ | BAC_ADDR_STATIC)) ==
BAC_ADDR_IN_USE) { BAC_ADDR_IN_USE) {
if (pMatch->TimeToLive <= ulTime) { /* Shorter lived entry found */ if (pMatch->TimeToLive <= ulTime) {
/* Shorter lived entry found */
ulTime = pMatch->TimeToLive; ulTime = pMatch->TimeToLive;
pCandidate = pMatch; pCandidate = pMatch;
} }
} }
pMatch++;
} }
if (pCandidate != NULL) { /* Found something to free up */ if (pCandidate != NULL) {
/* Found something to free up */
pCandidate->Flags = BAC_ADDR_RESERVED; pCandidate->Flags = BAC_ADDR_RESERVED;
pCandidate->TimeToLive = /* only reserve it for a short while */
BAC_ADDR_SHORT_TIME; /* only reserve it for a short while */ pCandidate->TimeToLive = BAC_ADDR_SHORT_TIME;
return (pCandidate); return (pCandidate);
} }
/* Second pass - try in use and un bound as last resort */ /* Second pass - try in use and un bound as last resort */
pMatch = Address_Cache; for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
if ((pMatch->Flags & if ((pMatch->Flags &
(BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ | BAC_ADDR_STATIC)) == (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ | BAC_ADDR_STATIC)) ==
((uint8_t)(BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ))) { ((uint8_t)(BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ))) {
@@ -242,13 +256,13 @@ static struct Address_Cache_Entry *address_remove_oldest(void)
pCandidate = pMatch; pCandidate = pMatch;
} }
} }
pMatch++;
} }
if (pCandidate != NULL) { /* Found something to free up */ if (pCandidate != NULL) {
/* Found something to free up */
pCandidate->Flags = BAC_ADDR_RESERVED; pCandidate->Flags = BAC_ADDR_RESERVED;
pCandidate->TimeToLive = /* only reserve it for a short while */
BAC_ADDR_SHORT_TIME; /* only reserve it for a short while */ pCandidate->TimeToLive = BAC_ADDR_SHORT_TIME;
} }
return (pCandidate); return (pCandidate);
@@ -382,8 +396,8 @@ static void address_file_init(const char *pFilename)
} }
} }
address_add((uint32_t)device_id, max_apdu, &src); address_add((uint32_t)device_id, max_apdu, &src);
address_set_device_TTL((uint32_t)device_id, 0, /* Mark as static entry */
true); /* Mark as static entry */ address_set_device_TTL((uint32_t)device_id, 0, true);
} }
} }
} }
@@ -401,13 +415,12 @@ static void address_file_init(const char *pFilename)
void address_init(void) void address_init(void)
{ {
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
unsigned index;
Top_Protected_Entry = 0; Top_Protected_Entry = 0;
for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
pMatch = Address_Cache; pMatch = &Address_Cache[index];
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) {
pMatch->Flags = 0; pMatch->Flags = 0;
pMatch++;
} }
#ifdef BACNET_ADDRESS_CACHE_FILE #ifdef BACNET_ADDRESS_CACHE_FILE
address_file_init(Address_Cache_Filename); address_file_init(Address_Cache_Filename);
@@ -425,23 +438,22 @@ void address_init(void)
void address_init_partial(void) void address_init_partial(void)
{ {
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
unsigned index;
pMatch = Address_Cache; for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
if ((pMatch->Flags & BAC_ADDR_IN_USE) != if ((pMatch->Flags & BAC_ADDR_IN_USE) != 0) {
0) { /* It's in use so let's check further */ /* It's in use so let's check further */
if (((pMatch->Flags & BAC_ADDR_BIND_REQ) != 0) || if (((pMatch->Flags & BAC_ADDR_BIND_REQ) != 0) ||
(pMatch->TimeToLive == 0)) { (pMatch->TimeToLive == 0)) {
pMatch->Flags = 0; pMatch->Flags = 0;
} }
} }
if ((pMatch->Flags & BAC_ADDR_RESERVED) != if ((pMatch->Flags & BAC_ADDR_RESERVED) != 0) {
0) { /* Reserved entries should be cleared */ /* Reserved entries should be cleared */
pMatch->Flags = 0; pMatch->Flags = 0;
} }
pMatch++;
} }
#ifdef BACNET_ADDRESS_CACHE_FILE #ifdef BACNET_ADDRESS_CACHE_FILE
address_file_init(Address_Cache_Filename); address_file_init(Address_Cache_Filename);
@@ -464,13 +476,14 @@ void address_set_device_TTL(
uint32_t device_id, uint32_t TimeOut, bool StaticFlag) uint32_t device_id, uint32_t TimeOut, bool StaticFlag)
{ {
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
unsigned index;
pMatch = Address_Cache; for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
if (((pMatch->Flags & BAC_ADDR_IN_USE) != 0) && if (((pMatch->Flags & BAC_ADDR_IN_USE) != 0) &&
(pMatch->device_id == device_id)) { (pMatch->device_id == device_id)) {
if ((pMatch->Flags & BAC_ADDR_BIND_REQ) == if ((pMatch->Flags & BAC_ADDR_BIND_REQ) == 0) {
0) { /* If bound then we have either static or normaal */ /* If bound then we have either static or normaal */
if (StaticFlag) { if (StaticFlag) {
pMatch->Flags |= BAC_ADDR_STATIC; pMatch->Flags |= BAC_ADDR_STATIC;
pMatch->TimeToLive = BAC_ADDR_FOREVER; pMatch->TimeToLive = BAC_ADDR_FOREVER;
@@ -479,12 +492,11 @@ void address_set_device_TTL(
pMatch->TimeToLive = TimeOut; pMatch->TimeToLive = TimeOut;
} }
} else { } else {
pMatch->TimeToLive = TimeOut; /* For unbound we can only set the /* For unbound we can only set the time to live */
time to live */ pMatch->TimeToLive = TimeOut;
} }
break; /* Exit now if found at all - bound or unbound */ break; /* Exit now if found at all - bound or unbound */
} }
pMatch++;
} }
} }
@@ -500,20 +512,22 @@ bool address_get_by_device(
{ {
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
bool found = false; /* return value */ bool found = false; /* return value */
unsigned index;
pMatch = Address_Cache; for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
if (((pMatch->Flags & BAC_ADDR_IN_USE) != 0) && if (((pMatch->Flags & BAC_ADDR_IN_USE) != 0) &&
(pMatch->device_id == device_id)) { (pMatch->device_id == device_id)) {
if ((pMatch->Flags & BAC_ADDR_BIND_REQ) == if ((pMatch->Flags & BAC_ADDR_BIND_REQ) == 0) {
0) { /* If bound then fetch data */ /* If bound then fetch data */
bacnet_address_copy(src, &pMatch->address); bacnet_address_copy(src, &pMatch->address);
*max_apdu = pMatch->max_apdu; *max_apdu = pMatch->max_apdu;
found = true; /* Prove we found it */ /* Prove we found it */
found = true;
} }
break; /* Exit now if found at all - bound or unbound */ /* Exit now if found at all - bound or unbound */
break;
} }
pMatch++;
} }
return found; return found;
@@ -531,11 +545,13 @@ bool address_get_device_id(BACNET_ADDRESS *src, uint32_t *device_id)
{ {
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
bool found = false; /* return value */ bool found = false; /* return value */
unsigned index;
pMatch = Address_Cache; for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) == if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) ==
BAC_ADDR_IN_USE) { /* If bound */ BAC_ADDR_IN_USE) {
/* If bound */
if (bacnet_address_same(&pMatch->address, src)) { if (bacnet_address_same(&pMatch->address, src)) {
if (device_id) { if (device_id) {
*device_id = pMatch->device_id; *device_id = pMatch->device_id;
@@ -544,7 +560,6 @@ bool address_get_device_id(BACNET_ADDRESS *src, uint32_t *device_id)
break; break;
} }
} }
pMatch++;
} }
return found; return found;
@@ -561,6 +576,7 @@ void address_add(uint32_t device_id, unsigned max_apdu, BACNET_ADDRESS *src)
{ {
bool found = false; /* return value */ bool found = false; /* return value */
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
unsigned index;
if (Own_Device_ID == device_id) { if (Own_Device_ID == device_id) {
return; return;
@@ -573,57 +589,49 @@ void address_add(uint32_t device_id, unsigned max_apdu, BACNET_ADDRESS *src)
bind request if it exists */ bind request if it exists */
/* existing device or bind request outstanding - update address */ /* existing device or bind request outstanding - update address */
pMatch = Address_Cache; for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
/* Device already in the list, then update the values. */ /* Device already in the list, then update the values. */
if (((pMatch->Flags & BAC_ADDR_IN_USE) != 0) && if (((pMatch->Flags & BAC_ADDR_IN_USE) != 0) &&
(pMatch->device_id == device_id)) { (pMatch->device_id == device_id)) {
bacnet_address_copy(&pMatch->address, src); bacnet_address_copy(&pMatch->address, src);
pMatch->max_apdu = max_apdu; pMatch->max_apdu = max_apdu;
/* Pick the right time to live */ /* Pick the right time to live */
if ((pMatch->Flags & BAC_ADDR_BIND_REQ) != 0) {
if ((pMatch->Flags & BAC_ADDR_BIND_REQ) != /* Bind requested so long time */
0) { /* Bind requested so long time */
pMatch->TimeToLive = BAC_ADDR_LONG_TIME; pMatch->TimeToLive = BAC_ADDR_LONG_TIME;
} else if ((pMatch->Flags & BAC_ADDR_STATIC) != } else if ((pMatch->Flags & BAC_ADDR_STATIC) != 0) {
0) { /* Static already so make sure it never expires */ /* Static already so make sure it never expires */
pMatch->TimeToLive = BAC_ADDR_FOREVER; pMatch->TimeToLive = BAC_ADDR_FOREVER;
} else if ((pMatch->Flags & BAC_ADDR_SHORT_TTL) != } else if ((pMatch->Flags & BAC_ADDR_SHORT_TTL) != 0) {
0) { /* Opportunistic entry so leave on short fuse */ /* Opportunistic entry so leave on short fuse */
pMatch->TimeToLive = BAC_ADDR_SHORT_TIME; pMatch->TimeToLive = BAC_ADDR_SHORT_TIME;
} else { } else {
pMatch->TimeToLive = /* Renewing existing entry */
BAC_ADDR_LONG_TIME; /* Renewing existing entry */ pMatch->TimeToLive = BAC_ADDR_LONG_TIME;
} }
/* Clear bind request flag just in case */
pMatch->Flags &= ~BAC_ADDR_BIND_REQ; /* Clear bind request flag just pMatch->Flags &= ~BAC_ADDR_BIND_REQ;
in case */
found = true; found = true;
break; break;
} }
pMatch++;
} }
/* New device - add to cache if there is room. */ /* New device - add to cache if there is room. */
if (!found) { if (!found) {
pMatch = Address_Cache; for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
if ((pMatch->Flags & BAC_ADDR_IN_USE) == 0) { if ((pMatch->Flags & BAC_ADDR_IN_USE) == 0) {
pMatch->Flags = BAC_ADDR_IN_USE; pMatch->Flags = BAC_ADDR_IN_USE;
pMatch->device_id = device_id; pMatch->device_id = device_id;
pMatch->max_apdu = max_apdu; pMatch->max_apdu = max_apdu;
bacnet_address_copy(&pMatch->address, src); bacnet_address_copy(&pMatch->address, src);
pMatch->TimeToLive = /* Opportunistic entry so leave on short fuse */
BAC_ADDR_SHORT_TIME; /* Opportunistic entry so leave on pMatch->TimeToLive = BAC_ADDR_SHORT_TIME;
short fuse */
found = true; found = true;
break; break;
} }
pMatch++;
} }
} }
/* If adding has failed, see if we can squeeze it in by removed the oldest /* If adding has failed, see if we can squeeze it in by removed the oldest
* entry. */ * entry. */
if (!found) { if (!found) {
@@ -633,8 +641,8 @@ void address_add(uint32_t device_id, unsigned max_apdu, BACNET_ADDRESS *src)
pMatch->device_id = device_id; pMatch->device_id = device_id;
pMatch->max_apdu = max_apdu; pMatch->max_apdu = max_apdu;
bacnet_address_copy(&pMatch->address, src); bacnet_address_copy(&pMatch->address, src);
pMatch->TimeToLive = BAC_ADDR_SHORT_TIME; /* Opportunistic entry so /* Opportunistic entry so leave on short fuse */
leave on short fuse */ pMatch->TimeToLive = BAC_ADDR_SHORT_TIME;
} }
} }
return; return;
@@ -660,13 +668,15 @@ bool address_device_bind_request(uint32_t device_id,
{ {
bool found = false; /* return value */ bool found = false; /* return value */
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
unsigned index;
/* existing device - update address info if currently bound */ /* existing device - update address info if currently bound */
pMatch = Address_Cache; for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
if (((pMatch->Flags & BAC_ADDR_IN_USE) != 0) && if (((pMatch->Flags & BAC_ADDR_IN_USE) != 0) &&
(pMatch->device_id == device_id)) { (pMatch->device_id == device_id)) {
if ((pMatch->Flags & BAC_ADDR_BIND_REQ) == 0) { /* Already bound */ if ((pMatch->Flags & BAC_ADDR_BIND_REQ) == 0) {
/* Already bound */
found = true; found = true;
if (src) { if (src) {
bacnet_address_copy(src, &pMatch->address); bacnet_address_copy(src, &pMatch->address);
@@ -677,25 +687,23 @@ bool address_device_bind_request(uint32_t device_id,
if (device_ttl) { if (device_ttl) {
*device_ttl = pMatch->TimeToLive; *device_ttl = pMatch->TimeToLive;
} }
if ((pMatch->Flags & BAC_ADDR_SHORT_TTL) != if ((pMatch->Flags & BAC_ADDR_SHORT_TTL) != 0) {
0) { /* Was picked up opportunistacilly */ /* Was picked up opportunistacilly */
pMatch->Flags &= /* Convert to normal entry */
~BAC_ADDR_SHORT_TTL; /* Convert to normal entry */ pMatch->Flags &= ~BAC_ADDR_SHORT_TTL;
pMatch->TimeToLive = /* And give it a decent time to live */
BAC_ADDR_LONG_TIME; /* And give it a decent time to pMatch->TimeToLive = BAC_ADDR_LONG_TIME;
* live
*/
} }
} }
return ( /* True if bound, false if bind request outstanding */
found); /* True if bound, false if bind request outstanding */ return (found);
} }
pMatch++;
} }
/* Not there already so look for a free entry to put it in */ /* Not there already so look for a free entry to put it in */
pMatch = Address_Cache; /* existing device - update address info if currently bound */
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
pMatch = &Address_Cache[index];
if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_RESERVED)) == 0) { if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_RESERVED)) == 0) {
/* In use and awaiting binding */ /* In use and awaiting binding */
pMatch->Flags = (uint8_t)(BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ); pMatch->Flags = (uint8_t)(BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ);
@@ -705,7 +713,6 @@ bool address_device_bind_request(uint32_t device_id,
/* now would be a good time to do a Who-Is request */ /* now would be a good time to do a Who-Is request */
return (false); return (false);
} }
pMatch++;
} }
/* No free entries, See if we can squeeze it in by dropping an existing one /* No free entries, See if we can squeeze it in by dropping an existing one
@@ -749,10 +756,11 @@ void address_add_binding(
uint32_t device_id, unsigned max_apdu, BACNET_ADDRESS *src) uint32_t device_id, unsigned max_apdu, BACNET_ADDRESS *src)
{ {
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
unsigned index;
/* existing device or bind request - update address */ /* existing device or bind request - update address */
pMatch = Address_Cache; for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
if (((pMatch->Flags & BAC_ADDR_IN_USE) != 0) && if (((pMatch->Flags & BAC_ADDR_IN_USE) != 0) &&
(pMatch->device_id == device_id)) { (pMatch->device_id == device_id)) {
bacnet_address_copy(&pMatch->address, src); bacnet_address_copy(&pMatch->address, src);
@@ -766,7 +774,6 @@ void address_add_binding(
} }
break; break;
} }
pMatch++;
} }
return; return;
} }
@@ -844,16 +851,15 @@ unsigned address_count(void)
{ {
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
unsigned count = 0; /* return value */ unsigned count = 0; /* return value */
unsigned index;
pMatch = Address_Cache; for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
/* Only count bound entries */ /* Only count bound entries */
if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) == if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) ==
BAC_ADDR_IN_USE) { BAC_ADDR_IN_USE) {
count++; count++;
} }
pMatch++;
} }
return count; return count;
@@ -873,10 +879,11 @@ int address_list_encode(uint8_t *apdu, unsigned apdu_len)
int iLen = 0; int iLen = 0;
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
BACNET_OCTET_STRING MAC_Address; BACNET_OCTET_STRING MAC_Address;
unsigned index;
/* Look for matching address. */ /* Look for matching address. */
pMatch = Address_Cache; for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { pMatch = &Address_Cache[index];
if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) == if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) ==
BAC_ADDR_IN_USE) { BAC_ADDR_IN_USE) {
iLen += encode_application_object_id( iLen += encode_application_object_id(
@@ -913,7 +920,6 @@ int address_list_encode(uint8_t *apdu, unsigned apdu_len)
break; break;
} }
} }
pMatch++;
} }
return (iLen); return (iLen);
@@ -1019,13 +1025,12 @@ int rr_address_list_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest)
/* From here on in we only have a starting point and a positive count */ /* From here on in we only have a starting point and a positive count */
if (pRequest->Range.RefIndex > if (pRequest->Range.RefIndex > uiTotal) {
uiTotal) { /* Nothing to return as we are past the end of the list */ /* Nothing to return as we are past the end of the list */
return (0); return (0);
} }
/* Index of last required entry */
uiTarget = pRequest->Range.RefIndex + pRequest->Count - uiTarget = pRequest->Range.RefIndex + pRequest->Count - 1;
1; /* Index of last required entry */
if (uiTarget > uiTotal) { /* Capped at end of list if necessary */ if (uiTarget > uiTotal) { /* Capped at end of list if necessary */
uiTarget = uiTotal; uiTarget = uiTotal;
} }
@@ -1037,14 +1042,16 @@ int rr_address_list_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest)
pMatch++; pMatch++;
/* Shall not happen as the count has been checked first. */ /* Shall not happen as the count has been checked first. */
if (pMatch > &Address_Cache[MAX_ADDRESS_CACHE - 1]) { if (pMatch > &Address_Cache[MAX_ADDRESS_CACHE - 1]) {
return (0); /* Issue with the table. */ /* Issue with the table. */
return (0);
} }
} }
/* Seek to start position */ /* Seek to start position */
while (uiIndex != pRequest->Range.RefIndex) { while (uiIndex != pRequest->Range.RefIndex) {
if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) == if ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) ==
BAC_ADDR_IN_USE) { /* Only count bound entries */ BAC_ADDR_IN_USE) {
/* Only count bound entries */
pMatch++; pMatch++;
uiIndex++; uiIndex++;
} else { } else {
@@ -1052,7 +1059,8 @@ int rr_address_list_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest)
} }
/* Shall not happen as the count has been checked first. */ /* Shall not happen as the count has been checked first. */
if (pMatch > &Address_Cache[MAX_ADDRESS_CACHE - 1]) { if (pMatch > &Address_Cache[MAX_ADDRESS_CACHE - 1]) {
return (0); /* Issue with the table. */ /* Issue with the table. */
return (0);
} }
} }
@@ -1067,14 +1075,12 @@ int rr_address_list_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest)
&pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS, true); &pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS, true);
break; break;
} }
iTemp = (int32_t)encode_application_object_id( iTemp = (int32_t)encode_application_object_id(
&apdu[iLen], OBJECT_DEVICE, pMatch->device_id); &apdu[iLen], OBJECT_DEVICE, pMatch->device_id);
iTemp += encode_application_unsigned( iTemp += encode_application_unsigned(
&apdu[iLen + iTemp], pMatch->address.net); &apdu[iLen + iTemp], pMatch->address.net);
/* pick the appropriate type of entry from the cache */ /* pick the appropriate type of entry from the cache */
if (pMatch->address.len != 0) { if (pMatch->address.len != 0) {
octetstring_init( octetstring_init(
&MAC_Address, pMatch->address.adr, pMatch->address.len); &MAC_Address, pMatch->address.adr, pMatch->address.len);
@@ -1086,25 +1092,29 @@ int rr_address_list_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest)
iTemp += encode_application_octet_string( iTemp += encode_application_octet_string(
&apdu[iLen + iTemp], &MAC_Address); &apdu[iLen + iTemp], &MAC_Address);
} }
/* Reduce the remaining space */
uiRemaining -= iTemp; /* Reduce the remaining space */ uiRemaining -= iTemp;
iLen += iTemp; /* and increase the length consumed */ /* and increase the length consumed */
iLen += iTemp;
uiLast = uiIndex; /* Record the last entry encoded */ /* Record the last entry encoded */
uiIndex++; /* and get ready for next one */ uiLast = uiIndex;
/* and get ready for next one */
uiIndex++;
pMatch++; pMatch++;
pRequest->ItemCount++; /* Chalk up another one for the response count */ /* Chalk up another one for the response count */
pRequest->ItemCount++;
while ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) != while ((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_BIND_REQ)) !=
BAC_ADDR_IN_USE) { /* Find next bound entry */ BAC_ADDR_IN_USE) {
/* Find next bound entry */
pMatch++; pMatch++;
/* Can normally not happen. */ /* Can normally not happen. */
if (pMatch > &Address_Cache[MAX_ADDRESS_CACHE - 1]) { if (pMatch > &Address_Cache[MAX_ADDRESS_CACHE - 1]) {
return (0); /* Issue with the table. */ /* Issue with the table. */
return (0);
} }
} }
} }
/* Set remaining result flags if necessary */ /* Set remaining result flags if necessary */
if (uiFirst == 1) { if (uiFirst == 1) {
bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_FIRST_ITEM, true); bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_FIRST_ITEM, true);
@@ -1129,9 +1139,10 @@ int rr_address_list_encode(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest)
void address_cache_timer(uint16_t uSeconds) void address_cache_timer(uint16_t uSeconds)
{ {
struct Address_Cache_Entry *pMatch; struct Address_Cache_Entry *pMatch;
unsigned index;
pMatch = Address_Cache;
while (pMatch <= &Address_Cache[MAX_ADDRESS_CACHE - 1]) { for (index = 0; index < MAX_ADDRESS_CACHE; index++) {
pMatch = &Address_Cache[index];
if (((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_RESERVED)) != 0) && if (((pMatch->Flags & (BAC_ADDR_IN_USE | BAC_ADDR_RESERVED)) != 0) &&
((pMatch->Flags & BAC_ADDR_STATIC) == ((pMatch->Flags & BAC_ADDR_STATIC) ==
0)) { /* Check all entries holding a slot except statics 0)) { /* Check all entries holding a slot except statics
@@ -1142,8 +1153,6 @@ void address_cache_timer(uint16_t uSeconds)
pMatch->Flags = 0; pMatch->Flags = 0;
} }
} }
pMatch++;
} }
} }