Please note as of Wednesday, August 15th, 2018 this wiki has been set to read only. If you are a TI Employee and require Edit ability please contact x0211426 from the company directory.

Zigbee Known Issues and Proposed Fixes

From Texas Instruments Wiki
Jump to: navigation, search

Introduction

This page contains known issues on the published Zigbee Software releases from TI. TI has a software release candidates and all fixes may not be available to developers as soon as they are implemented. The purpose of this page is to provide developers information of the issues and fixes in case an issue is found on the published software before a new release is made. This will help developers fix problems before they are fixed in released Zigbee releases from TI.

Z-Stack 3.0.1 Issues/Fixes

Memory Leak in zcl.c

Issue description:
Memory leak in zcl_HandleExternal()

Proposed Fix:

zcl_HandleExternal()
{
...
#ifdef BDB_REPORTING
    if(pCmd->zclHdr.commandID == ZCL_CMD_CONFIG_REPORT)
    {
      bdb_ProcessInConfigReportCmd(pCmd);
      osal_msg_deallocate((uint8 *)pCmd); // ++++++++++++++ ADD THIS CODE
      return TRUE;          
    }
    if(pCmd->zclHdr.commandID == ZCL_CMD_READ_REPORT_CFG)
    {
      bdb_ProcessInReadReportCfgCmd(pCmd);
      osal_msg_deallocate((uint8 *)pCmd); // ++++++++++++++ ADD THIS CODE
      return TRUE;
    }
#endif
...
}

Network association issues after prior APS Remove or Leave Request

Issue description:
Under some conditions when an APS Remove/Leave Request is sent to a device to remove itself or another device, NV will not be cleared properly and new network associates will not work due to the old APS key from the TC Link Key exchange staying persistent in NV.

Proposed Fix:

// in ZDApp.c
UINT16 ZDApp_event_loop( uint8 task_id, UINT16 events )
{
...
  if ( events & ZDO_DEVICE_RESET )
  {
#ifdef ZBA_FALLBACK_NWKKEY
    if ( devState == DEV_END_DEVICE_UNAUTH )
    {
      ZDSecMgrFallbackNwkKey();
    }
    else
#endif
    {
      // Set the NV startup option to force a "new" join.
      zgWriteStartupOptions( ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE | ZCD_STARTOPT_DEFAULT_CONFIG_STATE ); /// ++++ MODIFY THIS LINE ++++

      // The device has been in the UNAUTH state, so reset
      // Note: there will be no return from this call
      SystemResetSoft();
    }
  }
...
}

Soft Reset/Freezing/Stack Overflow due to BDB_REPORTING on CC2530/CC2531

Issue description:
The default size of the XDATA stack is 0x300 (768 bytes), and with the addition of BDB_REPORTING in an application, sometimes the callstack will become too large and overflow the XDATA stack.

Proposed Fix:
Increase the size of the XDATA stack in the project options to at least 0x400:

SampleLight XDATA Stack 0x400 31JAN2018.png


OTA Upgrade from ZHA 1.2 to Z3.0 results in broken device

Issue description:
When doing an OTA upgrade from ZHA 1.2 to Z3.0, the usage of some NV items have changed between versions and the network security information is formatted in a different way. Because of this, it is necessary that we "upgrade" some NV security items when doing this upgrade.

Proposed Fix:

Some code below already exists in Z-Stack and is provided as context. Add all the code changes for this fix are under the compile flag UPGRADE_SECURITY_NV_ITEMS

// in ZGlobals.c


/*********************************************************************
 * LOCAL FUNCTIONS
 */
...
#ifdef UPGRADE_SECURITY_NV_ITEMS
static void zgUpgradeSecurityNVItems( void );
#endif // UPGRADE_SECURITY_NV_ITEMS
...

uint8 zgInit( void )
{
...
#ifndef NONWK
  if ( ZG_SECURE_ENABLED )
  {
    // Initialize the Pre-Configured Key to the default key
    zgPreconfigKeyInit( setDefault );

    // Initialize NV items for all Keys: NWK, APS, TCLK and Master
    ZDSecMgrInitNVKeyTables( setDefault );
  }
#endif // NONWK

#ifdef UPGRADE_SECURITY_NV_ITEMS
  zgUpgradeSecurityNVItems();
#endif // UPGRADE_SECURITY_NV_ITEMS

  // Clear the Config State default
  if ( setDefault )
  {
    zgWriteStartupOptions( ZG_STARTUP_CLEAR, ZCD_STARTOPT_DEFAULT_CONFIG_STATE );
  }
...
}

#ifdef UPGRADE_SECURITY_NV_ITEMS
static void zgUpgradeSecurityNVItems( void )
{
  //Nv configuration to allow upgrade from HA1.2 to Z3.0

  uint8 isOnANetwork = 1;
  //Read bdb attribute
  if(osal_nv_read(ZCD_NV_BDBNODEISONANETWORK, 0, sizeof(uint8), &isOnANetwork) == SUCCESS)
  {
    //After upgrade, this parameter will be 0, then update properly as it is in a network.
    //If the device was not in a network and is upgraded, the BDB will handle the network 
    //configuration status and will performing FN reset.
    
    nwkSecMaterialDesc_t  nwkSecMaterialDesc;
    nwkActiveKeyItems     keyItems;
    uint8                 keyAttributes;
    uint8                 tempKey[SEC_KEY_LEN];
    
    osal_memset(tempKey, 0x00, SEC_KEY_LEN);
    
    //Get the network frame counter from old NV item, also check if old key exists.
    //if it doesn't, we can assume that this is factory new Z3.0 device instead of 
    //upgraded ZHA 1.2 device
    osal_nv_read( ZCD_NV_NWKKEY, 0, sizeof( nwkActiveKeyItems ),(void *)&keyItems );
    
    if( osal_memcmp(tempKey, keyItems.active.key, SEC_KEY_LEN) )
    {
      // device is factory new, don't do anything 
    }
    // else if node is not on a network currently and is not factory new Z3.0 device, 
    // it must be ZHA 1.2 -> Z3.0.1 upgraded device
    else if(!isOnANetwork)
    {
      //If none of these parameters can be configured by Nv operations BDB will be able to initialize or handle.
      
      //set bdbNodeIsOnANetwork attribute to 1 indicating that we need to resume our network state
      isOnANetwork = 0x01;
      osal_nv_write( ZCD_NV_BDBNODEISONANETWORK, 0, sizeof(uint8), &isOnANetwork );
      
      //Set the network frame counter in new NV item, frame counter will be incremented by 1000+250 in ZDApp_RestoreNwkSecMaterial() 
      //to ensure that its outgoing packets can be used by devices in its previous network
      nwkSecMaterialDesc.FrameCounter = keyItems.frameCounter; 
      
      //Retrieve Extended PANID from NIB in NV
      osal_nv_read( ZCD_NV_NIB, osal_offsetof(nwkIB_t,extendedPANID), Z_EXTADDR_LEN, &nwkSecMaterialDesc.extendedPanID );
      
      //Set the BDB network security material, BDB state machine will restore network state if this is a valid entry
      osal_nv_write( ZCD_NV_NWK_SEC_MATERIAL_TABLE_START, 0, sizeof(nwkSecMaterialDesc_t), &nwkSecMaterialDesc );  
      
      //indicate to BDB that our previous nwk was non-R21, so don't expect TC Link Key exchange
      keyAttributes = ZG_NON_R21_NWK_JOINED;
      osal_nv_write(ZCD_NV_TCLK_TABLE_START, osal_offsetof(APSME_TCLKDevEntry_t,keyAttributes), sizeof(uint8), &keyAttributes); 
    }
  }
}
#endif // UPGRADE_SECURITY_NV_ITEMS

IEEE Address of CC2538ZNP is reported incorrectly

Issue description:
MSB and LSB of IEEE address are flipped when using the CC2538ZNP project. This is due to the placement of the IEEE address in Flash changing between test and production versions of the CC2538 SoC devices. Non-ZNP CC2538ZNP projects are not affected because they use a different ZMain.c file, which already has the fix for this applied.

Proposed Fix:

// in ZMain.c for CC2538ZNP

/******************************************************************************
 * LOCAL DEFINITIONS
 */

// TI IEEE Organizational Unique Identifier
#define IEEE_OUI 0x00124B

...

// replace zmain_ext_addr() with the definition below
static void zmain_ext_addr( void )
{
  uint8 nullAddr[Z_EXTADDR_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  uint8 writeNV = TRUE;

  // First check whether a non-erased extended address exists in the OSAL NV.
  if ((SUCCESS != osal_nv_item_init(ZCD_NV_EXTADDR, Z_EXTADDR_LEN, NULL))  ||
      (SUCCESS != osal_nv_read(ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, aExtendedAddress)) ||
      (osal_memcmp(aExtendedAddress, nullAddr, Z_EXTADDR_LEN)))
  {
    // Attempt to read the extended address from the location in the last flash
    // page where the commissioning tools know to reserve it.
    if (!osal_memcmp((uint8 *)HAL_FLASH_IEEE_ADDR, nullAddr, Z_EXTADDR_LEN))
    {
      (void)osal_memcpy(aExtendedAddress, (uint8 *)HAL_FLASH_IEEE_ADDR, Z_EXTADDR_LEN);
    }
    else
    {
      // Disable prefetch when reading from Information Page.
      uint32 fctl = HWREG(FLASH_CTRL_FCTL);
      HWREG(FLASH_CTRL_FCTL) = fctl & ~(FLASH_CTRL_FCTL_PREFETCH_ENABLE);

      // Copy 64-bit extended address from the Information Page
      (void)osal_memcpy(aExtendedAddress, (uint8*)HAL_INFO_IEEE_ADDR, Z_EXTADDR_LEN);
      if (!osal_memcmp(aExtendedAddress, nullAddr, Z_EXTADDR_LEN))
      {
        uint32 oui = IEEE_OUI;
        // IEEE OUI is located in the upper 3 bytes of an 8-byte extended address
        // Early Test CC2538EMs had the TI OUI located in the 2nd word,
        // Production CC2538 devices have the TI OUI located in the 1st word
        if (osal_memcmp(&aExtendedAddress[1], &oui, 3))
        {
          // OUI found in 1st word, swap words to place OUI in upper bytes
          (void)osal_memcpy(aExtendedAddress, &aExtendedAddress[4], Z_EXTADDR_LEN/2);
          (void)osal_memcpy(&aExtendedAddress[4], (uint8*)HAL_INFO_IEEE_ADDR, Z_EXTADDR_LEN/2);
        }
      }
      else  // No valid extended address was found.
      {
        uint8 idx;

#if !defined ( NV_RESTORE )
        writeNV = FALSE;  // Make a temporary IEEE address, not saved in NV
#endif

       /* Create a sufficiently random extended address for expediency.
        * Note: this is only valid/legal in a test environment and
        *       must never be used for a commercial product.
        */
        for (idx = 0; idx < (Z_EXTADDR_LEN - 2);)
        {
          uint16 randy = osal_rand();
          aExtendedAddress[idx++] = LO_UINT16(randy);
          aExtendedAddress[idx++] = HI_UINT16(randy);
        }
        // Next-to-MSB identifies ZigBee device type.
#if ZG_BUILD_COORDINATOR_TYPE && !ZG_BUILD_JOINING_TYPE
        aExtendedAddress[idx++] = 0x10;
#elif ZG_BUILD_RTRONLY_TYPE
        aExtendedAddress[idx++] = 0x20;
#else
      aExtendedAddress[idx++] = 0x30;
#endif
      // MSB has historical signficance.
        aExtendedAddress[idx] = 0xF8;
      }

      // Restore flash control to previous state
      HWREG(FLASH_CTRL_FCTL) = fctl;
    }

    if (writeNV)
    {
      (void)osal_nv_write(ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, aExtendedAddress);
    }
  }

  // Set the MAC PIB extended address according to results from above.
  (void)ZMacSetReq(MAC_EXTENDED_ADDRESS, aExtendedAddress);
}

...


Modifying CC2538 Linker to utilize all 32k RAM causes lockup

Issue description:
Some CC2538 parts have 32k of RAM, but the first 16k is disabled by default in our linker file since only the second 16k is retained in all power modes. The first 16k of RAM loses its contents when the device enters PM2. If you are designing a device which never goes into low power mode, it is fine to reclaim this RAM for application usage. You can do this by changing the following in the linker file:

//
// Define a region for the on-chip SRAM.
//
define region SRAM = mem:[from 0x20000000 to 0x20007FFF]; // 0x20004000 --> 0x20000000

However, in some applications, increasing the RAM to this value will cause Z-Stack to lock up.


Proposed Fix:

Move the run-time stack to the end of RAM. Find the code below in your linker file and make the following change:

//
// Indicate that the noinit values should be left alone.  This includes the
// stack, which if initialized will destroy the return address from the
// initialization code, causing the processor to branch to zero and fault.
//
do not initialize { section .noinit };
place at end of SRAM { section .noinit }; // ++++++++++ ADD THIS LINE ++++++++++

ZED does not receive Broadcast sent to MAC dst 0xFFFF from parent

Issue description:
In Zigbee, if a broadcast message is sent to destination address 0xFFFF, all devices (Rx-always-on AND sleepy) will receive this message. This means that parent routing devices must buffer broadcasts sent to 0xFFFF for any of their sleepy ZED children. In Z-Stack, if you have a single ZR/ZC node that has more than (32 - MAX_NEIGHBOR_ENTRIES) direct sleepy ZED children, each ZED beyond this number will not be able to receive the broadcast message. MAX_NEIGHBOR_ENTRIES is 16 by default for routing devices in Z-Stack.

Proposed Fix:
There is no perfect fix available for this right now since this implementation is in the pre-compiled Z-Stack libraries, but there are some workarounds we can suggest:

  1. Do not send broadcast messages to destination 0xFFFF, only use 0xFFFC/0xFFFD (MAC dst addr for rx-always-on devices only) and send unicast messages to sleepy ZED nodes.
    • This is the preferred method, since you will not have to limit your device table size as a result.
  2. Limit the number of sleepy ZED nodes per ZC/ZR to a maximum of 16
    • This is good practice for large networks anyway, for a robust mesh network topology you should always aim for one ZR for every 10-15 ZEDs
  3. Decrease MAX_NEIGHBOR_ENTRIES from 16 to a smaller value
    • Not recommended, MAX_NEIGHBOR_ENTRIES determines the size of your neighbor table, which is a list of ZR devices that are within RF range of you. Larger neighbor table = easier Zigbee route discovery = more robust mesh networking. TI Z-Stack was tested with MAX_NEIGHBOR_ENTRIES=16 to be a good value for most Zigbee networking situations.

NWK/APS packet retries/failure when ZED polls during commissioning (Transport Key, Simple Descriptor Request, etc)

Issue description:
Sometimes ZC will fail to send out a NWK/APS layer packet during network commissioning, e.g. Transport Key, to a joining ZED, and this requires the ZED to poll again to get the packet. This will not cause functionality issues for the joining device since it will retry and eventually get the packet, but it is not ideal to need to retry to receive the same packet multiple times. This issue is caused by a race condition involving a blocking NV write operation that happens on the ZC after a new device joins the network.

Proposed Fix:
Change the value of ZDAPP_UPDATE_NWK_NV_TIME from it's default of 700 (ms) to a larger value, like 3500. This will cause the NV write operation to start at a later time and thus not interfere with network commissioning.

ZED does not go back to low power state after losing parent and attempting recovery

Issue description:
After the API bdb_ZedAttemptRecoverNwk() is called from the application to attempt for a ZED to rejoin the network, the receiver is not turned back off, which causes ZED to leave RX on during idle and not go into a low power state.

Proposed fix:
Modify the function bdb_parentLost() in bdb.c:

void bdb_parentLost(void)
{
#if ZG_BUILD_ENDDEVICE_TYPE
  if(ZG_DEVICE_ENDDEVICE_TYPE)
  {
    while(pBDBListNwk)
    {
      bdb_nwkDescFree(pBDBListNwk);
    }
    
    nwk_desc_list_free();  
    if(bdbCommissioningProcedureState.bdbCommissioningState != BDB_PARENT_LOST)
    {
      //If parent lost during TCLK exchange, then report TCLK exchange fail
      if(bdbCommissioningProcedureState.bdbCommissioningState == BDB_COMMISSIONING_STATE_TC_LINK_KEY_EXCHANGE)
      {
        bdb_reportCommissioningState(BDB_COMMISSIONING_STATE_TC_LINK_KEY_EXCHANGE, FALSE);
        return;
      }
      bdbCommissioningProcedureState.bdb_ParentLostSavedState = bdbCommissioningProcedureState.bdbCommissioningState;
      
    }
    bdbCommissioningProcedureState.bdbCommissioningState = BDB_PARENT_LOST;
    NLME_OrphanStateSet();
    ZDApp_ChangeState( DEV_NWK_ORPHAN );

    // turn receiver off while in orphan state
    byte temp = FALSE;                   // ++++++++++++++ ADD THIS CODE
    ZMacSetReq(ZMacRxOnIdle, &temp);     // ++++++++++++++ ADD THIS CODE

    bdb_reportCommissioningState(BDB_PARENT_LOST,FALSE);
  }
#endif
}


ZCL ID mixup for Chatting + Voice Over Zigbee

Issue description:
ZCL IDs are swapped

Proposed fix:

// this is how it is now

#define ZCL_CLUSTER_ID_TELECOMMUNICATIONS_CHATTING           0x0904

#define ZCL_CLUSTER_ID_TELECOMMUNICATIONS_VOICE_OVER_ZIGBEE  0x0905

// IDs should be swapped like this:

#define ZCL_CLUSTER_ID_TELECOMMUNICATIONS_CHATTING           0x0905

#define ZCL_CLUSTER_ID_TELECOMMUNICATIONS_VOICE_OVER_ZIGBEE  0x0904

CC2530/1 ZNP device sporadically returns ZMemError

Issue description:
Sometimes in our Zigbee Linux Gateway solution, a CC2530/1 ZNP device will return a failure message with the status ZMemError, like below.

[14:52:12.119,309] [GATEWAY/LSTN] PKTTYPE: [                  Z_STACK<<<<<<<<<<<GATEWAY         ] afDataReq
[14:52:12.120,400] [GATEWAY/LSTN] PKTBODY:                                                          cmdID = AF_DATA_REQ
[14:52:12.122,748] [GATEWAY/LSTN] PKTBODY:                                                          dstAddr :
[14:52:12.123,831] [GATEWAY/LSTN] PKTBODY:                                                            addrMode = SHORT
[14:52:12.125,632] [GATEWAY/LSTN] PKTBODY:                                                            shortAddr = 0x0000EC56 (60502)
[14:52:12.126,453] [GATEWAY/LSTN] PKTBODY:                                                            endpoint = 0x00000001 (1)
[14:52:12.126,601] [GATEWAY/LSTN] PKTBODY:                                                            panID = 0x00000000 (0)
[14:52:12.128,656] [GATEWAY/LSTN] PKTBODY:                                                          srcEndpoint = 0x00000004 (4)
[14:52:12.128,963] [GATEWAY/LSTN] PKTBODY:                                                          clusterID = 0x00000402 (1026)
[14:52:12.129,108] [GATEWAY/LSTN] PKTBODY:                                                          transID = 0x00000011 (17)
[14:52:12.129,856] [GATEWAY/LSTN] PKTBODY:                                                          options :
[14:52:12.130,114] [GATEWAY/LSTN] PKTBODY:                                                          radius = 0x0000001E (30)
[14:52:12.130,282] [GATEWAY/LSTN] PKTBODY:                                                          payload (hex string) = 00:11:06:00:00:00:29:3C:00:84:03:64:00
[14:52:12.130,864] [Z_STACK/LSTN] PKTTYPE: [         NPISRVR<<Z_STACK                           ] [SREQ] 21:24:02:02:56:EC:00:08:02:10:F3:EE:01:00:00:04:02:04:11:00:1E:0D:00:00:11:06:00:00:00:29:3C:00:84:03:64:00
[14:52:12.131,305] [NPISRVR/MAIN] PKT_HEX: [SOCZIGB<<NPISRVR                                    ] [send] 21:24:02:02:56:EC:00:08:02:10:F3:EE:01:00:00:04:02:04:11:00:1E:0D:00:00:11:06:00:00:00:29:3C:00:84:03:64:00
[14:52:12.145,118] [NPISRVR/U_RX] PKT_HEX: [SOCZIGB>>NPISRVR                                    ] [SRSP] 01:64:02:10
[14:52:12.145,559] [NPISRVR/MAIN] PKT_HEX: [         NPISRVR>>Z_STACK                           ] [ucst] 01:64:02:10
[14:52:12.146,349] [Z_STACK/LSTN] PKTTYPE: [                  Z_STACK>>>>>>>>>>>GATEWAY         ] zstackDefaultRsp
[14:52:12.146,499] [Z_STACK/LSTN] PKTBODY:                                                          cmdID = AF_DATA_REQ
[14:52:12.146,567] [Z_STACK/LSTN] PKTBODY:                                                          status = ZMemError
[14:52:12.148,151] [GATEWAY/LSTN] PKTTYPE: [                                    GATEWAY>>>>>>>>>>>CON007] GwZigbeeGenericCnf
[14:52:12.148,413] [GATEWAY/LSTN] PKTBODY:                                                          cmdId = ZIGBEE_GENERIC_CNF
[14:52:12.148,556] [GATEWAY/LSTN] PKTBODY:                                                          status = STATUS_FAILURE
[14:52:12.148,679] [GATEWAY/LSTN] PKTBODY:                                                          sequenceNumber = 0x000001A1 (417)

Proposed fix:
Increase the size of the heap in the CC2530/1 ZNP project. By default, it is 2170 bytes for the ZNP project which is too small for some applications.

You can increase the size of the heap by adding this compile flag to your project's Preprocessor Defined Symbols:

MAXMEMHEAP=2800

To further increase the heap (or for general RAM/Flash optimizations) check this wiki page: http://processors.wiki.ti.com/index.php/Optimizing_Flash_and_RAM_Usage_of_Z-Stack_for_CC2530

ZC sends ZEDs Leave Reqs after MAC Association

Issue description:
When trying to join a large number of ZEDs at once, ZC will sometimes send ZEDs Leave (w/ Rejoin) Requests. This is due to the network layer data buffers overflowing. If ZC is unable to buffer the Transport Key packet to the ZED due to lack of space in the network layer data buffers (for buffering indirect messages for sleepy children), ZC will discard the Transport Key and then remove the device from it's association table. Then, the next time that ZED polls the ZC for data, the ZC will send it a Leave Request because the ZC believes it is "rogue" since that ZED is not in it's association table.

Proposed fix:
1. Stagger the joining of ZED devices, i.e. make your join event sporadic (osal_rand() % 30000) <--- random amount of time between 0 and 30 seconds

2. Join less ZEDs at once

3. Increase the number of network layer data buffers, if RAM permits:

// in nwk_globals.c
// doubling the size of all the buffers:

// Maximums for the data buffer queue
#define NWK_MAX_DATABUFS_WAITING    16 //8     // Waiting to be sent to MAC
#define NWK_MAX_DATABUFS_SCHEDULED  10 //5     // Timed messages to be sent
#define NWK_MAX_DATABUFS_CONFIRMED  10 //5     // Held after MAC confirms
#define NWK_MAX_DATABUFS_TOTAL      24 //12    // Total number of buffers

APS ACK transID parameter error if using zcl_TransID

Issue description:
zcl_TransID is used as the parameter of AF_DataRequest() in zcl_SendCommand() but is always zero. It was only used since it doesn't affect the APS frame and since the APS header has the correct sequence number only the APS ACK validation is affected. Therefore zcl_TransID becomes obsolete after being removed from this function.

Proposed fix:
Use APS_Counter instead since this variable is incremented each time an APS frame is generated in APSDE_FrameHdrSet() and has the count of APS frames

// in External Variables section of zcl.c
extern uint8 APS_Counter;

// in zcl_SendCommand() of zcl.c
// Fill in the command frame
zcl_memcpy( pBuf, cmdFormat, cmdFormatLen );

status = AF_DataRequest( destAddr, epDesc, clusterID, msgLen, msgBuf,
                         &APS_Counter, options, AF_DEFAULT_RADIUS);
zcl_mem_free ( msgBuf );

BDB reporting doesn't support read/write attribute data callback functions

Issue description:
The current BDB reporting implementation doesn't support attributes that use a callback function to read/write attribute data.

Proposed fix:
Replace bdb_RepFindAttrEntry() in bdb_reporting.c

uint8 gAttrDataValue[BDBREPORTING_MAX_ANALOG_ATTR_SIZE];

static uint8 bdb_RepFindAttrEntry( uint8 endpoint, uint16 cluster, uint16 attrID, zclAttribute_t* attrRes )
{
  epList_t *epCur = epList;
  uint8 i;

  zcl_memset(gAttrDataValue, 0, BDBREPORTING_MAX_ANALOG_ATTR_SIZE);
  for ( epCur = epList; epCur != NULL; epCur = epCur->nextDesc )
  {
    if( epCur->epDesc->endPoint == endpoint )
    {
      zclAttrRecsList* attrItem = zclFindAttrRecsList( epCur->epDesc->endPoint );
      
      if( (attrItem != NULL) && ( (attrItem->numAttributes > 0) && (attrItem->attrs != NULL) ) )
      {
        for ( i = 0; i < attrItem->numAttributes; i++ )
        {
          if ( ( attrItem->attrs[i].clusterID == cluster ) && ( attrItem->attrs[i].attr.attrId ==  attrID ) )
          {
            uint16 dataLen;

            attrRes->attrId = attrItem->attrs[i].attr.attrId;
            attrRes->dataType = attrItem->attrs[i].attr.dataType;
            attrRes->accessControl = attrItem->attrs[i].attr.accessControl;

            dataLen = zclGetDataTypeLength(attrRes->dataType);
            zcl_ReadAttrData( endpoint, cluster, attrRes->attrId, gAttrDataValue, &dataLen );
            attrRes->dataPtr = gAttrDataValue;
            return BDBREPORTING_TRUE;
          }
        }
      }
    }
  }
  return BDBREPORTING_FALSE;
 }

Errors due to BDB header build types

Issue description:
Some identifiers are left undefined if -DZSTACK_DEVICE_BUILD="(DEVICE_BUILD_ROUTER | DEVICE_BUILD_ENDDEVICE)" (from znp.cfg).

Proposed fix:
Replace bdb.h include and macros sections:

#if (ZG_BUILD_JOINING_TYPE || (ZSTACK_DEVICE_BUILD == DEVICE_BUILD_ROUTER) || (ZSTACK_DEVICE_BUILD == DEVICE_BUILD_ENDDEVICE)) // ++ CHANGE THIS LINE
//Optional
  #if defined ( INTER_PAN ) && ( defined ( BDB_TL_INITIATOR ) || defined ( BDB_TL_TARGET ) )
    #define BDB_TOUCHLINK_CAPABILITY_ENABLED 1
  #else
    #define BDB_TOUCHLINK_CAPABILITY_ENABLED 0
  #endif
#else
  #if defined ( INTER_PAN ) && ( defined ( BDB_TL_INITIATOR ) || defined ( BDB_TL_TARGET ) )
    #error TouchLink cannot be enabled for coordinator. Please make sure not to define either BDB_TL_INITIATOR or BDB_TL_TARGET
  #endif
#endif

/*********************************************************************
 * MACROS
 */
  
// bdbNodeCommissioningCapability MACROS  
#if (ZG_BUILD_COORDINATOR_TYPE) 
  #define BDB_NETWORK_STEERING_CAPABILITY (BDB_NETWORK_STEERING_CAPABILITY_ENABLED<<0)
  #define BDB_NETWORK_FORMATION_CAPABILITY (BDB_NETWORK_FORMATION_CAPABILITY_ENABLED<<1)
  #define BDB_FINDING_BINDING_CAPABILITY (BDB_FINDING_BINDING_CAPABILITY_ENABLED<<2)
  #define BDB_TOUCHLINK_CAPABILITY (0<<3) //ZC cannot perform TL proceedure
#endif
#if (ZG_BUILD_JOINING_TYPE || (ZSTACK_DEVICE_BUILD == DEVICE_BUILD_ROUTER )) // ++ CHANGE THIS LINE
  #define BDB_NETWORK_STEERING_CAPABILITY (BDB_NETWORK_STEERING_CAPABILITY_ENABLED<<0)
  #define BDB_NETWORK_FORMATION_CAPABILITY (BDB_ROUTER_FORM_DISTRIBUTED_NWK_ENABLED<<1)
  #define BDB_FINDING_BINDING_CAPABILITY (BDB_FINDING_BINDING_CAPABILITY_ENABLED<<2)
  #define BDB_TOUCHLINK_CAPABILITY (BDB_TOUCHLINK_CAPABILITY_ENABLED<<3) 
#endif    
#if (ZG_BUILD_ENDDEVICE_TYPE)
  #define BDB_NETWORK_STEERING_CAPABILITY      (BDB_NETWORK_STEERING_CAPABILITY_ENABLED<<0)
  #define BDB_NETWORK_FORMATION_CAPABILITY     (0<<1)                                       //ZED cannot form nwk
  #define BDB_FINDING_BINDING_CAPABILITY       (BDB_FINDING_BINDING_CAPABILITY_ENABLED<<2)
  #define BDB_TOUCHLINK_CAPABILITY             (BDB_TOUCHLINK_CAPABILITY_ENABLED<<3)      
#endif  

Modify f8wCoord.cfg by commenting coordinator setting and adding router and device build:

/* Coordinator Settings */
//-DZDO_COORDINATOR // Coordinator Functions
//-DRTR_NWK

/* Generic All-in-One Settings */
-DZSTACK_DEVICE_BUILD="(DEVICE_BUILD_ROUTER | DEVICE_BUILD_ENDDEVICE)"

/* Other Settings */
-DNWK_AUTO_POLL

Change the device library with -C $PROJ_DIR$\..\..\..\Libraries\TI2530DB\bin\AllDevice-Pro.lib and replace all instances of #if ( ZSTACK_ROUTER_BUILD ) || defined ( ZBIT ) with #if ( ZSTACK_ROUTER_BUILD ) || (ZG_BUILD_ENDDEVICE_TYPE) || defined ( ZBIT )

Low power mode not entered upon ZED rejoin

Issue description:
The ZED device state is incorrectly set during rejoin, therefore bypassing the entry into standby and remaining active. This results in higher current consumption than should be expected.

Proposed fix:
Change DEV_END_DEVICE to DEV_NWK_SEC_REJOIN_CURR_CHANNEL inside the BDB_PARENT_LOST and BDB_INITIALIZATION cases of bdb_reportCommissioningState from bdb.c

Low power mode not entered upon ZED factory new before commissioning

Issue description:
High current consumption at ZED startup from factory new before being commissioned into a network.

Proposed fix:
Change the following inside osal_pwrmgr.c:

#include "ZGlobals.h"
void osal_pwrmgr_init( void )
{
#if !defined USE_ICALL && !defined OSAL_PORT2TIRTOS
#if defined POWER_SAVING && ZSTACK_END_DEVICE_BUILD                  
  pwrmgr_attribute.pwrmgr_device = PWRMGR_BATTERY;   // Default to power conservation for ZED if power saving enabled.
#else
  pwrmgr_attribute.pwrmgr_device = PWRMGR_ALWAYS_ON; // No power conservation for routing devices.
#endif
#endif /* USE_ICALL */
  pwrmgr_attribute.pwrmgr_task_state = 0;            // Cleared.  All set to conserve
#if defined USE_ICALL || defined OSAL_PORT2TIRTOS
  pwrmgr_initialized = TRUE;
#endif /* defined USE_ICALL || defined OSAL_PORT2TIRTOS */
}

ZED poll rate set incorrectly if reset from a leave request with rejoin enabled

Issue description:
ZED will poll using REJOIN_POLL_RATE instead of POLL_RATE after being reset due to a parent leave request where the rejoin option was set.

Proposed fix:
In ZDApp_ProcessNetworkJoin of ZDApp.c, remove NLME_SetPollRate( zgRejoinPollRate ); from if (nwkStatus == ZSuccess) and place in the else statement instead. One must also set the zgRejoinPollRate when device state is DEV_END_DEVICE_UNAUTH

if ( ZG_SECURE_ENABLED && ( ZDApp_RestoreNwkKey( TRUE ) == false ) )
{
  if ( ZSTACK_END_DEVICE_BUILD )
  {
     NLME_SetPollRate( zgRejoinPollRate );
  }
  // wait for auth from trust center
  ZDApp_ChangeState( DEV_END_DEVICE_UNAUTH );

Optimally, also place NLME_SetPollRate( ZDApp_SavedPollRate ); inside of ZDO_JoinConfirmCB.