Tool/software: WEBENCH® Design Tools
fix the access of "zclport_registerZclHandleExternal" in zcl_port.h like this
extern bool zclport_registerZclHandleExternal(uint8_t endpoint, zclport_pFnZclHandleExternal pfn);
Then fix zcl_port.c
// multiple endpoint for ZCL handler external, added by luoyiming 2020-02-08 typedef struct { void *next; uint8_t endpoint; zclport_pFnZclHandleExternal pfn; } zclHandleExternalList_t; // Function pointer for applications to ZCL Handle External // added multiple endpoint processing by luoyiming at 2020-02-08 zclHandleExternalList_t *zclHandleExternalList = NULL; /** * Call to register a function pointer to handle zcl_HandleExternal() messages. * Added multiple endpoint processing by luoyiming at 2020-02-08. * * Public function defined in zcl_port.h */ bool zclport_registerZclHandleExternal( uint8_t endpoint, zclport_pFnZclHandleExternal pfn ) { zclHandleExternalList_t *find = zclHandleExternalList; zclHandleExternalList_t *tail = NULL; // If endpoint is valid, added by luoyiming 2020-02-08 if ( zcl_afFindEndPointDesc( endpoint ) == NULL ) { return false; } // match if there be same endpoint and find tail item, fixed by luoyiming 2020-02-08 while ( find ) { if ( find->endpoint == endpoint ) { find->pfn = pfn; return true; } if ( find->next == NULL ) { tail = find; } find = find->next; } // add new item, fixed by luoyiming 2020-02-08 zclHandleExternalList_t *newItem = zcl_mem_alloc( sizeof(zclHandleExternalList_t) ); if ( newItem ) { newItem->next = NULL; newItem->endpoint = endpoint; newItem->pfn = pfn; if ( zclHandleExternalList == NULL ) { zclHandleExternalList = newItem; } else { tail->next = newItem; } return true; } return false; } /********************************************************************* * @fn zcl_HandleExternal * * @brief Callback function to handle messages externally * * @param pInMsg - incoming message to process * * @return TRUE */ uint8_t zcl_HandleExternal(zclIncoming_t *pInMsg) { #ifdef BDB_REPORTING zclIncomingMsg_t *pCmd; pCmd = (zclIncomingMsg_t *)OsalPort_msgAllocate( sizeof ( zclIncomingMsg_t ) ); if ( pCmd != NULL ) { // fill in the message pCmd->hdr.event = ZCL_INCOMING_MSG; pCmd->zclHdr = pInMsg->hdr; pCmd->clusterId = pInMsg->msg->clusterId; pCmd->srcAddr = pInMsg->msg->srcAddr; pCmd->endPoint = pInMsg->msg->endPoint; pCmd->attrCmd = pInMsg->attrCmd; if(pCmd->zclHdr.commandID == ZCL_CMD_CONFIG_REPORT) { zstack_bdbProcessInConfigReportReq_t Req = {0}; Req.pZclIncommingMsg = pCmd; Zstackapi_bdbProcessInConfigReportCmd(zclPortFindEntity(pCmd->endPoint),&Req); OsalPort_msgDeallocate((uint8_t*)pCmd); return TRUE; } if(pCmd->zclHdr.commandID == ZCL_CMD_READ_REPORT_CFG) { zstack_bdbProcessInReadReportCfgReq_t Req = {0}; Req.pZclIncommingMsg = pCmd; Zstackapi_bdbProcessInReadReportCfgCmd(zclPortFindEntity(pCmd->endPoint),&Req); OsalPort_msgDeallocate((uint8_t*)pCmd); return TRUE; } OsalPort_msgDeallocate((uint8_t*)pCmd); } #endif // zclHandleExternal for multiple endpoint, fixed by luoyiming 2020-02-08 zclHandleExternalList_t *find = zclHandleExternalList; // Did the application register to handle this message while ( find ) { if ( ( find->endpoint == pInMsg->msg->endPoint ) && ( find->pfn ) ) { // Let the application handle it return (find->pfn( pInMsg )); } find = find->next; } return(TRUE); }
The completely solution is in my GitHub