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就不行了。好奇怪。
你有相关的例程的话,可以发给我参考下。
