上位机public void setNotification(String serviceUUID, String characteristicUUID,boolean enable);
public void setNotification(0xFFE0,0xFFE4,TRUE);
设备CC2541:在SimpleBLEPeripheral工程上修改,增加了char6,
对于增加char6:
1、修改simpleGATTprofile.h 的宏定义
// Simple Profile Service UUID
#define SIMPLEPROFILE_SERV_UUID 0xFFE0
// Key Pressed UUID
#define SIMPLEPROFILE_CHAR1_UUID 0xFFF1
#define SIMPLEPROFILE_CHAR2_UUID 0xFFF2
#define SIMPLEPROFILE_CHAR3_UUID 0xFFF3
#define SIMPLEPROFILE_CHAR4_UUID 0xFFF4
#define SIMPLEPROFILE_CHAR5_UUID 0xFFF5
#define SIMPLEPROFILE_CHAR6_UUID 0xFFE4
#define SIMPLEPROFILE_CHAR7_UUID 0xFFE5
2、添加char6的UUID : 0xFFE4
3、添加char6的设置属性
// Simple Profile Characteristic 6 Properties
static uint8 simpleProfileChar6Props = GATT_PROP_READ | GATT_PROP_WRITE | GATT_PROP_NOTIFY;
4、属性表修改
5、修改参数函数
6、修改读写特征值函数
7、修改回调函数simpleProfileChangeCB
8、修改周期函数performPeriodicTask
9、修改应用层初始化SimpleBLEPeripheral_Init
都改了,但设备还是接收不到APP发送过来的数据,求教TI大神.
GATT代码如下。
/**************************************************************************************************
Filename: simpleGATTprofile.c
Revised: $Date: 2013-05-06 13:33:47 -0700 (Mon, 06 May 2013) $
Revision: $Revision: 34153 $
Description: This file contains the Simple GATT profile sample GATT service profile for use with the BLE sample application.
Copyright 2010 – 2013 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED 揂S IS?WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.**************************************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "bcomdef.h"
#include "OSAL.h"
#include "linkdb.h"
#include "att.h"
#include "gatt.h"
#include "gatt_uuid.h"
#include "gattservapp.h"
#include "gapbondmgr.h"
#include "simpleGATTprofile.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
#define SERVAPP_NUM_ATTR_SUPPORTED 25//21//17
/*********************************************************************
* 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)
};
// Characteristic 3 UUID: 0xFFF3
CONST uint8 simpleProfilechar3UUID[ATT_BT_UUID_SIZE] =
{ LO_UINT16(SIMPLEPROFILE_CHAR3_UUID), HI_UINT16(SIMPLEPROFILE_CHAR3_UUID)
};
// Characteristic 4 UUID: 0xFFF4
CONST uint8 simpleProfilechar4UUID[ATT_BT_UUID_SIZE] =
{ LO_UINT16(SIMPLEPROFILE_CHAR4_UUID), HI_UINT16(SIMPLEPROFILE_CHAR4_UUID)
};
// Characteristic 5 UUID: 0xFFF5
CONST uint8 simpleProfilechar5UUID[ATT_BT_UUID_SIZE] =
{ LO_UINT16(SIMPLEPROFILE_CHAR5_UUID), HI_UINT16(SIMPLEPROFILE_CHAR5_UUID)
};
// Characteristic 6 UUID: 0xFFE4
CONST uint8 simpleProfilechar6UUID[ATT_BT_UUID_SIZE] =
{ LO_UINT16(SIMPLEPROFILE_CHAR6_UUID), HI_UINT16(SIMPLEPROFILE_CHAR6_UUID)
};
// Characteristic 7 UUID: 0xFFF7
CONST uint8 simpleProfilechar7UUID[ATT_BT_UUID_SIZE] =
{ LO_UINT16(SIMPLEPROFILE_CHAR7_UUID), HI_UINT16(SIMPLEPROFILE_CHAR7_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 = 0;
// Simple Profile Characteristic 1 User Description
static uint8 simpleProfileChar1UserDesp[17] = "Characteristic 1\0";
// Simple Profile Characteristic 2 Properties
static uint8 simpleProfileChar2Props = GATT_PROP_READ;
// Characteristic 2 Value
static uint8 simpleProfileChar2 = 0;
// Simple Profile Characteristic 2 User Description
static uint8 simpleProfileChar2UserDesp[17] = "Characteristic 2\0";
// Simple Profile Characteristic 3 Properties
static uint8 simpleProfileChar3Props = GATT_PROP_WRITE;
// Characteristic 3 Value
static uint8 simpleProfileChar3 = 0;
// Simple Profile Characteristic 3 User Description
static uint8 simpleProfileChar3UserDesp[17] = "Characteristic 3\0";
// Simple Profile Characteristic 4 Properties
static uint8 simpleProfileChar4Props = GATT_PROP_NOTIFY;
// Characteristic 4 Value
static uint8 simpleProfileChar4 = 0;
// Simple Profile Characteristic 4 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 simpleProfileChar4Config[GATT_MAX_NUM_CONN];
// Simple Profile Characteristic 4 User Description
static uint8 simpleProfileChar4UserDesp[17] = "Characteristic 4\0";
// Simple Profile Characteristic 5 Properties
static uint8 simpleProfileChar5Props = GATT_PROP_READ;
// Characteristic 5 Value
static uint8 simpleProfileChar5[SIMPLEPROFILE_CHAR5_LEN] = { 0, 0, 0, 0, 0 };
// Simple Profile Characteristic 5 User Description
static uint8 simpleProfileChar5UserDesp[17] = "Characteristic 5\0";
// Simple Profile Characteristic 6 Properties
static uint8 simpleProfileChar6Props = GATT_PROP_READ | GATT_PROP_WRITE | GATT_PROP_NOTIFY;
//static uint8 simpleProfileChar6Props = GATT_PROP_READ;
// Characteristic 6 Value
static uint8 simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN] = { 0, 0, 0, 0, 0 };
static uint8 simpleProfileChar6Len = 0;
// Simple Profile Characteristic 6 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 simpleProfileChar6Config[GATT_MAX_NUM_CONN];
// Simple Profile Characteristic 6 User Description
static uint8 simpleProfileChar6UserDesp[17] = "Characteristic 6\0";
// Simple Profile Characteristic 7 Properties
//static uint8 simpleProfileChar7Props = GATT_PROP_NOTIFY;
// Characteristic 7 Value
static uint8 simpleProfileChar7[SIMPLEPROFILE_CHAR7_LEN] = { 0, 0, 0, 0, 0 };
static uint8 simpleProfileChar7Len = 0;
// Simple Profile Characteristic 7 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 simpleProfileChar7Config[GATT_MAX_NUM_CONN];
// Simple Profile Characteristic 7 User Description
//static uint8 simpleProfileChar7UserDesp[17] = "Characteristic 7\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 },
GATT_PERMIT_READ, 0, &simpleProfileChar2 },
// Characteristic 2 User Description
{ { ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ, 0, simpleProfileChar2UserDesp }, // Characteristic 3 Declaration
{ { ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ, 0,
&simpleProfileChar3Props },
// Characteristic Value 3
{ { ATT_BT_UUID_SIZE, simpleProfilechar3UUID },
GATT_PERMIT_WRITE, 0, &simpleProfileChar3 },
// Characteristic 3 User Description
{ { ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ, 0, simpleProfileChar3UserDesp },
// Characteristic 4 Declaration
{ { ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ, 0,
&simpleProfileChar4Props },
// Characteristic Value 4
{ { ATT_BT_UUID_SIZE, simpleProfilechar4UUID },
0, 0, &simpleProfileChar4 },
// Characteristic 4 configuration
{ { ATT_BT_UUID_SIZE, clientCharCfgUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, (uint8 *)simpleProfileChar4Config },
// Characteristic 4 User Description
{ { ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ, 0, simpleProfileChar4UserDesp },
// Characteristic 5 Declaration
{ { ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ, 0,
&simpleProfileChar5Props },
// Characteristic Value 5
{ { ATT_BT_UUID_SIZE, simpleProfilechar5UUID },
GATT_PERMIT_AUTHEN_READ, 0, simpleProfileChar5 },
// Characteristic 5 User Description
{ { ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ, 0, simpleProfileChar5UserDesp },
// Characteristic 6 Declaration
{ { ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ, 0,
&simpleProfileChar6Props },
// Characteristic Value 6
{ { ATT_BT_UUID_SIZE, simpleProfilechar6UUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0, simpleProfileChar6 },
// Characteristic 6 configuration
{ { ATT_BT_UUID_SIZE, clientCharCfgUUID },
GATT_PERMIT_AUTHEN_READ | GATT_PERMIT_WRITE, 0, (uint8 *)simpleProfileChar6Config },
// Characteristic 6 User Description
{ { ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ, 0, simpleProfileChar6UserDesp },
#if 0 // Characteristic 7 Declaration
{ { ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ, 0,
&simpleProfileChar7Props },
// Characteristic Value 7
{ { ATT_BT_UUID_SIZE, simpleProfilechar7UUID },
0,
0, simpleProfileChar7 },
// Characteristic 7 configuration
{ { ATT_BT_UUID_SIZE, clientCharCfgUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, (uint8 *)simpleProfileChar7Config },
// Characteristic 7 User Description
{ { ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ, 0, simpleProfileChar7UserDesp },
#endif
};
/*********************************************************************
* 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 pointer
simpleProfile_WriteAttrCB, // Write callback function pointer
NULL // Authorization callback function pointer
};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn SimpleProfile_AddService
*
* @brief Initializes the Simple Profile service by registering
* GATT attributes with the GATT server.
*
* @param services – 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 attributes
GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar4Config );
GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar6Config );
// Register with Link DB to receive link status change callback
VOID linkDB_Register( simpleProfile_HandleConnStatusCB ); if ( services & SIMPLEPROFILE_SERVICE )
{
// Register GATT attribute list and CBs with GATT Server App
status = GATTServApp_RegisterService( simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
&simpleProfileCBs );
}
return ( status );
}
/*********************************************************************
* @fn SimpleProfile_RegisterAppCBs
*
* @brief Registers the application callback function. Only call * this function once.
*
* @param callbacks – 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 );
}
}
/*********************************************************************
* @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 == sizeof ( uint8 ) ) {
simpleProfileChar1 = *((uint8*)value);
}
else
{
ret = bleInvalidRange;
}
break;
case SIMPLEPROFILE_CHAR2:
if ( len == sizeof ( uint8 ) ) {
simpleProfileChar2 = *((uint8*)value);
}
else
{
ret = bleInvalidRange;
}
break;
case SIMPLEPROFILE_CHAR3:
if ( len == sizeof ( uint8 ) ) {
simpleProfileChar3 = *((uint8*)value);
}
else
{
ret = bleInvalidRange;
}
break;
case SIMPLEPROFILE_CHAR4:
if ( len == sizeof ( uint8 ) ) {
simpleProfileChar4 = *((uint8*)value);
// See if Notification has been enabled
GATTServApp_ProcessCharCfg( simpleProfileChar4Config, &simpleProfileChar4, FALSE,
simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
INVALID_TASK_ID );
}
else
{
ret = bleInvalidRange;
}
break;
case SIMPLEPROFILE_CHAR5:
if ( len == SIMPLEPROFILE_CHAR5_LEN ) {
VOID osal_memcpy( simpleProfileChar5, value, SIMPLEPROFILE_CHAR5_LEN );
}
else
{
ret = bleInvalidRange;
}
break;
case SIMPLEPROFILE_CHAR6:
//LCD_WRITE_STRING_VALUE( "SetParameter 6 len=", len, 10, HAL_LCD_LINE_1 );
if ( len == SIMPLEPROFILE_CHAR6_LEN )// if ( len <= SIMPLEPROFILE_CHAR6_LEN ) {
VOID osal_memcpy( simpleProfileChar6, value, len );
simpleProfileChar6Len = len;
// See if Notification has been enabled
GATTServApp_ProcessCharCfg( simpleProfileChar6Config, simpleProfileChar6, FALSE,
simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
INVALID_TASK_ID );
}
else
{
ret = bleInvalidRange;
}
break;
case SIMPLEPROFILE_CHAR7:
//LCD_WRITE_STRING_VALUE( "SetParameter 7 len=", len, 10, HAL_LCD_LINE_1 );
//if ( len == SIMPLEPROFILE_CHAR7_LEN ) if ( len <= SIMPLEPROFILE_CHAR7_LEN ) {
VOID osal_memcpy( simpleProfileChar7, value, len );
simpleProfileChar7Len = len;
// See if Notification has been enabled
GATTServApp_ProcessCharCfg( simpleProfileChar7Config, simpleProfileChar7, 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:
*((uint8*)value) = simpleProfileChar1;
break;
case SIMPLEPROFILE_CHAR2:
*((uint8*)value) = simpleProfileChar2;
break;
case SIMPLEPROFILE_CHAR3:
*((uint8*)value) = simpleProfileChar3;
break;
case SIMPLEPROFILE_CHAR4:
*((uint8*)value) = simpleProfileChar4;
break;
case SIMPLEPROFILE_CHAR5:
VOID osal_memcpy( value, simpleProfileChar5, SIMPLEPROFILE_CHAR5_LEN );
break; case SIMPLEPROFILE_CHAR6:
VOID osal_memcpy( value, simpleProfileChar6, simpleProfileChar6Len );
// *returnBytes = simpleProfileChar6Len;
break; case SIMPLEPROFILE_CHAR7:
VOID osal_memcpy( value, simpleProfileChar7, simpleProfileChar7Len );
// *returnBytes = simpleProfileChar7Len;
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 )
{
// No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
// gattserverapp handles those reads
// characteristics 1 and 2 have read permissions
// characteritisc 3 does not have read permissions; therefore it is not
// included here
// characteristic 4 does not have read permissions, but because it
// can be sent as a notification, it is included here
case SIMPLEPROFILE_CHAR1_UUID:
case SIMPLEPROFILE_CHAR2_UUID:
case SIMPLEPROFILE_CHAR4_UUID:
*pLen = 1;
pValue[0] = *pAttr->pValue;
break;
case SIMPLEPROFILE_CHAR5_UUID:
*pLen = SIMPLEPROFILE_CHAR5_LEN;
VOID osal_memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR5_LEN );
break;
case SIMPLEPROFILE_CHAR6_UUID:
//*Len = SIMPLEPROFILE_CHAR6_LEN;
//VOID osal_memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR6_LEN );
//LCD_WRITE_STRING_VALUE( "ReadAttrCB 6 len=", simpleProfileChar6Len, 10, HAL_LCD_LINE_1 );
*pLen = simpleProfileChar6Len;
VOID osal_memcpy( pValue, pAttr->pValue, simpleProfileChar6Len );
{
// 这个变量用于表明上一次写数据到从机已经成功, 可用于判断写数据时的判断, 以确保数据的完整性
//extern bool simpleBLEChar6DoWrite2;
//simpleBLEChar6DoWrite2 = TRUE;
}
break;
case SIMPLEPROFILE_CHAR7_UUID:
//*pLen = SIMPLEPROFILE_CHAR7_LEN;
//VOID osal_memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR7_LEN );
//LCD_WRITE_STRING_VALUE( "ReadAttrCB 7 len=", simpleProfileChar7Len, 10, HAL_LCD_LINE_1 );
*pLen = simpleProfileChar7Len;
VOID osal_memcpy( pValue, pAttr->pValue, simpleProfileChar7Len );
{
// 这个变量用于表明上一次写数据到从机已经成功, 可用于判断写数据时的判断, 以确保数据的完整性
//extern bool simpleBLEChar7DoWrite;
//simpleBLEChar7DoWrite = TRUE;
}
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
*
* @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:
case SIMPLEPROFILE_CHAR3_UUID:
//Validate the value
// Make sure it's not a blob oper
if ( offset == 0 )
{
if ( len != 1 )
{
status = ATT_ERR_INVALID_VALUE_SIZE;
}
}
else
{
status = ATT_ERR_ATTR_NOT_LONG;
}
//Write the value
if ( status == SUCCESS )
{
uint8 *pCurValue = (uint8 *)pAttr->pValue; *pCurValue = pValue[0];
if( pAttr->pValue == &simpleProfileChar1 )
{
notifyApp = SIMPLEPROFILE_CHAR1; }
else
{
notifyApp = SIMPLEPROFILE_CHAR3; }
}
break;
case SIMPLEPROFILE_CHAR6_UUID:
//Validate the value
// Make sure it's not a blob oper
//LCD_WRITE_STRING_VALUE( "WriteAttrCB 6 len=", len, 10, HAL_LCD_LINE_1 );
//LCD_WRITE_STRING_VALUE( "WriteAttrCB 6 len2=", simpleProfileChar6Len, 10, HAL_LCD_LINE_1 );
if ( offset == 0 )
{
if ( len != SIMPLEPROFILE_CHAR6_LEN )
//if ( len > SIMPLEPROFILE_CHAR6_LEN )
{
status = ATT_ERR_INVALID_VALUE_SIZE;
}
}
else
{
status = ATT_ERR_ATTR_NOT_LONG;
}
//Write the value
if ( status == SUCCESS )
{
//VOID osal_memcpy( pAttr->pValue, pValue, SIMPLEPROFILE_CHAR6_LEN );
VOID osal_memcpy( pAttr->pValue, pValue, len );
simpleProfileChar6Len = len;
notifyApp = SIMPLEPROFILE_CHAR6;
}
break;
case SIMPLEPROFILE_CHAR7_UUID:
//Validate the value
// Make sure it's not a blob oper
//LCD_WRITE_STRING_VALUE( "WriteAttrCB 7 len=", len, 10, HAL_LCD_LINE_1 );
//LCD_WRITE_STRING_VALUE( "WriteAttrCB 7 len2=", simpleProfileChar7Len, 10, HAL_LCD_LINE_1 );
if ( offset == 0 )
{
if ( len > SIMPLEPROFILE_CHAR7_LEN )
{
status = ATT_ERR_INVALID_VALUE_SIZE;
}
}
else
{
status = ATT_ERR_ATTR_NOT_LONG;
}
//Write the value
if ( status == SUCCESS )
{
//VOID osal_memcpy( pAttr->pValue, pValue, SIMPLEPROFILE_CHAR7_LEN );
VOID osal_memcpy( pAttr->pValue, pValue, len );
simpleProfileChar7Len = len;
notifyApp = SIMPLEPROFILE_CHAR7;
}
break;
case GATT_CLIENT_CHAR_CFG_UUID:
status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_NOTIFY );
/*
if ( pAttr->handle == simpleProfileAttrTbl[ATTRTBL_CHAR4_CCC_IDX].handle )//CHAR4 NOTIFY { // BloodPressure Notifications status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len, offset, GATT_CLIENT_CFG_NOTIFY ); } else if ( pAttr->handle == simpleProfileAttrTbl[ATTRTBL_CHAR6_CCC_IDX].handle )//CHAR6 NOTIFY { // BloodPressure Notifications status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len, offset, GATT_CLIENT_CFG_NOTIFY ); } else { status = ATT_ERR_INVALID_HANDLE; }
*/
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 ); }
return ( status );
}
/*********************************************************************
* @fn simpleProfile_HandleConnStatusCB
*
* @brief Simple Profile link status change handler function.
*
* @param connHandle – connection handle
* @param changeType – type of change
*
* @return none
*/
static void simpleProfile_HandleConnStatusCB( uint16 connHandle, uint8 changeType )
{ // Make sure this is not loopback connection
if ( connHandle != LOOPBACK_CONNHANDLE )
{
// Reset Client Char Config if connection has dropped
if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED ) ||
( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) && ( !linkDB_Up( connHandle ) ) ) )
{ GATTServApp_InitCharCfg( connHandle, simpleProfileChar4Config );
// GATTServApp_InitCharCfg( connHandle, simpleProfileChar6Config );
}
}
}
/*********************************************************************
*********************************************************************/
ming lu3:
上位机APP发送的数据是:0x7A 01 01 01 01 01 09 01 02 03 04 12 07 19 7A
kqian0327:
回复 ming lu3:
你好,
你可以把sniffer的数据抓出来,贴出来再看看是什么原因。