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.

LAUNCHXL-CC2640R2: How to enable notification in multirole program

Part Number: LAUNCHXL-CC2640R2

Hi All, 

I am working in a project to send a data from mobile application to cc2640r2 using multirole and make it relay the same data to another cc2640r2 which runs the peripheral application. These things are works well but when I send some notification from the peripheral end, it is not getting received in the multirole. I have studied some documents and came to know that I need to set a character in the multirole to enable the notification. I tried it but still I couldn't able to make it work. 

As I am new to TIRTOS, It would be great if someone could help me in showing the steps or example code to enable the notification on the multirole to receive data from peripheral. 

Thanks in advance

  • Hey Prakash,

    I've assigned an expert to comment. May I know the SDK you are working with? In addition, can you share the code you tried?

    For reference, I would start by familiarizing myself with our Custom Profile Simplelink Academy Module. The characteristic you refer to is the CCCD, which you will have to write a 0x0001 to so that the multi_role device will receive the notifcation.

  • Hi Ammar, 

    Thanks for replying to my post and assigning an expert to it. I am using simplelink_cc2640r2_sdk_2_40_00_32. I have looked into the ssp_ble_client application and tried to implement the same functionality on multi_role to enable the notification and read the data. I have changed the GATT_DiscEvent function as shown in the code below but the function is not going into the if condition to find the CCCD.

    In the task_fucntion of multirole I have created a new event called NOTI_ENABLE_EVT to write 0x0001 and to enable the notification, and in the processGATTMsg I am reading the notification. 

    Link to ssp_ble_client application is here for reference: https://github.com/ti-simplelink/ble_examples/tree/simplelink_sdk-1.50/examples/rtos/CC2640R2_LAUNCHXL/bleapps/spp_ble_client

    static void multi_role_processGATTDiscEvent(gattMsgEvent_t *pMsg)
    {
    if (discState == BLE_DISC_STATE_MTU)
    {
    // MTU size response received, discover simple service
    if (pMsg->method == ATT_EXCHANGE_MTU_RSP)
    {
    uint8_t uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(SIMPLEPROFILE_SERV_UUID),
    HI_UINT16(SIMPLEPROFILE_SERV_UUID) };

    discState = BLE_DISC_STATE_SVC;

    // Discovery simple service
    VOID GATT_DiscPrimaryServiceByUUID(pMsg->connHandle, uuid,
    ATT_BT_UUID_SIZE, selfEntity);
    }
    }
    else if (discState == BLE_DISC_STATE_SVC)
    {
    // Service found, store handles
    if (pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&
    pMsg->msg.findByTypeValueRsp.numInfo > 0)
    {
    svcStartHdl = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);
    svcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);
    }

    // If procedure complete
    if (((pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP) &&
    (pMsg->hdr.status == bleProcedureComplete)) ||
    (pMsg->method == ATT_ERROR_RSP))
    {
    if (svcStartHdl != 0)
    {
    attReadByTypeReq_t req;

    // Discover characteristic
    discState = BLE_DISC_STATE_CHAR;

    req.startHandle = svcStartHdl;
    req.endHandle = svcEndHdl;
    req.type.len = ATT_BT_UUID_SIZE;
    req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR1_UUID);
    req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR1_UUID);

    VOID GATT_DiscCharsByUUID(pMsg->connHandle, &req, selfEntity);
    }
    }
    }
    else if (discState == BLE_DISC_STATE_CHAR)
    {
    // Characteristic found, store handle
    if ((pMsg->method == ATT_READ_BY_TYPE_RSP) &&
    (pMsg->msg.readByTypeRsp.numPairs > 0))
    {
    uint8_t connIndex = SimpleCentral_getConnIndex(scConnHandle);

    // connIndex cannot be equal to or greater than MAX_NUM_BLE_CONNS
    SIMPLECENTRAL_ASSERT(connIndex < MAX_NUM_BLE_CONNS);

    // Store the handle of the simpleprofile characteristic 1 value
    connList[connIndex].charHandle
    = BUILD_UINT16(pMsg->msg.readByTypeRsp.pDataList[3],
    pMsg->msg.readByTypeRsp.pDataList[4]);

    Display_printf(dispHandle, SC_ROW_CUR_CONN, 0, "Simple Svc Found");

    // Now we can use GATT Read/Write
    tbm_setItemStatus(&scMenuPerConn,
    SC_ITEM_GATTREAD | SC_ITEM_GATTWRITE, SC_ITEM_NONE);
    }
    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
    // DEBUG("CCCD for Data Char Found..."); DEBUG_NEWLINE();
    charCCCDHdl = ATT_BT_PAIR_HANDLE(pMsg->msg.findInfoRsp.pInfo, i);
    break;
    }
    }
    else if(pMsg->msg.findInfoRsp.format == ATT_HANDLE_UUID_TYPE)
    {
    // Look for Serial Data Char.
    if (memcmp(&(pMsg->msg.findInfoRsp.pInfo[ATT_PAIR_UUID_IDX(i)]), uuidDataChar, ATT_UUID_SIZE) == 0)
    {
    // CCCD found
    // DEBUG("Data Char Found..."); //DEBUG_NEWLINE();
    Display_printf(dispHandle, 6, 0, "char CCCD Found");
    charDataHdl = ATT_BT_PAIR_HANDLE(pMsg->msg.findInfoRsp.pInfo, i);
    break;
    }
    }
    }
    }

    // If procedure complete
    if ((pMsg->method == ATT_FIND_INFO_RSP &&
    pMsg->hdr.status == bleProcedureComplete) ||
    (pMsg->method == ATT_ERROR_RSP))
    {

    //Enable notification on peripheral(after a few seconds delay, let it finish connection/discovery process)
    {
    Util_startClock(&startNotiEnableClock);
    }


    discState = BLE_DISC_STATE_IDLE;
    }
    }
    }

  • Hi Prakash,

    I don't think the example you're showing handles notifications received in the function you've posted. Rather, it looks like that happens on line 1143 of the SPPBLEClient_processGATTMsg function. Have you reviewed this? I would also take a step back and ensure that everything else is working correctly up to this point (e.g. the central is broadcasting notifications) if you have not already verified this.

    Best,

    Nate

  • Hi Nathan thanks for your response, I have also wrote the code to receive the notification inside the processGATTMsg function. Typically, I want multirole to receive notification and peripheral to send it. Using BLE scanner app I have checked and conformed that peripheral is sending the notification. The code below you can see how I am receiving the notification on the multirole end. 

    static void multirole_processGATTMsg(gattMsgEvent_t *pMsg)
    {
    if(pMsg->method == ATT_HANDLE_VALUE_NOTI)
    {
     Display_print1(dispHandle, 5, 0, "notificaiton: %d", pMsg->msg.handleValueNoti.pValue);

    }

  • Hi Prakash,

    Have you changed the CCCD in your central to enable notifications to the peripheral you're connected to? Based off this E2E post, it looks like the flow is pretty straightforward.

    https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/777504/cc2640r2f-enabling-notification-in-simple-central

    1. Call GATT_DiscAllCharDescs to get handle of CCCD

    2. Write 0x01 to CCCD handle to enable notification

    3. Add ATT_HANDLE_VALUE_NOTI to event handler in main loop

    You could verify that steps 1 and 2 happen on your peripheral device with some print statements. Then see if you start receiving notifications.

    Best,

    Nate

  • Dear Nathan, 

    Thanks a lot for your help, I could able to enable the notification now and the functionality is working pretty well. 

    Thanks to Ammar for assigning this issue to an expert.