1、特征分析
控制led亮灭:通过对一个特征值写来实现; 获取led状态:通过对一个特征值读来实现。
2、控制led亮灭服务
要实现特征值的读写,必须要有服务,特征声明,特征值声明。
3、属性表定义
代码语言:javascript复制static gattAttribute_t ledAttrTbl[] =
{
// 服务,主要服务
{
{ ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
GATT_PERMIT_READ, /* permissions */
0, /* handle */
(uint8 *)&ledService /* pValue */
},
// 特征声明
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&ledProps
},
// 特征值声明
{
{ ATT_BT_UUID_SIZE, ledcharUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE, //可读可写
0,
ledchar
},
// 特征描述(非必须)
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
ledUserDesp
},
};
上述表中定义了服务、特征声明、特征值声明、特征用户描述(非必须);服务、特征声明、特征值声明、特征用户描述,分别都属于属性。
4、注册服务
代码语言:javascript复制bStatus_t Led_AddService( uint32 services )
{
uint8 status = SUCCESS;
if ( services & LED_SERVICE )
{
// Register GATT attribute list and CBs with GATT Server App
status = GATTServApp_RegisterService( ledAttrTbl,
GATT_NUM_ATTRS( ledAttrTbl ),
GATT_MAX_ENCRYPT_KEY_SIZE,
&simpleProfileCBs );
}
return ( status );
}
5、属性读回调
代码语言:javascript复制static bStatus_t led_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint16 *pLen, uint16 offset, uint16 maxLen,uint8 method )
{
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位UUID
{
// 16-bit UUID
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch ( uuid )//在属性表里,初始化的UUID
{
case LED_CHAR_UUID:
*pLen = LED_CHAR_LEN;
tmos_memcpy( pValue, pAttr->pValue, LED_CHAR_LEN );
printf("LED readrn");
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 );
}
6、属性写回调
代码语言:javascript复制static bStatus_t led_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint16 len, uint16 offset,uint8 method )
{
bStatus_t status = SUCCESS;
uint8 notifyApp = 0xFF;
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 LED_CHAR_UUID:
//Validate the value
// Make sure it's not a blob oper
if ( offset == 0 )
{
if ( len > LED_CHAR_LEN )
{
status = ATT_ERR_INVALID_VALUE_SIZE;
}
}
else
{
status = ATT_ERR_ATTR_NOT_LONG;
}
//Write the value
if ( status == SUCCESS )
{
tmos_memcpy( pAttr->pValue, pValue, LED_CHAR_LEN );
notifyApp = LED_CHAR;
}
printf("LED Writern");
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 ) && led_AppCBs && led_AppCBs->ledChange )
{
led_AppCBs->ledChange( notifyApp, pValue, len );
//数据传到应用层
}
return ( status );
}
7、应用层控制LED
在写回调中数据判断合法后会传递数据到应用层。
代码语言:javascript复制static void ledChangeCB( uint8 paramID, uint8 *pValue, uint16 len )
{
if(paramID==LED_CHAR)
{
if(len==1)
{
if(pValue[0])
{
GPIOB_SetBits(bPWM6);
PRINT("highrn");
}
else
{
GPIOB_ResetBits(bPWM6);
PRINT("lowrn");
}
}
}
}
8、APP控制LED
控制LED亮灭服务的UUID为ffe0,即就是上图中左边红框中的,属性值可读可写;右边是写,发送0x01,LED亮,发送0x00,LED灭。
说明:篇幅限制,文中只列出了部分代码。
——————END——————