本篇博文最后修改时间:2016年12月29日,11:59。
一、简介
本文以SimpleBLEPeripheral工程为例,介绍如何用指令进行读取、修改配对密码。
二、实验平台
协议栈版本:BLE-CC254x-1.4.0
编译软件: IAR 8.20.2
硬件平台: Smart RF开发板(主芯片CC2541)
手机型号: 小米4S
安卓app:TruthBlue
三、版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn.NET/feilusia
联系方式:897503845@qq.com
香瓜BLE之CC2541群:127442605
香瓜BLE之CC2640群:557278427
四、实验前提
2、在进行本文步骤前,请先实现以下博文:
1)《CC2541之配对与绑定》:http://blog.csdn.net/feilusia/article/details/50212945香瓜的测试指令
1、功能码0x00(开关灯)
1)关灯
fe010000ffffffffffffffffffffffffffffffff
2)开灯
fe01000100ffffffffffffffffffffffffffffff
2、功能码0x01(读取密码)
fe0001ffffffffffffffffffffffffffffffffff
3、功能码0x02(修改密码)
1)修改密码为654321
fe0402f1fb0900f9ffffffffffffffffffffffff
2)修改密码为132648
fe04022806020034ffffffffffffffffffffffff
可自行对照上面的通信协议加强理解该指令。
七、实验步骤
1、修改通信协议的接收处理部分(替换GUA_RF_Communication.c)
//******************************************************************************
//name: GUA_RF_Communication.c
//introduce: 香瓜的通信协议
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group 香瓜BLE之CC2541(127442605)
//changetime: 2016.12.13
//******************************************************************************
#include "GUA_RF_Communication.h"
#include <string.h>
/*********************宏定义************************/
//通信协议的功能码
#define FUNC_GUA_LED_ON_OFF 0x00 //led开关的功能码
#define FUNC_GUA_READ_PASSWORD 0x01 //读取密码的功能码
#define FUNC_GUA_CHANGE_PASSWORD 0x02 //修改密码的功能码
//应用层事件(从应用层复制过来)
#define SBP_START_DEVICE_EVT 0x0001
#define SBP_PERIODIC_EVT 0x0002
#define SBP_GUA_RF_COMMUNICAION_PROCESS_EVT 0x0004 //通信处理事件
#define SBP_GUA_RF_COMMUNICAION_COMMAND_ERR_EVT 0x0008 //通信数据出错事件
#define SBP_GUA_TERMINATE_CONNECTION_EVT 0x0010 //从机主动断开事件
#define SBP_GUA_LED_ON_OFF_EVT 0x0040 //led开关事件
#define SBP_GUA_READ_PASSWORD_EVT 0x0080 //读取密码事件
#define SBP_GUA_CHANGE_PASSWORD_EVT 0x0100 //修改密码事件
//通信协议的数据包长度
#define GUA_DATA_PACKAGE_LEN 20 //20字节一包
//******************************************************************************
//name: GUA_RF_Communication_Judgment
//introduce: RF的通信数据判断
//parameter: npGUA_Receive: 接收缓冲区首地址
//return: true: 数据包正确
// false: 数据包错误
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group 香瓜BLE之CC2541(127442605)
//changetime: 2016.12.13
//******************************************************************************
GUA_U8 GUA_RF_Communication_Judgment(GUA_U8 *npGUA_Receive)
{
GUA_U8 nGUA_Sof = *npGUA_Receive;
GUA_U8 nGUA_Len = *(npGUA_Receive + 1);
GUA_U8 nGUA_Func = *(npGUA_Receive + 2);
GUA_U8 *npGUA_Data = npGUA_Receive + 3;
GUA_U8 nGUA_Crc = *(npGUA_Receive + 3 + nGUA_Len);
GUA_U8 nGUA_Crc_Count = 0;
//判断起始位正确性
if(nGUA_Sof != 0xFE)
{
return GUA_RF_COMMUNICATION_JUDGMENT_FALSE;
}
//接收数据长度
if(nGUA_Len > 16)
{
return GUA_RF_COMMUNICATION_JUDGMENT_FALSE;
}
//计算校验和
nGUA_Crc_Count += nGUA_Sof;
nGUA_Crc_Count += nGUA_Len;
nGUA_Crc_Count += nGUA_Func;
while(nGUA_Len--)
{
nGUA_Crc_Count += *(npGUA_Data + nGUA_Len);
}
//比较校验和
if(nGUA_Crc != nGUA_Crc_Count)
{
return GUA_RF_COMMUNICATION_JUDGMENT_FALSE;
}
//数据包正确
return GUA_RF_COMMUNICATION_JUDGMENT_TRUE;
}
extern void GUA_SimpleGATTprofile_Char6_Notify(GUA_U16 nGUA_ConnHandle, GUA_U8 *npGUA_Value, GUA_U8 nGUA_Len);
//******************************************************************************
//name: GUA_RF_Communication_DataPackage_Send
//introduce: RF的通信数据打包并发送(包头+有效数据长度+功能码+有效数据+补齐字节)
//parameter: nGUA_Func: 功能码
// npGUA_ValidData: 有效数据首地址
// nGUA_ValidData_Len: 要发送的数据
//return: none
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group 香瓜BLE之CC2541(127442605)
//changetime: 2016.12.13
//******************************************************************************
void GUA_RF_Communication_DataPackage_Send(GUA_U16 nGUA_ConnHandle, GUA_U8 nGUA_Func, GUA_U8 *npGUA_ValidData, GUA_U8 nGUA_ValidData_Len)
{
GUA_U8 nbGUA_DataPackage_Data[GUA_DATA_PACKAGE_LEN];
GUA_U8 nGUA_Num;
//初始化发送缓冲区
memset(nbGUA_DataPackage_Data, 0xFF, 20);
//填充数据
nbGUA_DataPackage_Data[0] = 0xFE; //包头
nbGUA_DataPackage_Data[1] = nGUA_ValidData_Len; //有效数据长度
nbGUA_DataPackage_Data[2] = nGUA_Func; //功能码
memcpy(nbGUA_DataPackage_Data + 3, npGUA_ValidData, nGUA_ValidData_Len); //有效数据
nbGUA_DataPackage_Data[3 + nGUA_ValidData_Len] = 0; //校验和清零
for(nGUA_Num = 0; nGUA_Num < (3 + nGUA_ValidData_Len); nGUA_Num++)
{
nbGUA_DataPackage_Data[3 + nGUA_ValidData_Len] += nbGUA_DataPackage_Data[nGUA_Num]; //校验和累加
}
//发送数据
GUA_SimpleGATTprofile_Char6_Notify(nGUA_ConnHandle, nbGUA_DataPackage_Data, GUA_DATA_PACKAGE_LEN);
}
//******************************************************************************
//name: GUA_RF_Communication_Process
//introduce: RF的通信数据处理
//parameter: npGUA_Receive: 接收缓冲区首地址
// nGUA_Event: 要启动的事件
//return: none
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group 香瓜BLE之CC2541(127442605)
//changetime: 2016.12.13
//******************************************************************************
void GUA_RF_Communication_Process(GUA_U8 *npGUA_Receive, GUA_U16 *npGUA_Event)
{
GUA_U8 nGUA_Func = *(npGUA_Receive + 2);
//判断功能码
switch(nGUA_Func)
{
//led开关的功能码
case FUNC_GUA_LED_ON_OFF:
{
*npGUA_Event = SBP_GUA_LED_ON_OFF_EVT;
break;
}
//读取密码的功能码
case FUNC_GUA_READ_PASSWORD:
{
*npGUA_Event = SBP_GUA_READ_PASSWORD_EVT;
break;
}
//修改密码的功能码
case FUNC_GUA_CHANGE_PASSWORD:
{
*npGUA_Event = SBP_GUA_CHANGE_PASSWORD_EVT;
break;
}
//功能码无效
default:
{
*npGUA_Event = SBP_GUA_RF_COMMUNICAION_COMMAND_ERR_EVT;
break;
}
}
}
2、添加“从机主动断开事件、读取密码事件、修改密码事件”
①定义“从机主动断开事件、读取密码事件、修改密码事件”(SimpleBLEPeripheral.c中)
//从机主动断开事件
if (events & SBP_GUA_TERMINATE_CONNECTION_EVT)
{
//断开连接
GAPRole_TerminateConnection();
return (events ^ SBP_GUA_TERMINATE_CONNECTION_EVT);
}
//功能码01 读取密码事件
if (events & SBP_GUA_READ_PASSWORD_EVT)
{
uint16 nGUA_ConnHandle;
uint8 nGUA_Func;
uint8 nbGUA_ValidData[16];
uint8 nGUA_ValidData_Len;
//获得连接句柄
GAPRole_GetParameter(GAPROLE_CONNHANDLE, &nGUA_ConnHandle);
//功能码填充
nGUA_Func = 0x01;
//有效数据填充
osal_memcpy(&nbGUA_ValidData[0], (uint8 *)(&gGUA_Password), sizeof(gGUA_Password));
//有效数据的长度
nGUA_ValidData_Len = sizeof(gGUA_Password);
//发送数据
GUA_RF_Communication_DataPackage_Send(nGUA_ConnHandle, nGUA_Func, nbGUA_ValidData, nGUA_ValidData_Len);
return (events ^ SBP_GUA_READ_PASSWORD_EVT);
}
//功能码02 修改密码事件
if ( events & SBP_GUA_CHANGE_PASSWORD_EVT )
{
uint16 nGUA_ConnHandle;
uint8 nGUA_Func;
uint8 nbGUA_ValidData[16];
uint8 nGUA_ValidData_Len;
uint8 nbGUA_Char6[SIMPLEPROFILE_CHAR6_LEN] = {0};
/*****************处理指令************************/
//读出RF接收到的数据到缓冲区
SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR6, nbGUA_Char6);
//将APP传来的密码保存起来
osal_memcpy((uint8 *)(&gGUA_Password), &nbGUA_Char6[3], sizeof(gGUA_Password));
GUA_SNV_Password(GUA_SNV_PASSWORD_WRITE, (uint8 *)(&gGUA_Password), sizeof(gGUA_Password));
//清除绑定信息
GAPBondMgr_SetParameter(GAPBOND_ERASE_ALLBONDS,0, NULL);
//设置1S后断开连接
osal_start_timerEx(simpleBLEPeripheral_TaskID, SBP_GUA_TERMINATE_CONNECTION_EVT, 1000);
/*****************应答************************/
//获得连接句柄
GAPRole_GetParameter(GAPROLE_CONNHANDLE, &nGUA_ConnHandle);
//功能码填充
nGUA_Func = 0x02;
//有效数据填充
osal_memcpy(&nbGUA_ValidData[0], (uint8 *)(&gGUA_Password), sizeof(gGUA_Password));
//有效数据的长度
nGUA_ValidData_Len = sizeof(gGUA_Password);
//发送数据
GUA_RF_Communication_DataPackage_Send(nGUA_ConnHandle, nGUA_Func, nbGUA_ValidData, nGUA_ValidData_Len);
return (events ^ SBP_GUA_CHANGE_PASSWORD_EVT);
}
其中,在修改密码1S之后,从机会主动断开连接。
②定义“从机主动断开事件、读取密码事件、修改密码事件”的宏(替换SimpleBLEPeripheral.h中原来的事件宏)
// Simple BLE Peripheral Task Events
#define SBP_START_DEVICE_EVT 0x0001
#define SBP_PERIODIC_EVT 0x0002
#define SBP_GUA_RF_COMMUNICAION_PROCESS_EVT 0x0004 //通信处理事件
#define SBP_GUA_RF_COMMUNICAION_COMMAND_ERR_EVT 0x0008 //通信数据出错事件
#define SBP_GUA_TERMINATE_CONNECTION_EVT 0x0010 //从机主动断开事件
#define SBP_GUA_LED_ON_OFF_EVT 0x0040 //led开关事件
#define SBP_GUA_READ_PASSWORD_EVT 0x0080 //读取密码事件
#define SBP_GUA_CHANGE_PASSWORD_EVT 0x0100 //修改密码事件
手机可能缓存了之前的代码(在更新过CC2541的代码之后,都需要清除手机端的缓存!!!),因此要清除缓存,清除缓存的方法如下:
方法一:关闭app、关闭蓝牙总开关、打开蓝牙总开关、打开app。
方法二:手机重启。
九、实验结果
3、再次连接
再次连接时又会弹窗要求输入密码需要输入密码,这时候输入的则是我们刚刚修改好的654321。
4、再次查询密码
因此,成功地通过指令将密码从123456修改为654321,实验成功。