Part Number: CC2640
Tool/software: TI-RTOS
Hello,
I am using multi_role example code for launchpad and I am connecting one peripheral directly using GAP commands,
here I want to receive notification from peripheral to multirole client, here my peripheral sends notification from Charecteristic 4,
I am trying to enabling CCCD from client side,
but it is not getting enabled, here I am sharing code snippets.
else if (discInfo[connIndex].discState == BLE_DISC_STATE_CHAR)
{
// Characteristic descriptors found
if (pMsg->method == ATT_FIND_INFO_RSP &&
pMsg->msg.findInfoRsp.numInfo > 0)
{
uint8_t i;
// For each handle/uuid pair
for (i = 0; i < pMsg->msg.findInfoRsp.numInfo; i++)
{
if(pMsg->msg.findInfoRsp.format == ATT_HANDLE_BT_UUID_TYPE)
{
// Look for CCCD
if (ATT_BT_PAIR_UUID(pMsg->msg.findInfoRsp.pInfo, i) ==
GATT_CLIENT_CHAR_CFG_UUID)
{
// CCCD found
if (noCharCCCDHdl < MAX_CCCD_HANDLES){
charCCCDHdl[noCharCCCDHdl] = ATT_BT_PAIR_HANDLE(pMsg->msg.findInfoRsp.pInfo, i);
noCharCCCDHdl++;
}
}
}
}
}
This code is inside multi_role_processGATTDiscEvent
static uint8_t multi_role_processGATTMsg(gattMsgEvent_t *pMsg)
{
// See if GATT server was unable to transmit an ATT response
if (pMsg->hdr.status == blePending)
{
// No HCI buffer was available. Let's try to retransmit the response
// on the next connection event.
if (HCI_EXT_ConnEventNoticeCmd(pMsg->connHandle, selfEntity,
MR_CONN_EVT_END_EVT) == SUCCESS)
{
System_printf("Inside conn event notice command\n");
System_flush();
// First free any pending response
multi_role_freeAttRsp(FAILURE);
// Hold on to the response message for retransmission
pAttRsp = pMsg;
// Don't free the response message yet
return (FALSE);
}
}
else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT)
{
// ATT request-response or indication-confirmation flow control is
// violated. All subsequent ATT requests or indications will be dropped.
// The app is informed in case it wants to drop the connection.
// Display the opcode of the message that caused the violation.
// Display_print1(dispHandle, 0, 0, "FC Violated: %d", pMsg->msg.flowCtrlEvt.opcode);
}
else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
{
// MTU size updated
Display_print1(dispHandle, 0, 0, "MTU Size: %d", pMsg->msg.mtuEvt.MTU);
}
//messages from GATT server
if (linkDB_NumActive() > 0)
{
// System_printf("Inside linkDB_NumActive>0\n");
// System_flush();
//find index from connection handle
connIndex = multi_role_mapConnHandleToIndex(pMsg->connHandle);
if ((pMsg->method == ATT_READ_RSP) ||
(pMsg->method == ATT_HANDLE_VALUE_NOTI) ||
((pMsg->method == ATT_ERROR_RSP) &&
(pMsg->msg.errorRsp.reqOpcode == ATT_READ_REQ)))
{
if (pMsg->method == ATT_ERROR_RSP)
{
// Display_print1(dispHandle, 0, 0, "Read Error %d", pMsg->msg.errorRsp.errCode);
}
else
{
// After a successful read, display the read value
// Display_print1(dispHandle, 0, 0, "Read rsp: %d", pMsg->msg.readRsp.pValue[0]);
uint8_t *notificationdata = pMsg->msg.handleValueNoti.pValue;
}
}
else if ((pMsg->method == ATT_WRITE_RSP) ||
((pMsg->method == ATT_ERROR_RSP) &&
(pMsg->msg.errorRsp.reqOpcode == ATT_WRITE_REQ)))
{
if (pMsg->method == ATT_ERROR_RSP == ATT_ERROR_RSP)
{
// Display_print1(dispHandle, 0, 0, "Write Error %d", pMsg->msg.errorRsp.errCode);
}
else
{
// After a succesful write, display the value that was written and
// increment value
// Display_print1(dispHandle, 0, 0, "Write sent: %d", charVal++);
}
}
else if (discInfo[connIndex].discState != BLE_DISC_STATE_IDLE)
{
multi_role_processGATTDiscEvent(pMsg);
}
} // else - in case a GATT message came after a connection has dropped, ignore it.
// Free message payload. Needed only for ATT Protocol messages
GATT_bm_free(&pMsg->msg, pMsg->method);
// It's safe to free the incoming message
return (TRUE);
}
This is multi_role_processGATTMsg function
static void multi_role_EnableNotification( uint16 connHandle, uint16 attrHandle )
{
attWriteReq_t req;
// System_printf("Inside enable notification\n");
// System_flush();
req.pValue = GATT_bm_alloc( connHandle, ATT_WRITE_REQ, 2, NULL );
if ( req.pValue != NULL )
{
uint8 notificationsOn[] = {0x01, 0x00};
// attAttribute_t
req.handle = attrHandle;
req.len = 2;
memcpy(req.pValue, notificationsOn, 2);
req.sig = FALSE;
req.cmd = TRUE;
if ( GATT_WriteNoRsp( connHandle, &req ) != SUCCESS )
{
GATT_bm_free( (gattMsg_t *)&req, ATT_WRITE_REQ );
}
}
}
This is enable notification function
Util_constructClock(&startNotiEnableClock, multi_role_startNotiHandler,
DEFAULT_NOTI_ENABLE_DELAY, 0, false, SBC_START_NOTIFICATION);
if (currentCharCCCDHdlIndex < noCharCCCDHdl)
{
multi_role_EnableNotification( connHandle, charCCCDHdl[currentCharCCCDHdlIndex ] );
currentCharCCCDHdlIndex ++;
//Enable notification on peripheral(after a few seconds delay, let it finish connection/discovery process)
{
Util_startClock(&startNotiEnableClock);
}
}
This is timer for some delay for connection establishment.
here in multi_role_processGATTDiscEvent while debugging i found that It's not going into loop where I find CCCD.
Please provide some guidance so I can resolve this issue as soon as possible.
regards,
jaydipsinh
