微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI蓝牙设计交流 > CHAR1的长度改成20后,查找不了特征值?

CHAR1的长度改成20后,查找不了特征值?

时间:10-02 整理:3721RD 点击:

我把center和peripheral的GATTProfile文件修改成char1能发送20个字节,错误,查找不到特征值。

if ( pMsg->method == ATT_READ_BY_TYPE_RSP &&
      pMsg->msg.readByTypeRsp.numPairs > 0 ) {
    simpleBLECharHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0],
                                     pMsg->msg.readByTypeRsp.dataList[1] );
    LCD_WRITE_STRING( "Simple Svc Found", HAL_LCD_LINE_1 );
    simpleBLEProcedureInProgress = FALSE;
    simpleBLEDiscState = BLE_DISC_STATE_IDLE;
}

不能进入到上述函数,LCD一直没有显示"Simple Svc Found"。

我修改的代码为:

 simpleGATTprofile.h

// Profile Parameters
#define SIMPLEPROFILE_CHAR1 0 // RW uint8 - Profile Characteristic 1 value
#define SIMPLEPROFILE_CHAR2 1 // RW uint8 - Profile Characteristic 2 value

// Simple Profile Service UUID
#define SIMPLEPROFILE_SERV_UUID 0xFFF0

// Key Pressed UUID
#define SIMPLEPROFILE_CHAR1_UUID 0xFFF1
#define SIMPLEPROFILE_CHAR2_UUID 0xFFF2

// Simple Keys Profile Services bit fields
#define SIMPLEPROFILE_SERVICE 0x00000001

#define SIMPLEPROFILE_CHAR1_LEN 20

 simpleGATTprofile.c

/*********************************************************************
 * @fn      SimpleProfile_SetParameter
 *
 * @brief   Set a Simple Profile parameter.
 *
 * @param   param - Profile parameter ID
 * @param   len - length of data to right
 * @param   value - pointer to data to write.  This is dependent on
 *          the parameter ID and WILL be cast to the appropriate
 *          data type (example: data type of uint16 will be cast to
 *          uint16 pointer).
 *
 * @return  bStatus_t
 */
bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
{
  bStatus_t ret = SUCCESS;
  switch ( param )
  {
    case SIMPLEPROFILE_CHAR1:
      if ( len <= SIMPLEPROFILE_CHAR1_LEN )
      {
          VOID osal_memcpy( simpleProfileChar1, value, len );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case SIMPLEPROFILE_CHAR2:
      if ( len == sizeof ( uint8 ) )
      {
        simpleProfileChar2 = *((uint8*)value);

        // See if Notification has been enabled
        GATTServApp_ProcessCharCfg( simpleProfileChar2Config, &simpleProfileChar2, FALSE,
                                    simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                    INVALID_TASK_ID );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    default:
      ret = INVALIDPARAMETER;
      break;
  }

  return ( ret );
}

/*********************************************************************
 * @fn      SimpleProfile_GetParameter
 *
 * @brief   Get a Simple Profile parameter.
 *
 * @param   param - Profile parameter ID
 * @param   value - pointer to data to put.  This is dependent on
 *          the parameter ID and WILL be cast to the appropriate
 *          data type (example: data type of uint16 will be cast to
 *          uint16 pointer).
 *
 * @return  bStatus_t
 */
bStatus_t SimpleProfile_GetParameter( uint8 param, void *value )
{
  bStatus_t ret = SUCCESS;
  switch ( param )
  {
    case SIMPLEPROFILE_CHAR1:
       VOID osal_memcpy( value, simpleProfileChar1, SIMPLEPROFILE_CHAR1_LEN );  //simpleProfileChar1 是数组名
      break;

    case SIMPLEPROFILE_CHAR2:
      *((uint8*)value) = simpleProfileChar2;
      break;

    default:
      ret = INVALIDPARAMETER;
      break;
  }

  return ( ret );
}

/*********************************************************************
 * @fn          simpleProfile_ReadAttrCB
 *
 * @brief       Read an attribute.
 *
 * @param       connHandle - connection message was received on
 * @param       pAttr - pointer to attribute
 * @param       pValue - pointer to data to be read
 * @param       pLen - length of data to be read
 * @param       offset - offset of the first octet to be read
 * @param       maxLen - maximum length of data to be read
 *
 * @return      Success or Failure
 */
static uint8 simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                            uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen )
{
  bStatus_t status = SUCCESS;

  // If attribute permissions require authorization to read, return error
  if ( gattPermitAuthorRead( pAttr->permissions ) )
  {
    // Insufficient authorization
    return ( ATT_ERR_INSUFFICIENT_AUTHOR );
  }

  // Make sure it's not a blob operation (no attributes in the profile are long)
  if ( offset > 0 )
  {
    return ( ATT_ERR_ATTR_NOT_LONG );
  }

  if ( pAttr->type.len == ATT_BT_UUID_SIZE )
  {
    // 16-bit UUID
    uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    switch ( uuid )
    {
      case SIMPLEPROFILE_CHAR1_UUID:
        *pLen = SIMPLEPROFILE_CHAR1_LEN;
        VOID osal_memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN );
        break;
      case SIMPLEPROFILE_CHAR2_UUID:
        *pLen = 1;
        pValue[0] = *pAttr->pValue;
        break;

      default:
        // Should never get here! (characteristics 3 and 4 do not have read permissions)
        *pLen = 0;
        status = ATT_ERR_ATTR_NOT_FOUND;
        break;
    }
  }
  else
  {
    // 128-bit UUID
    *pLen = 0;
    status = ATT_ERR_INVALID_HANDLE;
  }

  return ( status );
}

/*********************************************************************
 * @fn      simpleProfile_WriteAttrCB
 *
 * @brief   Validate attribute data prior to a write operation
 *
 * @param   connHandle - connection message was received on
 * @param   pAttr - pointer to attribute
 * @param   pValue - pointer to data to be written
 * @param   len - length of data
 * @param   offset - offset of the first octet to be written
 * @param   complete - whether this is the last packet
 * @param   oper - whether to validate and/or write attribute value
 *
 * @return  Success or Failure
 */

static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                                 uint8 *pValue, uint8 len, uint16 offset )

{
  bStatus_t status = SUCCESS;
  uint8 notifyApp = 0xFF;

  // If attribute permissions require authorization to write, return error
  if ( gattPermitAuthorWrite( pAttr->permissions ) )
  {
    // Insufficient authorization
    return ( ATT_ERR_INSUFFICIENT_AUTHOR );
  }

  if ( pAttr->type.len == ATT_BT_UUID_SIZE )
  {
    // 16-bit UUID
    uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    switch ( uuid )
    {
      case SIMPLEPROFILE_CHAR1_UUID:

        //Validate the value
        // Make sure it's not a blob oper
        if ( offset == 0 )
        {
            if ( len > SIMPLEPROFILE_CHAR1_LEN )
            {
                status = ATT_ERR_INVALID_VALUE_SIZE;
            }
        }
        else
        {
          status = ATT_ERR_ATTR_NOT_LONG;
        }

        //Write the value
        if ( status == SUCCESS )
        {
//            uint8 *pCurValue = (uint8 *)pAttr->pValue;
//            osal_memset(pCurValue,0,SIMPLEPROFILE_CHAR1_LEN);
//            VOID osal_memcpy( pCurValue, pValue, len );

            uint8 i = 0;
            uint8 *pCurValue = (uint8 *)pAttr->pValue;
            for ( i = 0; i<len; i++) {
                *pCurValue = pValue[i];
                pCurValue++;
            };
            if(len < SIMPLEPROFILE_CHAR1_LEN) {
                for (; i<SIMPLEPROFILE_CHAR1_LEN; i++) {
                    *pCurValue = 0;
                    *pCurValue ++;
                }
            }
            notifyApp = SIMPLEPROFILE_CHAR1;
        }
        break;

      case GATT_CLIENT_CHAR_CFG_UUID:
        status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                 offset, GATT_CLIENT_CFG_NOTIFY );
        break;

      default:
        // Should never get here! (characteristics 2 and 4 do not have write permissions)
        status = ATT_ERR_ATTR_NOT_FOUND;
        break;
    }
  }
  else
  {
    // 128-bit UUID
    status = ATT_ERR_INVALID_HANDLE;
  }

  // If a charactersitic value changed then callback function to notify application of change
  if ( (notifyApp != 0xFF ) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange )
  {
    simpleProfile_AppCBs->pfnSimpleProfileChange( notifyApp );  //调用回调函数 simpleProfileChangeCB()
  }

  return ( status );
}
具体的两个文件就修改成这样,好奇怪就是不行。后开我修改了simpleProfile_ReadAttrCB函数的:
   case SIMPLEPROFILE_CHAR1_UUID:
        *pLen = SIMPLEPROFILE_CHAR1_LEN;
        VOID osal_memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN );
        break;

改成:

     case SIMPLEPROFILE_CHAR1_UUID:
          *pLen = 16;
          VOID osal_memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN );
          break;

这样就可以了。但只是16个字节。

 








用仿真器设置断点调试一下吧。或者用抓包软件看一下。

看过了,GATT_ReadUsingCharUUID后,下面的pMsg->method == ATT_READ_BY_TYPE_RSP一直不成立。然后抓包发现char1 的句柄为0x25,然后用这个来发数据就能发了。

但是我把长度修改为1到19个,都可以发现句柄的,pMsg->method == ATT_READ_BY_TYPE_RSP是成立的。但是长度为20就不行了。好奇怪。

你有相关的例程的话,可以发给我参考下。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top