TI中文支持网
TI专业的中文技术问题搜集分享网站

CC2540的Center查找特征失败

我把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;
}

不能进入到上述函数。

我修改的代码为:

 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

/*********************************************************************
 * CONSTANTS
 */

#define SERVAPP_NUM_ATTR_SUPPORTED8

/*********************************************************************
 * TYPEDEFS
 */

/*********************************************************************
 * GLOBAL VARIABLES
 */
// Simple GATT Profile Service UUID: 0xFFF0
CONST uint8 simpleProfileServUUID[ATT_BT_UUID_SIZE] =
{LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID)
};

// Characteristic 1 UUID: 0xFFF1
CONST uint8 simpleProfilechar1UUID[ATT_BT_UUID_SIZE] =
{LO_UINT16(SIMPLEPROFILE_CHAR1_UUID), HI_UINT16(SIMPLEPROFILE_CHAR1_UUID)
};

// Characteristic 2 UUID: 0xFFF2
CONST uint8 simpleProfilechar2UUID[ATT_BT_UUID_SIZE] =
{LO_UINT16(SIMPLEPROFILE_CHAR2_UUID), HI_UINT16(SIMPLEPROFILE_CHAR2_UUID)
};

/*********************************************************************
 * EXTERNAL VARIABLES
 */

/*********************************************************************
 * EXTERNAL FUNCTIONS
 */

/*********************************************************************
 * LOCAL VARIABLES
 */

static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;

/*********************************************************************
 * Profile Attributes - variables
 */

// Simple Profile Service attribute
static CONST gattAttrType_t simpleProfileService = { ATT_BT_UUID_SIZE, simpleProfileServUUID };


// Simple Profile Characteristic 1 Properties
static uint8 simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE;

// Characteristic 1 Value
static uint8 simpleProfileChar1[SIMPLEPROFILE_CHAR1_LEN] =/*{0} ;*/ /**/{0xFC,0x02,0x03,0x05,0xDE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/**/

// Simple Profile Characteristic 1 User Description
static uint8 simpleProfileChar1UserDesp[17] = "Characteristic 1\0";



// Simple Profile Characteristic 2 Properties
static uint8 simpleProfileChar2Props = GATT_PROP_NOTIFY;

// Characteristic 2 Value
static uint8 simpleProfileChar2 = 0;

// Simple Profile Characteristic 2 Configuration Each client has its own
// instantiation of the Client Characteristic Configuration. Reads of the
// Client Characteristic Configuration only shows the configuration for
// that client and writes only affect the configuration of that client.
static gattCharCfg_t simpleProfileChar2Config[GATT_MAX_NUM_CONN];

// Simple Profile Characteristic 2 User Description
static uint8 simpleProfileChar2UserDesp[17] = "Characteristic 2\0";



/*********************************************************************
 * Profile Attributes - Table
 */

static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
{// Simple Profile Service{{ ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */GATT_PERMIT_READ,/* permissions */0,/* handle */(uint8 *)&simpleProfileService/* pValue */},// Characteristic 1 Declaration{{ ATT_BT_UUID_SIZE, characterUUID },GATT_PERMIT_READ,0,&simpleProfileChar1Props},// Characteristic Value 1{{ ATT_BT_UUID_SIZE, simpleProfilechar1UUID },GATT_PERMIT_READ | GATT_PERMIT_WRITE,0,simpleProfileChar1},// Characteristic 1 User Description{{ ATT_BT_UUID_SIZE, charUserDescUUID },GATT_PERMIT_READ,0,simpleProfileChar1UserDesp},// Characteristic 2 Declaration{{ ATT_BT_UUID_SIZE, characterUUID },GATT_PERMIT_READ,0,&simpleProfileChar2Props},// Characteristic Value 2{{ ATT_BT_UUID_SIZE, simpleProfilechar2UUID },0,0,&simpleProfileChar2},// Characteristic 2 configuration{{ ATT_BT_UUID_SIZE, clientCharCfgUUID },GATT_PERMIT_READ | GATT_PERMIT_WRITE,0,(uint8 *)simpleProfileChar2Config},// Characteristic 2 User Description{{ ATT_BT_UUID_SIZE, charUserDescUUID },GATT_PERMIT_READ,0,simpleProfileChar2UserDesp},

};


/*********************************************************************
 * LOCAL FUNCTIONS
 */
static uint8 simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen );
static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,uint8 *pValue, uint8 len, uint16 offset );

static void simpleProfile_HandleConnStatusCB( uint16 connHandle, uint8 changeType );


/*********************************************************************
 * PROFILE CALLBACKS
 */
// Simple Profile Service Callbacks
CONST gattServiceCBs_t simpleProfileCBs =
{simpleProfile_ReadAttrCB,  // Read callback function pointersimpleProfile_WriteAttrCB, // Write callback function pointerNULL// Authorization callback function pointer
};

/*********************************************************************
 * PUBLIC FUNCTIONS
 */

/*********************************************************************
 * @fnSimpleProfile_AddService
 *
 * @briefInitializes the Simple Profile service by registering
 *GATT attributes with the GATT server.
 *
 * @paramservices - services to add. This is a bit map and can
 *contain more than one service.
 *
 * @return  Success or Failure
 */
bStatus_t SimpleProfile_AddService( uint32 services )
{uint8 status = SUCCESS;// Initialize Client Characteristic Configuration attributesGATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar2Config );// Register with Link DB to receive link status change callbackVOID linkDB_Register( simpleProfile_HandleConnStatusCB );if ( services & SIMPLEPROFILE_SERVICE ){// Register GATT attribute list and CBs with GATT Server Appstatus = GATTServApp_RegisterService( simpleProfileAttrTbl,GATT_NUM_ATTRS( simpleProfileAttrTbl ),&simpleProfileCBs );}return ( status );
}


/*********************************************************************
 * @fnSimpleProfile_RegisterAppCBs
 *
 * @briefRegisters the application callback function. Only call
 *this function once.
 *
 * @paramcallbacks - pointer to application callbacks.
 *
 * @return  SUCCESS or bleAlreadyInRequestedMode
 */
bStatus_t SimpleProfile_RegisterAppCBs( simpleProfileCBs_t *appCallbacks )
{if ( appCallbacks ){simpleProfile_AppCBs = appCallbacks;return ( SUCCESS );}else{return ( bleAlreadyInRequestedMode );}
}


/*********************************************************************
 * @fnSimpleProfile_SetParameter
 *
 * @briefSet a Simple Profile parameter.
 *
 * @paramparam - Profile parameter ID
 * @paramlen - length of data to right
 * @paramvalue - 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 enabledGATTServApp_ProcessCharCfg( simpleProfileChar2Config, &simpleProfileChar2, FALSE,simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),INVALID_TASK_ID );}else{ret = bleInvalidRange;}break;default:ret = INVALIDPARAMETER;break;}return ( ret );
}

/*********************************************************************
 * @fnSimpleProfile_GetParameter
 *
 * @briefGet a Simple Profile parameter.
 *
 * @paramparam - Profile parameter ID
 * @paramvalue - 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 );
}

/*********************************************************************
 * @fnsimpleProfile_ReadAttrCB
 *
 * @briefRead an attribute.
 *
 * @paramconnHandle - connection message was received on
 * @parampAttr - pointer to attribute
 * @parampValue - pointer to data to be read
 * @parampLen - length of data to be read
 * @paramoffset - offset of the first octet to be read
 * @parammaxLen - maximum length of data to be read
 *
 * @returnSuccess 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 errorif ( gattPermitAuthorRead( pAttr->permissions ) ){// Insufficient authorizationreturn ( 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 UUIDuint16 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 );
}

/*********************************************************************
 * @fnsimpleProfile_WriteAttrCB
 *
 * @briefValidate attribute data prior to a write operation
 *
 * @paramconnHandle - connection message was received on
 * @parampAttr - pointer to attribute
 * @parampValue - pointer to data to be written
 * @paramlen - length of data
 * @paramoffset - offset of the first octet to be written
 * @paramcomplete - whether this is the last packet
 * @paramoper - 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 errorif ( gattPermitAuthorWrite( pAttr->permissions ) ){// Insufficient authorizationreturn ( ATT_ERR_INSUFFICIENT_AUTHOR );}if ( pAttr->type.len == ATT_BT_UUID_SIZE ){// 16-bit UUIDuint16 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 operif ( offset == 0 ){if ( len > SIMPLEPROFILE_CHAR1_LEN ){status = ATT_ERR_INVALID_VALUE_SIZE;}}else{status = ATT_ERR_ATTR_NOT_LONG;}//Write the valueif ( 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 UUIDstatus = ATT_ERR_INVALID_HANDLE;}// If a charactersitic value changed then callback function to notify application of changeif ( (notifyApp != 0xFF ) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange ){simpleProfile_AppCBs->pfnSimpleProfileChange( notifyApp );  //调用回调函数 simpleProfileChangeCB()}return ( status );
}


/*********************************************************************
 * @fnsimpleProfile_HandleConnStatusCB
 *
 * @briefSimple Profile link status change handler function.
 *
 * @paramconnHandle - connection handle
 * @paramchangeType - type of change
 *
 * @returnnone
 */
static void simpleProfile_HandleConnStatusCB( uint16 connHandle, uint8 changeType )
{// Make sure this is not loopback connectionif ( connHandle != LOOPBACK_CONNHANDLE ){// Reset Client Char Config if connection has droppedif ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED )||( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) &&( !linkDB_Up( connHandle ) ) ) ){GATTServApp_InitCharCfg( connHandle, simpleProfileChar2Config );}}
}

 
具体的两个文件就修改成这样,好奇怪就是不行。后开我修改了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;

这就可以了。不明白为什么。

 

 
Jiaming Li:

我查找特征部分代码:

static void simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg )
{attReadByTypeReq_t req;if ( simpleBLEDiscState == BLE_DISC_STATE_SVC ) {// Service found, store handles//当通过uuid GATT_DiscPrimaryServiceByUUID() 调用成功if ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&pMsg->msg.findByTypeValueRsp.numInfo > 0 ) {simpleBLESvcStartHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].handle;simpleBLESvcEndHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle;}// If procedure completeif ( ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP&&pMsg->hdr.status == bleProcedureComplete ) ||( pMsg->method == ATT_ERROR_RSP ) ){if ( simpleBLESvcStartHdl != 0 ) {// Discover characteristicsimpleBLEDiscState = BLE_DISC_STATE_CHAR;req.startHandle = simpleBLESvcStartHdl;req.endHandle = simpleBLESvcEndHdl;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);GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId );//根据服务的UUID调用API函数GATT_ReadUsingCharUUID协议栈会返回该服务的Handle。}}} else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR ) {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 Found11", HAL_LCD_LINE_1 );simpleBLEProcedureInProgress = FALSE;simpleBLEDiscState = BLE_DISC_STATE_IDLE;}else {simpleBLEDiscState = BLE_DISC_STATE_CHAR2;req.startHandle = simpleBLESvcStartHdl;req.endHandle = simpleBLESvcEndHdl;req.type.len = ATT_BT_UUID_SIZE;req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR2_UUID);//获取特性值xxxxx的handlereq.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR2_UUID);GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId );}}else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR2 ) {if ( pMsg->method == ATT_READ_BY_TYPE_RSP &&pMsg->msg.readByTypeRsp.numPairs > 0 ) {simpleBLECharHdl2 = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0],pMsg->msg.readByTypeRsp.dataList[1] );LCD_WRITE_STRING( "Simple Svc Found22", HAL_LCD_LINE_1 );simpleBLEProcedureInProgress = FALSE;LCD_WRITE_STRING( "0000000", HAL_LCD_LINE_8 );attWriteReq_t AttReq;uint8 ValueBuf[2];AttReq.handle = simpleBLECharHdl2;AttReq.len = 2;AttReq.sig = 0;AttReq.cmd = 0;ValueBuf[0] = 0x01;ValueBuf[1] = 0x00;osal_memcpy(AttReq.value,ValueBuf,2);GATT_WriteCharValue( 0, &AttReq, simpleBLETaskId );}simpleBLEDiscState = BLE_DISC_STATE_IDLE;}
}

他死活不能查找成功。

赞(0)
未经允许不得转载:TI中文支持网 » CC2540的Center查找特征失败
分享到: 更多 (0)