<span style="font-size:18px;">如果有某个地方有更好的翻译,请留言(会采纳)</span>
/*BLE中的GAP和GATTGATT通俗理解为用于主从机之间的客户端和服务器端的数据交互,以Attribute Table来体现。
//*GATT层:是一个服务框架定义了对ATT应用的子程序。GATT指定了profile的结构。
//*在BLE中,由profile或者是服务所使用的所有类型的数据都称为characteristic。发生于两个设备间通过BLE连接进行交换的数据都需经过GATT子程序处理。因此,app和profile会直接使用GATT。
//*GAP:直接与profile和app进行接触,解决设备的发现和连接相关的服务,此外GAP也会初始化安全相关的特色。
//*GAP Role Profile:在GAP剧本里所处的4个角色:广播Advertise,主机central,从机Peripheral,观察者Observer。
//*ATT协议允许一个设备去显示一些数据,对于其他设备称之为“Attribute属性”,在ATT中,那些显示这些属性的设备被称为server,同等的另一个设备称为client。LL层的状态master和slave和ATT层的这两个状态无关。
*/
/*********************************************************************
* 包含
*/
#include "bcomdef.h"
#include "OSAL.h"
#include "OSAL_PwrMgr.h"
#include "OnBoard.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_lcd.h"
#include "gatt.h"
#include "ll.h"
#include "hci.h"
#include "gapgattserver.h"
#include "gattservapp.h"
#include "central.h"
#include "gapbondmgr.h"
#include "simpleGATTprofile.h"
#include "simpleBLECentral.h"
//包含串口程序
#include "SerialApp.h"
/*********************************************************************
* 宏定义
*/
// 蓝牙设备地址长度
#define B_ADDR_STR_LEN 15
/*********************************************************************
* 常量
*/
// 扫描从机最大值
#define DEFAULT_MAX_SCAN_RES 8
//扫描持续时间(ms)
#define DEFAULT_SCAN_DURATION 4000
// 发现模式 (有限制的, 常规, 全部)
#define DEFAULT_DISCOVERY_MODE DEVDISC_MODE_ALL
// 开启主动扫描
#define DEFAULT_DISCOVERY_ACTIVE_SCAN TRUE
// 关闭扫描白名单
#define DEFAULT_DISCOVERY_WHITE_LIST FALSE
// 连接时关闭高速扫描
#define DEFAULT_LINK_HIGH_DUTY_CYCLE FALSE
// 连接时关闭白名单功能
#define DEFAULT_LINK_WHITE_LIST FALSE
//轮询RSSI信号周期(MS)
#define DEFAULT_RSSI_PERIOD 1000
//当连接时是否允许自动升级
#define DEFAULT_ENABLE_UPDATE_REQUEST FALSE
// 如果自动启用参数更新请求,最小连接间隔(计算单位:每次1.25ms)
#define DEFAULT_UPDATE_MIN_CONN_INTERVAL 20
//最大连接时间间隔(units of 1.25ms) 如果启用了自动请求更新参数
#define DEFAULT_UPDATE_MAX_CONN_INTERVAL 20
// Slave latency to use if automatic parameter update request is enabled
#define DEFAULT_UPDATE_SLAVE_LATENCY 0
// 监督超时值(units of 10ms) 如果启用了自动请求更新参数
#define DEFAULT_UPDATE_CONN_TIMEOUT 600
// 默认密码
#define DEFAULT_PASSCODE 19655
// 定义GAP模式
#define DEFAULT_PAIRING_MODE GAPBOND_PAIRING_MODE_WAIT_FOR_REQ
// 定义配对模式 (是否开启配对时候需要配对码)
#define DEFAULT_MITM_MODE FALSE
// 定义是否绑定模式
#define DEFAULT_BONDING_MODE TRUE
// Default GAP bonding I/O capabilities
#define DEFAULT_IO_CAPABILITIES GAPBOND_IO_CAP_DISPLAY_ONLY
//定义搜索器延时(MS)
#define DEFAULT_SVC_DISCOVERY_DELAY 1000
//基于从机的UUID码,如果真就过滤搜索结果
#define DEFAULT_DEV_DISC_BY_SVC_UUID TRUE
//应用程序状态
enum
{
BLE_STATE_IDLE,
BLE_STATE_CONNECTING,
BLE_STATE_CONNECTED,
BLE_STATE_DISCONNECTING
};
// 发现设备状态
enum
{
BLE_DISC_STATE_IDLE, // 闲置的
BLE_DISC_STATE_SVC, // 服务发现
BLE_DISC_STATE_CHAR // 发现特有
};
/*********************************************************************
* 类型定义
*/
/*********************************************************************
* 全局变量
*/
/*********************************************************************
* 外部变量
*/
/*********************************************************************
* 外部函数
*/
/*********************************************************************
* 局部变量
*/
//内部的任务/ 事件处理的任务ID
static uint8 simpleBLETaskId;
// GAP GATT 属性(BLE名称)
static const uint8 simpleBLEDeviceName[GAP_DEVICE_NAME_LEN] = "Simple BLE Central";
// 扫描结果和扫描结果索引
static uint8 simpleBLEScanRes;
static uint8 simpleBLEScanIdx;
// 扫描结果列表
static gapDevRec_t simpleBLEDevList[DEFAULT_MAX_SCAN_RES];
// 扫描状态
static uint8 simpleBLEScanning = FALSE;
// RSSI polling state
static uint8 simpleBLERssi = FALSE;
// Connection handle of current connection
static uint16 simpleBLEConnHandle = GAP_CONNHANDLE_INIT;
// 应用状态
static uint8 simpleBLEState = BLE_STATE_IDLE;
//探索状态
static uint8 simpleBLEDiscState = BLE_DISC_STATE_IDLE;
//搜索开始与结束的句柄
static uint16 simpleBLESvcStartHdl = 0;
static uint16 simpleBLESvcEndHdl = 0;
//发现特有设备句柄
static uint16 simpleBLECharHdl = 0;
// Value to write写的值
static uint8 simpleBLECharVal = 0;
// 读取的值/写切换
static bool simpleBLEDoWrite = FALSE;
// GATT读/写程序状态
static bool simpleBLEProcedureInProgress = FALSE;
/*********************************************************************
* 局部函数
*/
static void simpleBLECentralProcessGATTMsg( gattMsgEvent_t *pMsg );
static void simpleBLECentralRssiCB( uint16 connHandle, int8 rssi );
static void simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent );
static void simpleBLECentralPasscodeCB( uint8 *deviceAddr, uint16 connectionHandle,
uint8 uiInputs, uint8 uiOutputs );
static void simpleBLECentralPairStateCB( uint16 connHandle, uint8 state, uint8 status );
static void simpleBLECentral_HandleKeys( uint8 shift, uint8 keys );
static void simpleBLECentral_ProcessOSALMsg( osal_event_hdr_t *pMsg );
static void simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg );
static void simpleBLECentralStartDiscovery( void );
static bool simpleBLEFindSvcUuid( uint16 uuid, uint8 *pData, uint8 dataLen );
static void simpleBLEAddDeviceInfo( uint8 *pAddr, uint8 addrType );
char *bdAddr2Str ( uint8 *pAddr );
/*********************************************************************
* 配置回调函数
*/
// GAP Role 回调函数
static const gapCentralRoleCB_t simpleBLERoleCB =
{
simpleBLECentralRssiCB, // RSSI信号回调
simpleBLECentralEventCB // 事件回调
};
// 绑定管理器的回调函数
static const gapBondCBs_t simpleBLEBondCB =
{
simpleBLECentralPasscodeCB,
simpleBLECentralPairStateCB
};
/*********************************************************************
* 公共函数
*/
/*********************************************************************
* 函数名: SimpleBLECentral_Init
*
* 描叙: 初始化BLE主机,在任务初始化时候,被调用。
*
* 参数: 任务ID
*
* 返回: 无
*/
void SimpleBLECentral_Init( uint8 task_id )
{
simpleBLETaskId = task_id;
//添加串口初始化,并传递任务id
SerialApp_Init(simpleBLETaskId);
SerialPrintString("SimpleBLECentral_SerialPrint Start init.\r\n");
//设置主机配置参数
{
uint8 scanRes = DEFAULT_MAX_SCAN_RES;
GAPCentralRole_SetParameter ( GAPCENTRALROLE_MAX_SCAN_RES, sizeof( uint8 ), &scanRes );
}
// 设置GAP
GAP_SetParamValue( TGAP_GEN_DISC_SCAN, DEFAULT_SCAN_DURATION );
GAP_SetParamValue( TGAP_LIM_DISC_SCAN, DEFAULT_SCAN_DURATION );
GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, (uint8 *) simpleBLEDeviceName );
//设置GAP的绑定管理器
{
uint32 passkey = DEFAULT_PASSCODE;
uint8 pairMode = DEFAULT_PAIRING_MODE;
uint8 mitm = DEFAULT_MITM_MODE;
uint8 ioCap = DEFAULT_IO_CAPABILITIES;
uint8 bonding = DEFAULT_BONDING_MODE;
GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof( uint32 ), &passkey );
GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof( uint8 ), &pairMode );
GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof( uint8 ), &mitm );
GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof( uint8 ), &ioCap );
GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof( uint8 ), &bonding );
}
// 初始化GATT客户端
VOID GATT_InitClient();
//登记接受到的ATT标志/通知
GATT_RegisterForInd( simpleBLETaskId );
//初始化GATT属性
GGS_AddService( GATT_ALL_SERVICES ); // GAP
GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes
// 注册所有按键事件- 这个应用会处理所有按键事件
RegisterForKeys( simpleBLETaskId );
//关闭所有LED
HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );
标志SBP_START_DEVICE_EVT启动对应ID事件
osal_set_event( simpleBLETaskId, START_DEVICE_EVT );
SerialPrintString("Ready to Starting\r\n");
}
/*********************************************************************
* 函数名称 SimpleBLECentral_ProcessEvent
*
* 描述 BLE事件处理函数. 调用该函数处理所有BLE事件( 时间, 消息,用户定义事件)
*
* 参数: 任务ID
* 参数: 事件 - 要处理的事件(可包含多个事件).
*
* 返回: 失败:返回未处理的事件
成功: 0
*/
uint16 SimpleBLECentral_ProcessEvent( uint8 task_id, uint16 events )
{
VOID task_id; // OSAL required parameter that isn't used in this function
if ( events & SYS_EVENT_MSG )
{
uint8 *pMsg;
if ( (pMsg = osal_msg_receive( simpleBLETaskId )) != NULL )
{
simpleBLECentral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
// 释放处理消息
VOID osal_msg_deallocate( pMsg );
}
// 返回未处理的事件
return (events ^ SYS_EVENT_MSG);
}
if ( events & START_DEVICE_EVT )
{
//启动设备
VOID GAPCentralRole_StartDevice( (gapCentralRoleCB_t *) &simpleBLERoleCB );
// 启动后,注册绑定管理器
GAPBondMgr_Register( (gapBondCBs_t *) &simpleBLEBondCB );
SerialPrintString("BLE Stack is running\r\n");
return ( events ^ START_DEVICE_EVT );
}
if ( events & START_DISCOVERY_EVT )
{
simpleBLECentralStartDiscovery( );
return ( events ^ START_DISCOVERY_EVT );
}
return 0;
}
/*********************************************************************
* 函数名称 simpleBLECentral_ProcessOSALMsg
*
* 描述: 处理传进来的事件消息
*
* 参数: pMsg - 要处理的消息
*
* @return 无
*/
static void simpleBLECentral_ProcessOSALMsg( osal_event_hdr_t *pMsg )
{
switch ( pMsg->event )
{
case KEY_CHANGE:
simpleBLECentral_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
break;
case GATT_MSG_EVENT:
simpleBLECentralProcessGATTMsg( (gattMsgEvent_t *) pMsg );
break;
}
}
/*********************************************************************
* 函数名称: simpleBLECentral_HandleKeys
*
* 描述: 处理所有按键事件
*
* 参数: shift - true if in shift/alt.
* 参数: keys - bit field for key events. Valid entries:
* HAL_KEY_SW_2
* HAL_KEY_SW_1
*
* 返回值: 无
*/
uint8 gStatus;
static void simpleBLECentral_HandleKeys( uint8 shift, uint8 keys )
{
(void)shift;
if ( keys & HAL_KEY_UP )
{
// Start or stop discovery
SerialPrintString(" [KEY UP pressed!]\r\n");
if ( simpleBLEState != BLE_STATE_CONNECTED )
{
if ( !simpleBLEScanning )
{
simpleBLEScanning = TRUE;
simpleBLEScanRes = 0;
LCD_WRITE_STRING( "Discovering...", HAL_LCD_LINE_1 );
SerialPrintString("Discovering...\r\n");
LCD_WRITE_STRING( "", HAL_LCD_LINE_2 );
GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE,
DEFAULT_DISCOVERY_ACTIVE_SCAN,
DEFAULT_DISCOVERY_WHITE_LIST );
}
else
{
GAPCentralRole_CancelDiscovery();
}
}
else if ( simpleBLEState == BLE_STATE_CONNECTED &&
simpleBLECharHdl != 0 &&
simpleBLEProcedureInProgress == FALSE )
{
uint8 status;
//做一个读或写,只要没有其他正在进行读/写程序
if ( simpleBLEDoWrite )
{
// 写
attWriteReq_t req;
req.handle = simpleBLECharHdl;
req.len = 1;
req.value[0] = simpleBLECharVal;
req.sig = 0;
req.cmd = 0;
status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );
}
else
{
// 读
attReadReq_t req;
req.handle = simpleBLECharHdl;
status = GATT_ReadCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );
}
if ( status == SUCCESS )
{
simpleBLEProcedureInProgress = TRUE;
simpleBLEDoWrite = !simpleBLEDoWrite;
}
}
}
if ( keys & HAL_KEY_LEFT )
{
SerialPrintString(" [KEY LEFT pressed!]\r\n");
//显示发现结果
if ( !simpleBLEScanning && simpleBLEScanRes > 0 )
{
//增加目前结果(with wraparound)
simpleBLEScanIdx++;
if ( simpleBLEScanIdx >= simpleBLEScanRes )
{
simpleBLEScanIdx = 0;
}
LCD_WRITE_STRING_VALUE( "Device", simpleBLEScanIdx + 1,
10, HAL_LCD_LINE_1 );
SerialPrintValue( "Device", simpleBLEScanIdx + 1, 10);
LCD_WRITE_STRING( bdAddr2Str( simpleBLEDevList[simpleBLEScanIdx].addr ),
HAL_LCD_LINE_2 );
SerialPrintString((uint8*) bdAddr2Str( simpleBLEDevList[simpleBLEScanIdx].addr ));SerialPrintString("\r\n");
}
}
if ( keys & HAL_KEY_RIGHT )
{
SerialPrintString(" [KEY RIGHT pressed!]\r\n");
//连接更新
if ( simpleBLEState == BLE_STATE_CONNECTED )
{
GAPCentralRole_UpdateLink( simpleBLEConnHandle,
DEFAULT_UPDATE_MIN_CONN_INTERVAL,
DEFAULT_UPDATE_MAX_CONN_INTERVAL,
DEFAULT_UPDATE_SLAVE_LATENCY,
DEFAULT_UPDATE_CONN_TIMEOUT );
}
}
if ( keys & HAL_KEY_CENTER )
{
uint8 addrType;
uint8 *peerAddr;
SerialPrintString(" [KEY CENTER pressed!]\r\n");
//连接或断开连接
if ( simpleBLEState == BLE_STATE_IDLE )
{
//如果有扫描的结果
if ( simpleBLEScanRes > 0 )
{
//连接到当前设备扫描结果
peerAddr = simpleBLEDevList[simpleBLEScanIdx].addr;
addrType = simpleBLEDevList[simpleBLEScanIdx].addrType;
simpleBLEState = BLE_STATE_CONNECTING;
GAPCentralRole_EstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE,
DEFAULT_LINK_WHITE_LIST,
addrType, peerAddr );
LCD_WRITE_STRING( "Connecting", HAL_LCD_LINE_1 );
SerialPrintString("Connecting:");
LCD_WRITE_STRING( bdAddr2Str( peerAddr ), HAL_LCD_LINE_2 );
SerialPrintString((uint8*)bdAddr2Str( peerAddr));SerialPrintString("\r\n");
}
}
else if ( simpleBLEState == BLE_STATE_CONNECTING ||
simpleBLEState == BLE_STATE_CONNECTED )
{
//断开
simpleBLEState = BLE_STATE_DISCONNECTING;
gStatus = GAPCentralRole_TerminateLink( simpleBLEConnHandle );
LCD_WRITE_STRING( "Disconnecting", HAL_LCD_LINE_1 );
SerialPrintString("Disconnecting\r\n");
}
}
if ( keys & HAL_KEY_DOWN )
{
SerialPrintString(" [KEY DOWN pressed!]\r\n");
// 开始/取消RSSI信号轮询
if ( simpleBLEState == BLE_STATE_CONNECTED )
{
if ( !simpleBLERssi )
{
simpleBLERssi = TRUE;
GAPCentralRole_StartRssi( simpleBLEConnHandle, DEFAULT_RSSI_PERIOD );
}
else
{
simpleBLERssi = FALSE;
GAPCentralRole_CancelRssi( simpleBLEConnHandle );
LCD_WRITE_STRING( "RSSI Cancelled", HAL_LCD_LINE_1 );
SerialPrintString("RSSI Cancelled\r\n");
}
}
}
}
/*********************************************************************
* 函数名称: simpleBLECentralProcessGATTMsg
*
* 描述: 处理GATT消息
*
* 返回值 无
*/
static void simpleBLECentralProcessGATTMsg( gattMsgEvent_t *pMsg )
{
if ( simpleBLEState != BLE_STATE_CONNECTED )
{
//掉线时候,万一有GATT消息到来
// 忽视该消息
return;
}
static int dataCount=0;
if ( pMsg->method == ATT_HANDLE_VALUE_NOTI ||
pMsg->method == ATT_HANDLE_VALUE_IND )
{
attHandleValueNoti_t noti;
dataCount = dataCount+ 1;
LCD_WRITE_STRING_VALUE( "Data Cnt: ", dataCount, 10, HAL_LCD_LINE_5 );
noti.handle = pMsg->msg.handleValueNoti.handle;
noti.len = pMsg->msg.handleValueNoti.len;
osal_memcpy(¬i.value, &pMsg->msg.handleValueNoti.value,noti.len);
// osal_memcpy(¬i.value, &pMsg->msg.handleValueNoti.value,pMsg->msg.handleValueNoti.len);
sbpSerialAppWrite(noti.value,noti.len);
}
if ( ( pMsg->method == ATT_READ_RSP ) ||
( ( pMsg->method == ATT_ERROR_RSP ) &&
( pMsg->msg.errorRsp.reqOpcode == ATT_READ_REQ ) ) )
{
if ( pMsg->method == ATT_ERROR_RSP )
{
uint8 status = pMsg->msg.errorRsp.errCode;
LCD_WRITE_STRING_VALUE( "Read Error", status, 10, HAL_LCD_LINE_1 );
SerialPrintValue("Read Error", status, 10);SerialPrintString("\r\n");
}
else
{
//成功读取后,显示读取值。
uint8 valueRead = pMsg->msg.readRsp.value[0];
LCD_WRITE_STRING_VALUE( "Read rsp:", valueRead, 10, HAL_LCD_LINE_1 );
SerialPrintValue("Read rsp:", valueRead, 10);SerialPrintString("\r\n");
}
simpleBLEProcedureInProgress = FALSE;
}
else if ( ( pMsg->method == ATT_WRITE_RSP ) ||
( ( pMsg->method == ATT_ERROR_RSP ) &&
( pMsg->msg.errorRsp.reqOpcode == ATT_WRITE_REQ ) ) )
{
if ( pMsg->method == ATT_ERROR_RSP == ATT_ERROR_RSP )
{
uint8 status = pMsg->msg.errorRsp.errCode;
LCD_WRITE_STRING_VALUE( "Write Error", status, 10, HAL_LCD_LINE_1 );
SerialPrintValue( "Write Error", status, 10);SerialPrintString("\r\n");
}
else
{
// After a succesful write, display the value that was written and increment value
uint8 temp=simpleBLECharVal;
//LCD_WRITE_STRING_VALUE( "Write sent:", simpleBLECharVal, 10, HAL_LCD_LINE_1 );
//SerialPrintValue( "Write sent:", temp, 10);SerialPrintString("\r\n");
}
simpleBLEProcedureInProgress = FALSE;
}
else if ( ( pMsg->method == ATT_PREPARE_WRITE_RSP ) || ( pMsg->method == ATT_EXECUTE_WRITE_RSP ) ||
( ( pMsg->method == ATT_ERROR_RSP ) &&
( pMsg->msg.errorRsp.reqOpcode == ATT_EXECUTE_WRITE_REQ ) ) )
{
static uint8 message_times = 0;
//LCD_WRITE_STRING_VALUE( "Message_Times", ++message_times, 10, HAL_LCD_LINE_2 );
//if ( pMsg->method == ATT_ERROR_RSP == ATT_ERROR_RSP )
if ( pMsg->method == ATT_ERROR_RSP)
{
uint8 status = pMsg->msg.errorRsp.errCode;
//LCD_WRITE_STRING_VALUE( "Write LC Error", status, 10, HAL_LCD_LINE_1 );
}
else if( pMsg->method == ATT_PREPARE_WRITE_RSP ) //bleTimeout status
{
//HalLcdWriteString("Write LC Tout!",HAL_LCD_LINE_1);
}
else
{
// After a succesful write, display the value that was written and increment value
//HalLcdWriteString("Write LC Success!",HAL_LCD_LINE_1);
//LCD_WRITE_STRING_VALUE( "Message_Times", ++message_times, 10, HAL_LCD_LINE_2 );
}
simpleBLEProcedureInProgress = FALSE; //重要
}
else if ( simpleBLEDiscState != BLE_DISC_STATE_IDLE )
{
simpleBLEGATTDiscoveryEvent( pMsg );
}
}
/*********************************************************************
* 函数名称 simpleBLECentralRssiCB
*
* 描述 RSSI信号回调函数
*
* 参数 connHandle - 连接句柄
* 参数 rssi - RSSI信号值
*
* 返回 无
*/
static void simpleBLECentralRssiCB( uint16 connHandle, int8 rssi )
{
LCD_WRITE_STRING_VALUE( "RSSI -dB:", (uint8) (-rssi), 10, HAL_LCD_LINE_1 );
SerialPrintValue("RSSI -dB:", (uint8) (-rssi), 10);SerialPrintString("\r\n");
}
/*********************************************************************
* 函数名称 simpleBLECentralEventCB
*
* 描述 主机事件回调函数
*
* 参数 pEvent - 事件结构指针
*
* 返回值 无
*/
static void simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent )
{
switch ( pEvent->gap.opcode )
{
case GAP_DEVICE_INIT_DONE_EVENT:
{
LCD_WRITE_STRING( "BLE Central", HAL_LCD_LINE_1 );
SerialPrintString("BLE Central: ");
LCD_WRITE_STRING( bdAddr2Str( pEvent->initDone.devAddr ), HAL_LCD_LINE_2 );
SerialPrintString((uint8*)bdAddr2Str( pEvent->initDone.devAddr ));SerialPrintString("\r\n");
}
break;
case GAP_DEVICE_INFO_EVENT:
{
//如果过滤器发现有搜索结果(基于服务UUID码)
if ( DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE )
{
if ( simpleBLEFindSvcUuid( SIMPLEPROFILE_SERV_UUID,
pEvent->deviceInfo.pEvtData,
pEvent->deviceInfo.dataLen ) )
{
simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType );
}
}
}
break;
case GAP_DEVICE_DISCOVERY_EVENT:
{
// 收索完成
simpleBLEScanning = FALSE;
// 如果过滤器没有发现搜索结果(基于服务UUID码)
if ( DEFAULT_DEV_DISC_BY_SVC_UUID == FALSE )
{
//复制结果
simpleBLEScanRes = pEvent->discCmpl.numDevs;
osal_memcpy( simpleBLEDevList, pEvent->discCmpl.pDevList,
(sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) );
}
LCD_WRITE_STRING_VALUE( "Devices Found", simpleBLEScanRes,
10, HAL_LCD_LINE_1 );
SerialPrintValue("Devices Found", simpleBLEScanRes,10);
SerialPrintString("\r\n");
if ( simpleBLEScanRes > 0 )
{
LCD_WRITE_STRING( "<- To Select", HAL_LCD_LINE_2 );
SerialPrintString("<- To Select\r\n");
}
//初始化索引扫描设备
simpleBLEScanIdx = simpleBLEScanRes;
}
break;
case GAP_LINK_ESTABLISHED_EVENT:
{
if ( pEvent->gap.hdr.status == SUCCESS )
{
simpleBLEState = BLE_STATE_CONNECTED;
simpleBLEConnHandle = pEvent->linkCmpl.connectionHandle;
simpleBLEProcedureInProgress = TRUE;
//如果搜索器没有初始化
if ( simpleBLECharHdl == 0 )
{
osal_start_timerEx( simpleBLETaskId, START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY );
}
LCD_WRITE_STRING( "Connected", HAL_LCD_LINE_1 );
SerialPrintString("Connected: ");
LCD_WRITE_STRING( bdAddr2Str( pEvent->linkCmpl.devAddr ), HAL_LCD_LINE_2 );
SerialPrintString((uint8*) bdAddr2Str( pEvent->linkCmpl.devAddr ));SerialPrintString("\r\n");
}
else
{
simpleBLEState = BLE_STATE_IDLE;
simpleBLEConnHandle = GAP_CONNHANDLE_INIT;
simpleBLERssi = FALSE;
simpleBLEDiscState = BLE_DISC_STATE_IDLE;
LCD_WRITE_STRING( "Connect Failed", HAL_LCD_LINE_1 );
SerialPrintString("Connect Failed: ");
LCD_WRITE_STRING_VALUE( "Reason:", pEvent->gap.hdr.status, 10, HAL_LCD_LINE_2 );
SerialPrintValue("Reason:", pEvent->gap.hdr.status,10);
}
}
break;
case GAP_LINK_TERMINATED_EVENT:
{
simpleBLEState = BLE_STATE_IDLE;
simpleBLEConnHandle = GAP_CONNHANDLE_INIT;
simpleBLERssi = FALSE;
simpleBLEDiscState = BLE_DISC_STATE_IDLE;
simpleBLECharHdl = 0;
simpleBLEProcedureInProgress = FALSE;
LCD_WRITE_STRING( "Disconnected", HAL_LCD_LINE_1 );
SerialPrintString("Disconnected: ");
LCD_WRITE_STRING_VALUE( "Reason:", pEvent->linkTerminate.reason,
10, HAL_LCD_LINE_2 );
SerialPrintValue("Reason:", pEvent->linkTerminate.reason,10);
}
break;
case GAP_LINK_PARAM_UPDATE_EVENT:
{
LCD_WRITE_STRING( "Param Update", HAL_LCD_LINE_1 );
SerialPrintString("Param Update\r\n");
}
break;
default:
break;
}
}
/*********************************************************************
* 函数名称 pairStateCB
*
* 参数 配对状态回调函数
*
* 返回值 无
*/
static void simpleBLECentralPairStateCB( uint16 connHandle, uint8 state, uint8 status )
{
if ( state == GAPBOND_PAIRING_STATE_STARTED )
{
LCD_WRITE_STRING( "Pairing started", HAL_LCD_LINE_1 );
}
else if ( state == GAPBOND_PAIRING_STATE_COMPLETE )
{
if ( status == SUCCESS )
{
LCD_WRITE_STRING( "Pairing success", HAL_LCD_LINE_1 );
}
else
{
LCD_WRITE_STRING_VALUE( "Pairing fail", status, 10, HAL_LCD_LINE_1 );
}
}
else if ( state == GAPBOND_PAIRING_STATE_BONDED )
{
if ( status == SUCCESS )
{
LCD_WRITE_STRING( "Bonding success", HAL_LCD_LINE_1 );
}
}
}
/*********************************************************************
* 函数名称 simpleBLECentralPasscodeCB
*
* 参数 密码回调函数
*
* 返回值 无
*/
static void simpleBLECentralPasscodeCB( uint8 *deviceAddr, uint16 connectionHandle,
uint8 uiInputs, uint8 uiOutputs )
{
#if (HAL_LCD == TRUE)
uint32 passcode;
uint8 str[7];
//创建随机密码
LL_Rand( ((uint8 *) &passcode), sizeof( uint32 ));
passcode %= 1000000;
//显示密码的用户
if ( uiOutputs != 0 )
{
LCD_WRITE_STRING( "Passcode:", HAL_LCD_LINE_1 );
LCD_WRITE_STRING( (char *) _ltoa(passcode, str, 10), HAL_LCD_LINE_2 );
}
//发送密码响应
GAPBondMgr_PasscodeRsp( connectionHandle, SUCCESS, passcode );
#endif
}
/*********************************************************************
* 函数名称 simpleBLECentralStartDiscovery
*
* 参数 开始搜索从设备.
*
* 返回值 无
*/
static void simpleBLECentralStartDiscovery( void )
{
uint8 uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(SIMPLEPROFILE_SERV_UUID),
HI_UINT16(SIMPLEPROFILE_SERV_UUID) };
//初始化缓存处理
simpleBLESvcStartHdl = simpleBLESvcEndHdl = simpleBLECharHdl = 0;
simpleBLEDiscState = BLE_DISC_STATE_SVC;
//发现BLE服务器
GATT_DiscPrimaryServiceByUUID( simpleBLEConnHandle,
uuid,
ATT_BT_UUID_SIZE,
simpleBLETaskId );
}
/*********************************************************************
* 函数名称 simpleBLEGATTDiscoveryEvent
*
* 描述 处理GATT收索事件
*
*返回值 无
*/
static void simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg )
{
attReadByTypeReq_t req;
if ( simpleBLEDiscState == BLE_DISC_STATE_SVC )
{
// 服务发现, 存储处理
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 ( ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&
pMsg->hdr.status == bleProcedureComplete ) ||
( pMsg->method == ATT_ERROR_RSP ) )
{
if ( simpleBLESvcStartHdl != 0 )
{
//发现特有设备
simpleBLEDiscState = 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 );
}
}
}
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 Found", HAL_LCD_LINE_1 );
SerialPrintString("Simple Svc Found\r\n");
simpleBLEProcedureInProgress = FALSE;
}
simpleBLEDiscState = BLE_DISC_STATE_IDLE;
}
}
/*********************************************************************
* 函数名称 simpleBLEFindSvcUuid
*
* 描述 在广播的从机UUID列表中,发现赋予特有的UUID设备
*
* 返回值 TRUE(成功发现)
*/
static bool simpleBLEFindSvcUuid( uint16 uuid, uint8 *pData, uint8 dataLen )
{
uint8 adLen;
uint8 adType;
uint8 *pEnd;
pEnd = pData + dataLen - 1;
//一直轮询到底部
while ( pData < pEnd )
{
//取得列表长度
adLen = *pData++;
if ( adLen > 0 )
{
adType = *pData;
// If AD type is for 16-bit service UUID
if ( adType == GAP_ADTYPE_16BIT_MORE || adType == GAP_ADTYPE_16BIT_COMPLETE )
{
pData++;
adLen--;
// 轮询每个UUID
while ( adLen >= 2 && pData < pEnd )
{
//检查匹配
if ( pData[0] == LO_UINT16(uuid) && pData[1] == HI_UINT16(uuid) )
{
// 发现配对设备
return TRUE;
}
// 进行下一项目
pData += 2;
adLen -= 2;
}
// 处理可能错误的额外字节UUID列表中
if ( adLen == 1 )
{
pData++;
}
}
else
{
//进行下一项目
pData += adLen;
}
}
}
//没有找到匹配
return FALSE;
}
/*********************************************************************
* 参数名称 simpleBLEAddDeviceInfo
*
* 描述 将设备添加到发现结果列表
*
* 返回值 无
*/
static void simpleBLEAddDeviceInfo( uint8 *pAddr, uint8 addrType )
{
uint8 i;
//如果结果数不是最大值
if ( simpleBLEScanRes < DEFAULT_MAX_SCAN_RES )
{
//检查设备是否已经在扫描结果
for ( i = 0; i < simpleBLEScanRes; i++ )
{
if ( osal_memcmp( pAddr, simpleBLEDevList[i].addr , B_ADDR_LEN ) )
{
return;
}
}
//添加地址到扫描结果列表
osal_memcpy( simpleBLEDevList[simpleBLEScanRes].addr, pAddr, B_ADDR_LEN );
simpleBLEDevList[simpleBLEScanRes].addrType = addrType;
//增量扫描结果统计
simpleBLEScanRes++;
}
}
/*********************************************************************
* 函数名称 bdAddr2Str
*
* 参数 蓝牙地址转换为字符串
*
* 返回值 无
*/
char *bdAddr2Str( uint8 *pAddr )
{
uint8 i;
char hex[] = "0123456789ABCDEF";
static char str[B_ADDR_STR_LEN];
char *pStr = str;
*pStr++ = '0';
*pStr++ = 'x';
//从地址尾部开始
pAddr += B_ADDR_LEN;
for ( i = B_ADDR_LEN; i > 0; i-- )
{
*pStr++ = hex[*--pAddr >> 4];
*pStr++ = hex[*pAddr & 0x0F];
}
*pStr = 0;
return str;
}
uint8 sbpGattWriteString(uint8 *pBuffer, uint16 length)
{
uint8 status;
uint8 len;
if(length > 20)
len = 20;
else
len = length;
attWriteReq_t req;
req.handle = simpleBLECharHdl;
req.len = len;
req.sig = 0;//必须要填
req.cmd = 0;//必须要填
osal_memcpy(req.value,pBuffer,len);
status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );
return status;
}
uint8 str2hex(uint8 *hex);
uint8 str2hex(uint8 *str)
{
uint8 hex[] = "0123456789ABCDEF";
uint8 i=0,h,l;
for(i=0;i<16;i++){
if(hex[i]==str[0])
h=i;
if(hex[i]==str[1])
l=i;
}
return (h*16+l);
}
uint8 str_cmp(uint8 *p1,uint8 *p2,uint8 len);
uint8 str_cmp(uint8 *p1,uint8 *p2,uint8 len)
{
uint8 i=0;
while(i<len){
if(p1[i]!=p2[i])
return 1;
i++;
}
return 0;
}