/*BLE中的GAP和GATT GATT通俗理解为用于主从机之间的客户端和服务器端的数据交互,以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; } |
|