Quantcast
Channel: Forums - Recent Threads
Viewing all articles
Browse latest Browse all 262198

LAUNCHXL-CC26X2R1: Multi_role / GATT CLIENT and GATT Server Simultaneously

$
0
0

Part Number: LAUNCHXL-CC26X2R1

Hi all!

So I don't want you guys to get bored, so I have a new question :-)

In the past Simple Link Academy has been a massive help, but I did notice in the last days, that the information of using simple_central / multi_role as a GATT Client is very minimal. Therefor I do have some questions and yes I read chapter "Generic Attribute Profile (GATT)" and "ATT and GATT Introduction" multiple times, but I'm still stuck with the following question and problem.

1. When I use 2 multi_role devices that advertise and scan Simultaneously and connect to each other, how can I check which device is the Gatt Client and which the Gatt Server in this particular connection.

2. Without knowing how to solve no. 1 I try to write as a GATT Client to the GATT Server to a custom profile and I always get as a return "Write Error 1" when using GATT_WriteCharValue(), Here is my code where I try to write the Value to a custom profile after I press a button: 

 status_t status7;
                       uint8_t charVals[4] = { 0x04, 0x04, 0x04, 0x04 }; // Should be consistent with
                                                                                               // those in scMenuGattWrite
                       attWriteReq_t req;

                       req.pValue = GATT_bm_alloc(connHandle2, ATT_WRITE_REQ, 1, NULL);

                       if ( req.pValue != NULL )
                        {
                              uint8_t connIndex = multi_role_getConnIndex(connHandle2);

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

                              req.handle = connList[connIndex].charHandle;
                              req.len = 1;
                              charVal = charVals[1];
                              req.pValue[0] = charVal;
                              req.sig = 0;
                              req.cmd = 0;


                              status7 = GATT_WriteCharValue(connHandle2, &req, selfEntity);
                              if ( status7 != SUCCESS )
                              {
                                  GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);
                              }else
                              {
                                  Display_printf(dispHandle, MR_ROW_MYADDRSS, 0,  "Write Request Sent to connhandle %i", connHandle2);
                              }
                          }

This Is my multi_role_processGATTDiscEvent:

static void multi_role_processGATTDiscEvent(gattMsgEvent_t *pMsg)
{
  uint8_t connIndex = multi_role_getConnIndex(pMsg->connHandle);
  MULTIROLE_ASSERT(connIndex < MAX_NUM_BLE_CONNS);

  if (connList[connIndex].discState == BLE_DISC_STATE_MTU)
  {
    // MTU size response received, discover Custom service
    if (pMsg->method == ATT_EXCHANGE_MTU_RSP)
    {
      uint8_t uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(CUSTOMSERVICE_SERV_UUID),
                                         HI_UINT16(CUSTOMSERVICE_SERV_UUID) };

      connList[connIndex].discState = BLE_DISC_STATE_SVC;

      // Discovery Custom service
      VOID GATT_DiscPrimaryServiceByUUID(pMsg->connHandle, uuid,
                                         ATT_BT_UUID_SIZE, selfEntity);
    }
  }
  else if (connList[connIndex].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
        connList[connIndex].discState = BLE_DISC_STATE_CHAR;

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

        VOID GATT_DiscCharsByUUID(pMsg->connHandle, &req, selfEntity);
      }
    }
  }
  else if (connList[connIndex].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 = multi_role_getConnIndex(connHandle2);

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

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

      Display_printf(dispHandle, 13, 0, "Custom Svc Found");

      // Now we can use GATT Read/Write
      tbm_setItemStatus(&mrMenuPerConn,
                        MR_ITEM_GATTREAD | MR_ITEM_GATTWRITE, MR_ITEM_NONE);
    }

    connList[connIndex].discState = BLE_DISC_STATE_IDLE;
  }
}

This is my multi_role_processGATTMsg

static uint8_t multi_role_processGATTMsg(gattMsgEvent_t *pMsg)
{

  // Get connection index from handle
  uint8_t connIndex = multi_role_getConnIndex(pMsg->connHandle);
  MULTIROLE_ASSERT(connIndex < MAX_NUM_BLE_CONNS);



  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_printf(dispHandle, MR_ROW_CUR_CONN, 0, "FC Violated: %d", pMsg->msg.flowCtrlEvt.opcode);

  }
  else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
  {
    // MTU size updated
    Display_printf(dispHandle, MR_ROW_CUR_CONN, 0, "MTU Size: %d", pMsg->msg.mtuEvt.MTU);

  }


  // Messages from GATT server
  if (linkDB_Up(pMsg->connHandle))
  {

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

    }
    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)
      {
        Display_printf(dispHandle, 0, SP_NVS_DEBUG, "Write Error %d", pMsg->msg.errorRsp.errCode);

      }
      else
      {
        // After a succesful write, display the value that was written and
        // increment value
        Display_printf(dispHandle, SP_NVS_DEBUG, 0, "Write sent: %d", charVal);
      }

      tbm_goTo(&mrMenuPerConn);
    }
    else if (connList[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);
}

If I write a 0x04 to the characteristic Value CUSTOM_SERV6_UUID via the SimpleLink iOS app it works perfectly, but not if I do it from the multi_role -> multi_role.

I'm pretty sure I have a mistake there, I noticed that everything is very well explained, but I think the information how a GATT Client operates is very minimal and the past questions in the forum are not a big help.

Thanks in advance.


Kind Regards,

SPEEDBIRD


Viewing all articles
Browse latest Browse all 262198

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>