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.

RTOS/LAUNCHXL-CC2650: BLE central device, GATT_DiscCharsByUUID()

Part Number: LAUNCHXL-CC2650
Other Parts Discussed in Thread: CC2650

Tool/software: TI-RTOS

Hello,

I am working on a product prototyping on CC2650 launchpad with the simple central (from simple-link  GitHub) as the starting point for the application.

I would like to read and write the characteristics value of another CC2650 launchpad running  on simple peripheral. After reading the user guide I replace my code in the

buttoncb function (  SimpleBLECentral_handleKeys()  ). on building the code it is throwing lot of errors.

can I use the  GATT_DiscCharsByUUID() function directly before discovering service?

GATT_DiscCharsByUUID( uint16 connHandle, attReadByTypeReq_t *pReq, uint8 taskId )

Also what is the taskid parameter and pReq?  any implementation example available?

where could I get support on this?

Thank you

Regards,

Tom Victor
CTO, Technorip Innovations pvt Ltd

  • Hi Tom,

    You need the start and end handles of the service to use GATT_DiscCharsByUUID(), so you will have to do a GATT_DiscPrimaryServiceByUUID() first. Also when you have done GATT_DiscPrimaryServiceByUUID() you don't have to discover the charcteristics since they are part of the service. In simple_central, look at SimpleBLECentral_processGATTDiscEvent() where simple profile is discovered, then characteristic 1 is read.

    You can read more about the exchange of requests (attReadByTypeReq_t) and the GATT events containing the response (ATT_FIND_BY_TYPE_VALUE_RSP, ATT_READ_BY_TYPE_RSP and ATT_ERROR_RSP) in the BLE core spec. ( www.bluetooth.com/.../adopted-specifications )

    The pReq should be a pointer to a attReadByTypeReq_t struct and the taskId is the task you want to be notified of the response. If you use selfEntity, the response can be fetched as a pMsg from SimpleBLECentral_processGATTDiscEvent().
  • Thank you Marie,

    I have few more doubts,

    In my case, BLE service is designed using Bluetooth developer studio, so I can directly use the known UUIDs on GATT_DiscPrimaryServiceByUUID() (assuming task id is selfEntity)right?

    Where should I process the response, in the SimpleBLECentral_processStackMsg() function. Which event should I switched?

    static void SimpleBLECentral_processStackMsg(ICall_Hdr *pMsg)
    {
      switch (pMsg->event)
      {
        case GAP_MSG_EVENT:
          SimpleBLECentral_processRoleEvent((gapCentralRoleEvent_t *)pMsg);
          break;
    
        case GATT_MSG_EVENT:
          SimpleBLECentral_processGATTMsg((gattMsgEvent_t *)pMsg);
          break;
    
        case HCI_GAP_EVENT_EVENT:
          {
            // Process HCI message
            switch(pMsg->status)
            {
              case HCI_COMMAND_COMPLETE_EVENT_CODE:
                SimpleBLECentral_processCmdCompleteEvt((hciEvt_CmdComplete_t *)pMsg);
                break;
    
              default:
                break;
            }
          }
          break;
    
        default:
          break;
      }
    }
    

    Thank you

    Regards,

    Tom Victor

  • Hi Tom,

    Unless you have specified that your service should be a secondary service (and not a primary service which is the default), you can use GATT_DiscPrimaryServiceByUUID().

    SimpleBLECentral_processStackMsg() will sort the events for you. GATT_DiscPrimaryServiceByUUID() will return a GATT_MSG_EVENT, so you should go to SimpleBLECentral_processGATTMsg().

    If you want, you can take the code already in place in simple central to discover Simple Service and replace its UUIDs with you own. Again, please take a look at the BLE Core spec ( www.bluetooth.com/.../adopted-specifications ), chapter 4.4.2 Discover Primary Service by Service UUID!

  • Dear Marie,

    Thank you for the information.

    I just gone through the guides and program,  I got few doubts !

    In the SimpleBLECentral_processGATTDiscEvent() function,  I want to read the characteristics value (defined by GATT_ReadUsingCharUUID() function) . I am able to enter into the if condition(code below) and print the the display code. But I cant understand the correct data pointer holding the characteristic value, from the att.h file.

    else if (discState == BLE_DISC_STATE_CHAR)
        {
            // Characteristic found, store handle
            if ((pMsg->method == ATT_READ_BY_TYPE_RSP) &&
                (pMsg->msg.readByTypeRsp.numPairs > 0))
            {
                charHdl = BUILD_UINT16(pMsg->msg.readByTypeRsp.pDataList[0],
                                       pMsg->msg.readByTypeRsp.pDataList[1]);
                Display_print0(dispHandle, ROW_THREE, 0, "Simple Svc Found");
                procedureInProgress = FALSE;
            }
            discState = BLE_DISC_STATE_IDLE;
        }

    I hope "attMsg_t" is the data structure holding the response pointers? 

    can I use the following method

    for(i=0; i< pMsg->msg.readRsp.len; i++){
                    response[i] = pMsg->msg.readRsp.pValue ;
                }

    Thank you Marie

    Regards,

    Tom Victor

  • Hi Tom,

    Quoting the core spec: "Read By Type Response returns a list of Attribute Handle and Attribute Value pairs[...]", meaning that DataList also contains the attribute values. So if you want to see the value of the attribute you have too look at pDataList[2] etc. for all the attributes belonging to the characteristic.

    Alternatively you can send a read request using the characteristic handle obtained from GATT_ReadUsingCharUUID(). There is an example of this in simple central under SimpleBLECentral_handleKeys, case MENU_ITEM_READ_WRITE:

    				  				// Do a read
    				  				attReadReq_t req;
    				  				req.handle = charHdl;
    				  				status = GATT_ReadCharValue(connHandle, &req, selfEntity);
    				  				Display_print0(dispHandle, ROW_SIX, 0, "Read req sent");

    The reply comes in SimpleBLECentral_processGATTMsg(), ATT_READ_RSP:

    if (pMsg->method == ATT_ERROR_RSP)
    			{
    				Display_print1(dispHandle, ROW_SIX, 0, "Read Error %d", pMsg->msg.errorRsp.errCode);
    			}
    else
    			{
    				// After a successful read, display the read value
    				Display_print1(dispHandle, ROW_SIX, 0, "Read rsp: %d", pMsg->msg.readRsp.pValue[0]);
    			}

    PS. I'm aware that this is super confusing, but we will get there! :)