我把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;} }他死活不能查找成功。
TI中文支持网


