Hello,
I want to process incoming AF Commands through MT. I know that I have to call MT_AfIncomingMsg() somewhere, but I don't know where.
Can anyone help?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello,
I want to process incoming AF Commands through MT. I know that I have to call MT_AfIncomingMsg() somewhere, but I don't know where.
Can anyone help?
Hello Panagiotis,
For the ZNP example, it is called from znp_app.c -> znpEventLoop for the AF_INCOMING_MSG_CMD case of the SYS_EVENT_MSG event. You can consider the same for zclGenericApp_event_loop.
Regards,
Ryan
I have added this in zclGenericApp_event_loop
if ( events & SYS_EVENT_MSG )
{
while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclGenericApp_TaskID )) || ((pMsg = (osal_event_hdr_t *) osal_msg_receive(zclGenericApp_TaskID)) != NULL) )
{
switch ( MSGpkt->hdr.event )
{
case AF_INCOMING_MSG_CMD:
MT_AfIncomingMsg((afIncomingMSGPacket_t *)pMsg);
break;
But it doesn't enter: case AF_INCOMING_MSG_CMD:
I made a capture where I try to discover the basic cluster attributes and use on/off cluster.
This is what I see when I execute the commands
No AF responses, so I don't know for example the attributes of the basic cluster or if the on/off actually worked
Did you define both MT_AF_FUNC and MT_AF_CB_FUNC in your project? Which packet numbers from you sniffer log align with the messages shown in your screenshot? You can send a separate command to read the on/off attribute, I'm not sure what is contained in your basic attribute discovery message. Also, AF_DATA_CONFIRM should be monitored for AF ACK messages.
Regards,
Ryan
Both MT_AF_FUNC and MT_AF_CB_FUNC are defined.
You can see on/off on No. 2312, 3004 and the basic attribute discovery message on 3028.
In the screenshots the messages that are shown are MT commands that are being read through the coordinators usb uart.
In the basic attribute discovery message, it shows what attributes are included in the basic cluster.
Both messages are af data requests.
I changed epDesc->task_id of bdb_RegisterSimpleDescriptor to &MT_TaskID and it somewhat works now.
Now with every af command I get two responses. One response is the one that I want and the other is af_register_rsp which is being sent from the coordinator to the coordinator. Why is this happening?
Also now every af command is being sent 2-3 times.
Can you post a screenshot of the behavior you are observing? I'm guessing that changing epDesc->task_id of bdb_RegisterSimpleDescriptor to &MT_TaskID is most likely causing each incoming message to also enter MT_AfCommandProcessing with a case MT_AF_REGISTER which causes MT_AfRegister to be processed and return a response. The ZNP bdb_RegisterSimpleDescriptor has epDesc->task_id set to &zcl_TaskID, the same as GenericApp, indicating that this is not the correct change to make. This is a good opportunity to reference the znp_app.c and note what is accomplished in znpEventLoop to handle incoming cases with MT_* APIs.
Regards,
Ryan
For example I press "Read basic cluster's attributes" and the proccess happens three times
Also by just enabling MT Commands I get ZDO_SRC_RTG_IND_RSP with every response.
I have modified the event loop to include the znp method but it goes straight to return
afIncomingMSGPacket_t *MSGpkt;
osal_event_hdr_t *pMsg;
if ( events & SYS_EVENT_MSG )
{
//while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclGenericApp_TaskID )) || ((pMsg = (osal_event_hdr_t *) osal_msg_receive(zclGenericApp_TaskID)) != NULL))
while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclGenericApp_TaskID )))
{
switch ( MSGpkt->hdr.event)
{
case ZCL_INCOMING_MSG:
// Incoming ZCL Foundation command/response messages
zclGenericApp_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
break;
case KEY_CHANGE:
zclGenericApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
break;
case ZDO_STATE_CHANGE:
zclGenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
// now on the network
if ( (zclGenericApp_NwkState == DEV_ZB_COORD) ||
(zclGenericApp_NwkState == DEV_ROUTER) ||
(zclGenericApp_NwkState == DEV_END_DEVICE) )
{
giGenAppScreenMode = GENERIC_MAINMODE;
zclGenericApp_LcdDisplayUpdate();
}
break;
default:
break;
}
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
}
while (((pMsg = (osal_event_hdr_t *) osal_msg_receive(zclGenericApp_TaskID)) != NULL))
{
switch (pMsg->event )
{
case CMD_SERIAL_MSG:
MT_ProcessIncoming(((mtOSALSerialData_t *)pMsg)->msg);
break;
case AF_INCOMING_MSG_CMD:
MT_AfIncomingMsg((afIncomingMSGPacket_t *)pMsg);
break;
case AF_DATA_CONFIRM_CMD:
MT_AfDataConfirm((afDataConfirm_t *)pMsg);
break;
default:
break;
}
// Release the memory
osal_msg_deallocate( (uint8 *)pMsg );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
All cases should be under the same while loop.
//... if ( events & SYS_EVENT_MSG ) { while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclGenericApp_TaskID )) ) { switch ( MSGpkt->hdr.event ) { case AF_INCOMING_MSG_CMD: MT_AfIncomingMsg((afIncomingMSGPacket_t *)MSGpkt); break; case ZCL_INCOMING_MSG: // Incoming ZCL Foundation command/response messages zclGenericApp_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt ); break; //...
Regards,
Ryan
I am pretty certain that I have already tried it like this and it didn't work. I'm going to try it again tomorrow just to be sure.
Yes it didn't work. It doesn't enter case AF_INCOMING_MSG_CMD, it goes straight to return (events ^ SYS_EVENT_MSG);
Yes I have. This is what I have defined
ewarm
CC2538_USE_ALTERNATE_INTERRUPT_MAP=1
FEATURE_RESET_MACRO
SECURE=1
TC_LINKKEY_JOIN
NV_INIT
NV_RESTORE
ZTOOL_P1
MT_TASK
MT_UTIL_FUNC
MT_SYS_FUNC
MT_AF_FUNC
MT_ZDO_FUNC
MT_ZDO_CB_FUNC
MT_ZDO_MGMT
MT_ZDO_EXTENSIONS
MT_GP_CB_FUNC
MT_APP_FUNC
MT_APP_CNF_FUNC
MT_AF_CB_FUNC
MT_NWK_FUNC
xLCD_SUPPORTED=DEBUG
MULTICAST_ENABLED=FALSE
ZCL_READ
ZCL_WRITE
ZCL_BASIC
ZCL_IDENTIFY
ZCL_REPORT_DESTINATION_DEVICE
xLEGACY_LCD_DEBUG
HAL_UART=TRUE
xHAL_SPI=TRUE
USB_SETUP_MAX_NUMBER_OF_INTERFACES=5
HAL_UART_USB
xMT_UART_DEFAULT_OVERFLOW=FALSE
xMT_UART_DEFAULT_PORT
Has your application registered for the endpoint and how is afBuildMSGIncoming processed as below?
#if defined ( MT_AF_CB_FUNC ) // If ZDO or SAPI have registered for this endpoint, dont intercept it here if (AFCB_CHECK(CB_ID_AF_DATA_IND, *(epDesc->task_id))) { MT_AfIncomingMsg( (void *)MSGpkt ); // Release the memory. osal_msg_deallocate( (void *)MSGpkt ); } else #endif { // Send message through task message. osal_msg_send( *(epDesc->task_id), (uint8 *)MSGpkt ); }
Regards,
Ryan
I think the endpoint is registered in bdb_RegisterSimpleDescriptor
void bdb_RegisterSimpleDescriptor( SimpleDescriptionFormat_t *simpleDesc ) { endPointDesc_t *epDesc; // Register the application's endpoint descriptor // - This memory is allocated and never freed. epDesc = osal_mem_alloc( sizeof ( endPointDesc_t ) ); if ( epDesc ) { // Fill out the endpoint description. epDesc->endPoint = simpleDesc->EndPoint; //epDesc->task_id = &MT_TaskID; // all messages get sent to ZCL first epDesc->task_id = &zcl_TaskID; epDesc->simpleDesc = simpleDesc; epDesc->latencyReq = noLatencyReqs; // Register the endpoint description with the AF afRegister( epDesc ); } }
afBuildMSGIncoming is processed the same way as the one you sent me.
Isn't the endpoint registered by default in the generic app example?
Is the endpoint registered the same one which incoming messages are being transmitted, and does afBuildMSGIncoming enter MT_AfIncomingMsg or osal_msg_send?
Regards,
Ryan
It doesn't enter MT_AfIncomingMsg, it goes straight to osal_msg_send.
It is the same endpoint since the packet details show that it sends it to the right endpoint and the bdb_RegisterSimpleDescriptor() parameter is zclGenericApp_SimpleDesc
This behavior would confirm that the MT application does not intercept the incoming packet as the endpoint is not reserved to be processed by the MT task (the endpoint was registered by the ZCL task instead). You can attempt to process MT_AfIncomingMsg anyway and not release the memory with osal_msg_deallocate before entering osal_msg_send as well, or send messages to an endpoint registered by the MT task which also do not have an application attached to them (which causes the behavior observed when bdb_RegisterSimpleDescriptor was modified).
Regards,
Ryan
I made this changes in afBuildMSGIncoming and now it works.
#if defined ( MT_AF_CB_FUNC ) if(epDesc->endPoint != 0){ MT_AfIncomingMsg( (void *)MSGpkt ); } #endif // Send message through task message. osal_msg_send( *(epDesc->task_id), (uint8 *)MSGpkt );
It also works the same if I put MT_AfIncomingMsg in zcl_event_loop
if ( *msgPtr == AF_INCOMING_MSG_CMD ){ zcl_ProcessMessageMSG( (afIncomingMSGPacket_t *)msgPtr ); MT_AfIncomingMsg( (afIncomingMSGPacket_t *)msgPtr ); }
Thank you for your help!!!