Files
BLV_C1F_Module/BasicCode/Drive/BLE/multiCentral.c
caocong 95916b9995 fix:修改UDP通讯中,取电变化上报机制
1、问题点:当RCU网络状态异常的情况下,网络还处于协商状态下,还未进入正常通讯环节时,取电变化不会进行判断。这会导致取电变化上报与实际产生取电状态时间点对不上。
2、将BLV_C1F_Module代码上传至Gitea,之前代码修改记录请查看 .\BasicCode\Readme.txt
2026-01-23 09:23:12 +08:00

1621 lines
56 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/********************************** (C) COPYRIGHT *******************************
* File Name : multiCentral.c
* Author : WCH
* Version : V1.0
* Date : 2018/11/12
* Description : 主机多连接例程,主动扫描周围设备,连接至给定的三个从机设备地址,
* 寻找自定义服务及特征,执行读写命令,需与从机例程配合使用,
并将从机设备地址修改为该例程目标地址,三个从机设备地址默认为
(84:C2:E4:03:02:02)、(84:C2:E4:03:02:03)、(84:C2:E4:03:02:04)
*******************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "CONFIG.h"
#include "CH57x_common.h"
#include "peripheral.h"
#include "multiCentral.h"
#include "string.h"
#include "stdlib.h"
#include "SPI_SRAM.h"
/*********************************************************************
* MACROS
*/
// Length of bd addr as a string
#define B_ADDR_STR_LEN 15
/*********************************************************************
* CONSTANTS
*/
// Maximum number of scan responses
//最大扫描响应数
#define DEFAULT_MAX_SCAN_RES 10
// Scan duration in 0.625ms
#define DEFAULT_SCAN_DURATION 2400
// Connection min interval in 1.25ms
#define DEFAULT_MIN_CONNECTION_INTERVAL 20
// Connection max interval in 1.25ms
#define DEFAULT_MAX_CONNECTION_INTERVAL 100
// Connection supervision timeout in 10ms
#define DEFAULT_CONNECTION_TIMEOUT 60
// Discovey mode (limited, general, all)
//发现模式(有限、通用、全部)
#define DEFAULT_DISCOVERY_MODE DEVDISC_MODE_ALL
// TRUE to use active scan
//如果TRUE将使用活动扫描
#define DEFAULT_DISCOVERY_ACTIVE_SCAN TRUE
// TRUE to use white list during discovery
//如果为TRUE将在发现期间使用白名单
#define DEFAULT_DISCOVERY_WHITE_LIST TRUE/*FALSE*/
// TRUE to use high scan duty cycle when creating link
//如果TRUE将在创建链接时使用高扫描占空比
#define DEFAULT_LINK_HIGH_DUTY_CYCLE FALSE
// TRUE to use white list when creating link
//如果TRUE将在创建链接时使用白名单
#define DEFAULT_LINK_WHITE_LIST FALSE
// Default read RSSI period in 0.625ms
#define DEFAULT_RSSI_PERIOD 3600
// Minimum connection interval (units of 1.25ms)
#define DEFAULT_UPDATE_MIN_CONN_INTERVAL 20
// Maximum connection interval (units of 1.25ms)
#define DEFAULT_UPDATE_MAX_CONN_INTERVAL 100
// Slave latency to use parameter update
#define DEFAULT_UPDATE_SLAVE_LATENCY 0
// Supervision timeout value (units of 10ms)
#define DEFAULT_UPDATE_CONN_TIMEOUT 600
// Default passcode
#define DEFAULT_PASSCODE 0
// Default GAP pairing mode
#define DEFAULT_PAIRING_MODE GAPBOND_PAIRING_MODE_WAIT_FOR_REQ
// Default MITM mode (TRUE to require passcode or OOB when pairing)
#define DEFAULT_MITM_MODE TRUE
// Default bonding mode, TRUE to bond, max bonding 6 devices
#define DEFAULT_BONDING_MODE TRUE
// Default GAP bonding I/O capabilities
#define DEFAULT_IO_CAPABILITIES GAPBOND_IO_CAP_NO_INPUT_NO_OUTPUT
// Default service discovery timer delay in 0.625ms
#define DEFAULT_SVC_DISCOVERY_DELAY /*1600*/1
// Default parameter update delay in 0.625ms
#define DEFAULT_PARAM_UPDATE_DELAY /*3200*/1000
// Default read or write timer delay in 0.625ms
#define DEFAULT_READ_OR_WRITE_DELAY /*100*/1
// Establish link timeout in 0.625ms
#define ESTABLISH_LINK_TIMEOUT /*3200*/1800
// Application states
enum
{
BLE_STATE_IDLE,
BLE_STATE_CONNECTING,
BLE_STATE_CONNECTED,
BLE_STATE_DISCONNECTING
};
// Discovery states
enum
{
BLE_DISC_STATE_IDLE, // Idle
BLE_DISC_STATE_SVC, // Service discovery
BLE_DISC_STATE_CHAR // Characteristic discovery
};
// Task ID for internal task/event processing
static uint8 centralTaskId;
// Number of scan results
static uint8 centralScanRes;
// Scan result list
static gapDevRec_t centralDevList[DEFAULT_MAX_SCAN_RES];
// Peer device address
//static peerAddrDefItem_t PeerAddrDef[PERIPHERAL_DEVICE_MAX_NUM] =
//{
// {0x02,0x02,0x03,0xE4,0xC2,0x84 },
// {0x03,0x02,0x03,0xE4,0xC2,0x84 },
// {0x04,0x02,0x03,0xE4,0xC2,0x84 }
//};
BLE_DEVICE_CONFIG* Ble_Device_Head = NULL;
// Connection item list
static centralConnItem_t centralConnList[CENTRAL_MAX_CONNECTION];
// Value to write
//static uint8 centralCharVal = 0x5A;
// Value read/write toggle
static uint8 centralDoWrite = TRUE;
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void centralProcessGATTMsg( gattMsgEvent_t *pMsg );
static void centralRssiCB( uint16 connHandle, int8 rssi );
static void centralEventCB( gapRoleEvent_t *pEvent );
static void centralHciMTUChangeCB( uint16 connHandle, uint16 maxTxOctets, uint16 maxRxOctets );
static void centralPasscodeCB( uint8 *deviceAddr, uint16 connectionHandle,
uint8 uiInputs, uint8 uiOutputs );
static void centralPairStateCB( uint16 connHandle, uint8 state, uint8 status );
static uint16 connect_ProcessEvent( uint8 connect_index, uint16 events );
static void central_ProcessTMOSMsg( tmos_event_hdr_t *pMsg );
static void centralGATTDiscoveryEvent( uint8 connItem, gattMsgEvent_t *pMsg );
static void centralConnIistStartDiscovery_0( void );
static void centralAddDeviceInfo( uint8 *pAddr, uint8 addrType );
static void centralInitConnItem( uint8 task_id, centralConnItem_t* centralConnList );
static uint8 centralAddrCmp( /*peerAddrDefItem_t *PeerAddrDef,*/ uint8 *addr );
/*********************************************************************
* PROFILE CALLBACKS
*/
// GAP Role Callbacks
static gapCentralRoleCB_t centralRoleCB =
{
centralRssiCB, // RSSI callback
centralEventCB, // Event callback 主机事件
centralHciMTUChangeCB // MTU change callback
};
// Bond Manager Callbacks
static gapBondCBs_t centralBondCB =
{
centralPasscodeCB, //密码回调
centralPairStateCB //配对状态回调
};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn Central_Init
*
* @brief Initialization function for the Central App Task.
* This is called during initialization and should contain
* any application specific initialization (ie. hardware
* initialization/setup, table initialization, power up
* notification).
*
* @param task_id - the ID assigned by TMOS. This ID should be
* used to send messages and set timers.
*
* @return none
*/
void Central_Init( )
{
centralTaskId = TMOS_ProcessEventRegister( Central_ProcessEvent );
// Setup GAP
//写 GAP 参数
GAP_SetParamValue( TGAP_DISC_SCAN, DEFAULT_SCAN_DURATION ); //执行扫描的最短时间 n*0.625ms 2400*0.625
GAP_SetParamValue( TGAP_DISC_SCAN_INT, 32); //在链路层扫描状态期间使用的扫描间隔,通常在发现过程中使用
GAP_SetParamValue(TGAP_DISC_SCAN_WIND, 32); //设置扫描窗口单位0.625ms扫描窗口要小于等于扫描间隔默认为16
GAP_SetParamValue( TGAP_CONN_EST_INT_MIN, DEFAULT_MIN_CONNECTION_INTERVAL ); //使用连接建立过程时的最小链路层连接间隔n*1.25毫秒2*1.25
GAP_SetParamValue( TGAP_CONN_EST_INT_MAX, DEFAULT_MAX_CONNECTION_INTERVAL ); //使用连接建立过程时的最大链路层连接间隔n*1.25毫秒10*1.25
GAP_SetParamValue( TGAP_CONN_EST_SUPERV_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT ); //使用连接建立过程时链路层连接监视超时n*10毫秒 10*10
// Setup the GAP Bond Manager
{
uint32 passkey = DEFAULT_PASSCODE; //默认密码 0
uint8 pairMode = DEFAULT_PAIRING_MODE; //默认配对模式 (等待配对请求或从属安全请求)
uint8 mitm = DEFAULT_MITM_MODE; //MITM启用状态 1
uint8 ioCap = DEFAULT_IO_CAPABILITIES; //I/O功能 :无显示或输入设备
uint8 bonding = DEFAULT_BONDING_MODE; //绑定设备,如果启用,请在配对过程中请求绑定
GAPBondMgr_SetParameter( GAPBOND_CENT_DEFAULT_PASSCODE, sizeof( uint32 ), &passkey );
GAPBondMgr_SetParameter( GAPBOND_CENT_PAIRING_MODE, sizeof( uint8 ), &pairMode );
GAPBondMgr_SetParameter( GAPBOND_CENT_MITM_PROTECTION, sizeof( uint8 ), &mitm );
GAPBondMgr_SetParameter( GAPBOND_CENT_IO_CAPABILITIES, sizeof( uint8 ), &ioCap );
GAPBondMgr_SetParameter( GAPBOND_CENT_BONDING_ENABLED, sizeof( uint8 ), &bonding );
}
// Init Connection Item
centralInitConnItem( centralTaskId, centralConnList );
// Initialize GATT Client
GATT_InitClient();
// Register to receive incoming ATT Indications/Notifications
//注册以接收传入的ATT指示/通知
GATT_RegisterForInd( centralTaskId );
// Setup a delayed profile startup
//设置一个延时工程启动
tmos_set_event( centralTaskId, START_DEVICE_EVT );
}
/*********************************************************************
* @fn centralInitConnItem
*
* @brief Init Connection Item
*
* @param task_id -
* centralConnList -
*
* @return NULL
*/
static void centralInitConnItem( uint8 task_id, centralConnItem_t* centralConnList )
{
uint8 connItem;
for(connItem=0; connItem<CENTRAL_MAX_CONNECTION; connItem++)
{
// 每个连接的任务通过taskID区分
centralConnList[connItem].taskID = TMOS_ProcessEventRegister( Central_ProcessEvent );
centralConnList[connItem].connHandle = GAP_CONNHANDLE_INIT;
centralConnList[connItem].state = BLE_STATE_IDLE;
centralConnList[connItem].discState = BLE_DISC_STATE_IDLE;
centralConnList[connItem].procedureInProgress = FALSE;
centralConnList[connItem].charHdl = 0;
centralConnList[connItem].svcStartHdl = 0;
centralConnList[connItem].svcEndHdl = 0;
memset(centralConnList[connItem].peerAddr, 0, 6);
}
}
/*********************************************************************
* @fn Central_ProcessEvent
*
* @brief Central Application Task event processor. This function
* is called to process all events for the task. Events
* include timers, messages and any other user defined events.
*
* @param task_id - The TMOS assigned task ID.
* @param events - events to process. This is a bit map and can
* contain more than one event.
*
* @return events not processed
*/
uint16 Central_ProcessEvent( uint8 task_id, uint16 events )
{
if ( events & SYS_EVENT_MSG )
{
uint8 *pMsg;
if ( (pMsg = tmos_msg_receive( centralTaskId )) != NULL )
{
central_ProcessTMOSMsg( (tmos_event_hdr_t *)pMsg );
// Release the TMOS message
tmos_msg_deallocate( pMsg );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if ( events & START_DEVICE_EVT )
{
// Start the Device
GAPRole_CentralStartDevice( centralTaskId, &centralBondCB, &centralRoleCB );
return ( events ^ START_DEVICE_EVT );
}
if ( events & ESTABLISH_LINK_TIMEOUT_EVT )
{
if(ble_send_info.wait_connected == 1) //已经发起连接
{
ble_send_info.wait_connected = 0; //等待连接标志清零
ble_send_info.send_state = BLE_ERR_CONNECT_FAIL; //状态,发起连接失败
}
PRINT("发起连接超时\n");
BLE_DEVICE_CONFIG* Device_Info_List = Ble_Device_Head; //此链表使用头插法
while(Device_Info_List)
{
Device_Info_List->connecting = CENTRAL_IDLE; //清除正在连接标志
Device_Info_List = Device_Info_List->next; //寻找下一个节点
}
GAPRole_TerminateLink( INVALID_CONNHANDLE ); //终止链接
//开启扫描
GAPRole_CentralStartDiscovery( DEFAULT_DISCOVERY_MODE, //发现模式:全部
DEFAULT_DISCOVERY_ACTIVE_SCAN, //使用活动扫描
DEFAULT_DISCOVERY_WHITE_LIST ); //在发现期间不使用白名单
return ( events ^ ESTABLISH_LINK_TIMEOUT_EVT );
}
// 连接0的任务处理
if(task_id == centralConnList[CONNECT0_ITEM].taskID )
{
return connect_ProcessEvent( CONNECT0_ITEM, events );
}
// 连接1的任务处理
else if(task_id == centralConnList[CONNECT1_ITEM].taskID )
{
return connect_ProcessEvent( CONNECT1_ITEM, events );
}
// 连接2的任务处理
else if(task_id == centralConnList[CONNECT2_ITEM].taskID )
{
}
// Discard unknown events
return 0;
}
/*********************************************************************
* @fn connect0_ProcessEvent
*
* @brief Process an incoming task message.
*
* @param pMsg - message to process
*
* @return none
*/
static uint16 connect_ProcessEvent( uint8 connect_index, uint16 events )
{
if ( events & START_SVC_DISCOVERY_EVT )
{
// start service discovery
//centralConnIistStartDiscovery_0( ); //发现服务
SRAM_Write_Byte(0x02, ble_send_info.BLE_SendAddr); //数据长度
SRAM_Write_Byte(0x01, ble_send_info.BLE_SendAddr+1); //打开通知
SRAM_Write_Byte(0x00, ble_send_info.BLE_SendAddr+2);
BLE_DEVICE_CONFIG* Device_Info_List = Ble_Device_Head; //此链表使用头插法
while(Device_Info_List)
{
if( memcmp(Device_Info_List->mac, centralConnList[connect_index].peerAddr, 6) == 0/*centralAddrCmp(centralConnList[connect_index].peerAddr)*/ )
{
if(Device_Info_List->uuid_type == UUID_TYPE_128BIT) //128BIT uuid
{
UINT8 uuid_128bit[16] = { 0x9E,0xCA,0xDC,0x24,0x0E,0x00,0x00,0x80,0x00,0x10,0x00,0x00,0xE0,0xFE,0x00,0x00 }; //128bit服务UUID
if(memcmp(Device_Info_List->uuid_128bit, uuid_128bit, 16) == 0)
{
ble_send_info.char_handle = 0x10; //通知特征的CCC句柄
}
break;
}
switch(Device_Info_List->server_uuid)
{
case SIMPLEPROFILE_SERV_UUID: //0xFFE0
ble_send_info.char_handle = 0x2D; //通知特征的CCC句柄
break;
default: break;
}
}
Device_Info_List = Device_Info_List->next; //寻找下一个节点
}
PRINT("通知句柄:%X\n", ble_send_info.char_handle);
ble_send_info.wait_send = 1; //等待发送
//PRINT("ble_send_info.char_handle:%X\n", ble_send_info.char_handle);
centralConnList[connect_index].procedureInProgress = FALSE;
tmos_start_task( centralConnList[connect_index].taskID, START_READ_OR_WRITE_EVT, 1);
return ( events ^ START_SVC_DISCOVERY_EVT );
}
if ( events & START_READ_OR_WRITE_EVT )
{
if( centralConnList[connect_index].procedureInProgress == FALSE )
{
if( centralDoWrite )
{
// Do a write
PRINT("BLE开始发送\n");
attWriteReq_t req;
req.cmd = FALSE;
req.sig = FALSE;
//req.handle = centralConnList[CONNECT0_ITEM].charHdl; //发送的特征uuid
req.handle = ble_send_info.char_handle; //发送的特征uuid
req.len = SRAM_Read_Byte(ble_send_info.BLE_SendAddr); //发送数据长度
req.pValue = GATT_bm_alloc(centralConnList[connect_index].connHandle, ATT_WRITE_REQ, req.len, NULL, 0);
if ( req.pValue != NULL )
{
SRAM_Read_Buff(req.pValue, req.len, ble_send_info.BLE_SendAddr+1);
if( GATT_WriteCharValue(centralConnList[connect_index].connHandle, &req, centralTaskId) == SUCCESS )
{
PRINT("BLE发送完成\n");
centralConnList[connect_index].procedureInProgress = TRUE;
//centralDoWrite = !centralDoWrite;
//tmos_start_task( centralConnList[CONNECT0_ITEM].taskID, START_READ_OR_WRITE_EVT, 100);
}
else
{
GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);
}
}
}
// else
// {
// // Do a read
// attReadReq_t req;
//
// req.handle = centralConnList[connect_index].charHdl;
// if( GATT_ReadCharValue( centralConnList[connect_index].connHandle, &req, centralTaskId ) == SUCCESS )
// {
// centralConnList[connect_index].procedureInProgress = TRUE;
// centralDoWrite = !centralDoWrite;
// }
// }
}
return ( events ^ START_READ_OR_WRITE_EVT );
}
if ( events & START_PARAM_UPDATE_EVT )
{
// start connect parameter update
GAPRole_UpdateLink( centralConnList[connect_index].connHandle,
DEFAULT_UPDATE_MIN_CONN_INTERVAL, //最小连接间隔单位1.25ms20
DEFAULT_UPDATE_MAX_CONN_INTERVAL, //最大连接间隔单位1.25ms100
DEFAULT_UPDATE_SLAVE_LATENCY, //使用参数更新的从属延迟 0
DEFAULT_UPDATE_CONN_TIMEOUT ); //监控超时值单位10ms 600
return ( events ^ START_PARAM_UPDATE_EVT );
}
if ( events & START_READ_RSSI_EVT )
{
tmos_start_task( centralConnList[connect_index].taskID, START_SVC_DISCOVERY_EVT, 3600);
GAPRole_ReadRssiCmd(centralConnList[connect_index].connHandle);
tmos_start_task( centralConnList[connect_index].taskID, START_READ_RSSI_EVT, DEFAULT_RSSI_PERIOD );
return (events ^ START_READ_RSSI_EVT);
}
// Discard unknown events
return 0;
}
/*********************************************************************
* @fn central_ProcessTMOSMsg
*
* @brief Process an incoming task message.
*
* @param pMsg - message to process
*
* @return none
*/
static void central_ProcessTMOSMsg( tmos_event_hdr_t *pMsg )
{
switch ( pMsg->event )
{
case GATT_MSG_EVENT:
centralProcessGATTMsg( (gattMsgEvent_t *) pMsg );
break;
}
}
/*********************************************************************
* @fn centralProcessGATTMsg
*
* @brief Process GATT messages
*
* @return none
*/
static void centralProcessGATTMsg( gattMsgEvent_t *pMsg )
{
uint8 connItem;
for(connItem=0; connItem<CENTRAL_MAX_CONNECTION; connItem++)
{
if( centralConnList[connItem].connHandle == pMsg->connHandle )
break;
}
if( connItem == CENTRAL_MAX_CONNECTION )
{
return;
// Should not go there
}
if ( centralConnList[connItem].state != BLE_STATE_CONNECTED )
{
// In case a GATT message came after a connection has dropped,
// ignore the message
//如果GATT消息是在一个连接断开之后发出的则忽略该消息
return;
}
if ( ( pMsg->method == ATT_EXCHANGE_MTU_RSP ) ||
( ( pMsg->method == ATT_ERROR_RSP ) &&
( pMsg->msg.errorRsp.reqOpcode == ATT_EXCHANGE_MTU_REQ ) ) )
{
if ( pMsg->method == ATT_ERROR_RSP )
{
uint8 status = pMsg->msg.errorRsp.errCode;
PRINT( "Exchange MTU Error: %x\n", status );
}
centralConnList[connItem].procedureInProgress = FALSE;
}
if ( pMsg->method == ATT_MTU_UPDATED_EVENT )
{
PRINT("MTU: %x\n",pMsg->msg.mtuEvt.MTU);
}
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;
PRINT( "Read Error: %x\n", status );
}
else
{
// After a successful read, display the read value
PRINT("Read rsp: %s\n", (char*)pMsg->msg.readRsp.pValue);
}
centralConnList[connItem].procedureInProgress = FALSE;
}
else if ( ( pMsg->method == ATT_WRITE_RSP ) ||
( ( pMsg->method == ATT_ERROR_RSP ) &&
( pMsg->msg.errorRsp.reqOpcode == ATT_WRITE_REQ ) ) )
{
PRINT( "Write pMsg->method:%X errorRsp.reqOpcode:%X\n", pMsg->method, pMsg->msg.errorRsp.reqOpcode);
if ( pMsg->method == ATT_ERROR_RSP )
{
uint8 status = pMsg->msg.errorRsp.errCode;
ble_send_info.send_state = BLE_ERR_FAIL;
PRINT( "Write Error: %x\n", status );
}
else
{
// After a succesful write, display the value that was written and increment value
PRINT( "Write sent: %d\n", SRAM_Read_Byte(ble_send_info.BLE_SendAddr));
for(int i = 0; i< SRAM_Read_Byte(ble_send_info.BLE_SendAddr) ; i++)
{
PRINT( "%02X ", SRAM_Read_Byte(ble_send_info.BLE_SendAddr+1+i));
}
PRINT("\n");
ble_send_info.send_state = BLE_ERR_SUCCESS;
}
centralConnList[connItem].procedureInProgress = FALSE;
ble_send_info.wait_send = 0; //等待发送标志清零
GPIOB_ResetBits(GPIO_Pin_6); //示波器测量口 连接建立完 拉低
}
else if ( pMsg->method == ATT_HANDLE_VALUE_NOTI ) //接收到通知
{
//PRINT("Receive noti: %s len:%d\n", (char*)pMsg->msg.handleValueNoti.pValue, pMsg->msg.handleValueNoti.len);
if(ble_send_info.BLE_WriteAddr != NULL && pMsg->msg.handleValueNoti.len <= BLE_BUFF_MAX_LEN)
{
PRINT( "接收通知Notify:");
for(int i= 0; i< pMsg->msg.handleValueNoti.len; i++)
{
PRINT( " %02X", pMsg->msg.handleValueNoti.pValue[i]);
}
PRINT( "\n");
SRAM_Write_Byte(pMsg->msg.handleValueNoti.len, ble_send_info.BLE_WriteAddr); //接收长度
SRAM_Write_Buff(pMsg->msg.handleValueNoti.pValue, pMsg->msg.handleValueNoti.len, ble_send_info.BLE_WriteAddr +1); //数据内容
ble_send_info.BLE_WriteAddr += BLE_BUFF_MAX_LEN;
if(ble_send_info.BLE_WriteAddr >= SRAM_BLE_RECEIVE_END)
{
ble_send_info.BLE_WriteAddr = SRAM_BLE_RECEIVE_START;
}
}
}
else if ( centralConnList[connItem].discState != BLE_DISC_STATE_IDLE )
{
//centralGATTDiscoveryEvent( connItem, pMsg );
}
GATT_bm_free(&pMsg->msg, pMsg->method);
}
/*********************************************************************
* @fn centralRssiCB
*
* @brief RSSI callback.
*
* @param connHandle - connection handle
* @param rssi - RSSI
*
* @return none
*/
static void centralRssiCB( uint16 connHandle, int8 rssi )
{
PRINT( "RSSI -%d dB Conn - %x \n", -rssi, connHandle);
}
/*********************************************************************
* @fn centralHciMTUChangeCB
*
* @brief MTU changed callback.
*
* @param maxTxOctets - Max tx octets
* @param maxRxOctets - Max rx octets
*
* @return none
*/
static void centralHciMTUChangeCB( uint16 connHandle, uint16 maxTxOctets, uint16 maxRxOctets )
{
}
/*********************************************************************
* @fn centralEventCB
*
* @brief Central event callback function.
*
* @param pEvent - pointer to event structure
*
* @return none
*/
static void centralEventCB( gapRoleEvent_t *pEvent )
{
switch ( pEvent->gap.opcode )
{
case GAP_DEVICE_INIT_DONE_EVENT: //在设备初始化完成时发送。此事件作为定义为gapdevicenitdoneevent的tmos消息发送
{
PRINT( "Scanning...\n" );
//开启扫描
GAPRole_CentralStartDiscovery( DEFAULT_DISCOVERY_MODE, //发现模式:全部
DEFAULT_DISCOVERY_ACTIVE_SCAN, //使用活动扫描
DEFAULT_DISCOVERY_WHITE_LIST ); //在发现期间不使用白名单
}
break;
case GAP_DEVICE_INFO_EVENT: //在发现设备时在设备发现过程中发送。此事件作为定义为gapDeviceInfoEvent\t的tmos消息发送
{
// Add device to list
// if(pEvent->deviceInfo.eventType == GAP_ADTYPE_ADV_NONCONN_IND)
// {
// char* data = (char*)malloc(pEvent->deviceInfo.dataLen);
// memcpy(data, pEvent->deviceInfo.pEvtData, pEvent->deviceInfo.dataLen);
// PRINT("advertData:%s\n", data);
// free(data);
// }
// PRINT("ADDR_TYPE:%d pEvent->deviceInfo.pEvtData: ", pEvent->deviceInfo.addrType);
// for(int i = 0; i < pEvent->deviceInfo.dataLen; i++)
// {
// PRINT("%02X ", pEvent->deviceInfo.pEvtData[i]);
// }
// PRINT("\n");
centralAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType );
}
break;
case GAP_DEVICE_DISCOVERY_EVENT: //在设备发现过程完成时发送。此事件作为定义为gapDevDiscEvent的tmos消息发送
{
uint8 i;
// PRINT("pEvent->deviceInfo.addr: %02x %02x %02x %02x %02x %02x \n",
// pEvent->deviceInfo.addr[0],
// pEvent->deviceInfo.addr[1],
// pEvent->deviceInfo.addr[2],
// pEvent->deviceInfo.addr[3],
// pEvent->deviceInfo.addr[4],
// pEvent->deviceInfo.addr[5]);
// See if peer device has been discovered
//查看是否已发现对等设备
for ( i = 0; i < centralScanRes; i++ )
{
if ( centralAddrCmp( /*PeerAddrDef,*/ centralDevList[i].addr ) )
break;
}
// Peer device not found
//未找到对等设备
if(i == centralScanRes)
{
PRINT( "Device not found...\n" );
centralScanRes = 0;
GAPRole_CentralStartDiscovery( DEFAULT_DISCOVERY_MODE, //继续扫描
DEFAULT_DISCOVERY_ACTIVE_SCAN,
DEFAULT_DISCOVERY_WHITE_LIST );
PRINT( "Scanning...\n" );
}
// Peer device found
//找到了对等设备
else
{
PRINT( "Device found...\n" );
int j = 0;
for( ; j < CENTRAL_MAX_CONNECTION; j++)
{
if( memcmp(centralDevList[i].addr, centralConnList[j].peerAddr, 6) == 0)
break;
}
if( j == CENTRAL_MAX_CONNECTION ) //设备未连接并且未发起连接
{
GPIOB_SetBits(GPIO_Pin_6); //发起连接拉高PB6示波器测量
Set_Connecting_flg(centralDevList[i].addr); //标记正在连接
PRINT("addrType:%d\n", centralDevList[i].addrType);
GAPRole_CentralEstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE, //建立链接 (不使用高扫描占空比、不使用白名单创建连接)
DEFAULT_LINK_WHITE_LIST,
centralDevList[i].addrType,
centralDevList[i].addr );
// Start establish link timeout event
//开始建立链接超时事件
tmos_start_task( centralTaskId, ESTABLISH_LINK_TIMEOUT_EVT, ESTABLISH_LINK_TIMEOUT);
PRINT( "Connecting...\n" );
}
// else
// {
// centralScanRes = 0;
// GAPRole_CentralStartDiscovery( DEFAULT_DISCOVERY_MODE, //继续扫描
// DEFAULT_DISCOVERY_ACTIVE_SCAN,
// DEFAULT_DISCOVERY_WHITE_LIST );
// PRINT( "Scanning...\n" );
// }
}
}
break;
case GAP_LINK_ESTABLISHED_EVENT: //当建立链接请求完成时发送。此事件将作为定义为gapEstLinkReqEvent\t的tmos消息发送
{
// GPIOB_ResetBits(GPIO_Pin_6); //示波器测量口 连接建立完 拉低
tmos_stop_task( centralTaskId, ESTABLISH_LINK_TIMEOUT_EVT ); //链接建立完成,超时任务停止
Clear_Connecting_flg(pEvent->linkCmpl.devAddr); //清除正在连接标记
if ( pEvent->gap.hdr.status == SUCCESS )
{
uint8 connItem;
// 查询是否有空余连接条目
for(connItem=0; connItem<CENTRAL_MAX_CONNECTION; connItem++)
{
if( centralConnList[connItem].connHandle == GAP_CONNHANDLE_INIT )
break;
}
if( connItem == CENTRAL_MAX_CONNECTION ) //连接数量已到最大值
{
GAPRole_TerminateLink(pEvent->linkCmpl.connectionHandle); //终止当前连接
memset(centralConnList[connItem].peerAddr, 0, 6); //清除连接设备MAC地址
PRINT( "Connection max...\n" );
}
else
{
centralConnList[connItem].state = BLE_STATE_CONNECTED; //状态更新:连接状态
centralConnList[connItem].connHandle = pEvent->linkCmpl.connectionHandle; //当前连接句柄更新
memcpy(centralConnList[connItem].peerAddr, pEvent->linkCmpl.devAddr, 6); //获取设备mac地址
PRINT("peerAddr: %02x %02x %02x %02x %02x %02x \n",
centralConnList[connItem].peerAddr[0],
centralConnList[connItem].peerAddr[1],
centralConnList[connItem].peerAddr[2],
centralConnList[connItem].peerAddr[3],
centralConnList[connItem].peerAddr[4],
centralConnList[connItem].peerAddr[5]);
printf("Conn %x - Int %x \n", pEvent->linkCmpl.connectionHandle, pEvent->linkCmpl.connInterval);
// 连接0
// if( connItem == CONNECT0_ITEM )
{
centralConnList[connItem].procedureInProgress = TRUE; //GATT 读写程序状态变为 TRUE
// Initiate service discovery
//启动服务发现
tmos_start_task( centralConnList[connItem].taskID, START_SVC_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY);
// Initiate connect parameter update
//启动连接参数更新
tmos_start_task( centralConnList[connItem].taskID, START_PARAM_UPDATE_EVT, DEFAULT_PARAM_UPDATE_DELAY);
// Start RSSI polling
//启动 RSSI 轮询
tmos_start_task( centralConnList[connItem].taskID, START_READ_RSSI_EVT, DEFAULT_RSSI_PERIOD );
}
// 连接1
// else if( connItem == CONNECT1_ITEM )
// {
// }
//
// // 连接2
// else if( connItem == CONNECT2_ITEM )
// {
// }
PRINT( "Connected...\n" );
// See if need discover again
//看看是否需要再次发现
// for(connItem=0; connItem<CENTRAL_MAX_CONNECTION; connItem++)
// {
// if( centralConnList[connItem].connHandle == GAP_CONNHANDLE_INIT )
// break;
// }
// if( connItem < CENTRAL_MAX_CONNECTION )
// {
// PRINT( "Scanning...\n" );
// centralScanRes = 0;
// GAPRole_CentralStartDiscovery( DEFAULT_DISCOVERY_MODE, //继续扫描
// DEFAULT_DISCOVERY_ACTIVE_SCAN,
// DEFAULT_DISCOVERY_WHITE_LIST );
// }
}
} //建立连接失败,重新扫描
else
{
PRINT( "Connect Failed...Reason:%X\n",pEvent->gap.hdr.status );
PRINT( "Scanning...\n" );
centralScanRes = 0;
GAPRole_CentralStartDiscovery( DEFAULT_DISCOVERY_MODE, //重新扫描
DEFAULT_DISCOVERY_ACTIVE_SCAN,
DEFAULT_DISCOVERY_WHITE_LIST );
}
}
break;
case GAP_LINK_TERMINATED_EVENT: //在连接终止时发送。此事件以tmos消息的形式发送该消息定义为gapTerminateLinkEvent
{
GPIOB_ResetBits(GPIO_Pin_6); //示波器测量口 连接断开拉低PB6
uint8 connItem;
for( connItem=0; connItem<CENTRAL_MAX_CONNECTION; connItem++ )
{
if( centralConnList[connItem].connHandle == pEvent->linkTerminate.connectionHandle )
break;
}
if( connItem == CENTRAL_MAX_CONNECTION )
{
// Should not go there
}
PRINT( " %x Disconnected...Reason:%x\n",centralConnList[connItem].connHandle,pEvent->linkTerminate.reason );
BLE_DEVICE_CONFIG* Device_Info_List = Ble_Device_Head; //此链表使用头插法
while(Device_Info_List)
{
if(memcmp(Device_Info_List->mac, centralConnList[connItem].peerAddr, 6) ==0)
{
GAPRole_CentralEstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE, //建立链接 (不使用高扫描占空比、不使用白名单创建连接)
DEFAULT_LINK_WHITE_LIST,
Device_Info_List->addr_type,
Device_Info_List->mac );
PRINT("连接断开,再次发起连接\n");
}
Device_Info_List = Device_Info_List->next;
}
centralConnList[connItem].state = BLE_STATE_IDLE;
centralConnList[connItem].connHandle = GAP_CONNHANDLE_INIT;
centralConnList[connItem].discState = BLE_DISC_STATE_IDLE;
centralConnList[connItem].charHdl = 0;
centralConnList[connItem].procedureInProgress = FALSE;
Clear_Connecting_flg(centralConnList[connItem].peerAddr); //清除正在连接标记
memset(centralConnList[connItem].peerAddr, 0, 6); //清除连接设备MAC地址
centralScanRes = 0;
tmos_stop_task( centralConnList[connItem].taskID, START_READ_RSSI_EVT ); //停止读取这个设备的RSSI值
// PRINT( "Scanning...\n" );
// GAPRole_CentralStartDiscovery( DEFAULT_DISCOVERY_MODE, ////重新扫描
// DEFAULT_DISCOVERY_ACTIVE_SCAN,
// DEFAULT_DISCOVERY_WHITE_LIST );
}
break;
case GAP_LINK_PARAM_UPDATE_EVENT: //在收到更新参数事件时发送。此事件作为定义为GaplingUpdateEvent的tmos消息发送
{
printf("Update %x - Int %x \n", pEvent->linkUpdate.connectionHandle, pEvent->linkUpdate.connInterval);
}
break;
default:
break;
}
}
/*********************************************************************
* @fn pairStateCB
*
* @brief Pairing state callback.
*
* @return none
*/
static void centralPairStateCB( uint16 connHandle, uint8 state, uint8 status )
{
if ( state == GAPBOND_PAIRING_STATE_STARTED ) //开始配对
{
PRINT( "Connection %04x - Pairing started:%d\n",connHandle, status);
}
else if ( state == GAPBOND_PAIRING_STATE_COMPLETE ) //配对完成
{
if ( status == SUCCESS )
{
PRINT( "Connection %04x - Pairing success\n",connHandle );
}
else
{
PRINT( "Connection %04x - Pairing fail\n",connHandle );
}
}
else if ( state == GAPBOND_PAIRING_STATE_BONDED ) //设备连接
{
if ( status == SUCCESS )
{
PRINT( "Connection %04x - Bonding success\n",connHandle );
}
}
else if (state == GAPBOND_PAIRING_STATE_BOND_SAVED) //连接记录保存到 NV flash
{
if (status == SUCCESS)
{
PRINT("Connection %04x - Bond save success\n",connHandle);
}
else
{
PRINT("Connection %04x - Bond save failed: %d\n",connHandle, status);
}
}
}
/*********************************************************************
* @fn centralPasscodeCB
*
* @brief Passcode callback.
*
* @return none
*/
static void centralPasscodeCB( uint8 *deviceAddr, uint16 connectionHandle,
uint8 uiInputs, uint8 uiOutputs )
{
uint32 passcode;
// Create random passcode
passcode = tmos_rand( );
passcode %= 1000000;
// Display passcode to user
if ( uiOutputs != 0 )
{
PRINT("Passcode:%d\n",(int)passcode);
}
// Send passcode response
GAPBondMgr_PasscodeRsp( connectionHandle, SUCCESS, passcode );
}
/*********************************************************************
* @fn centralConnIistStartDiscovery_0
*
* @brief Start connection 0 service discovery.
*
* @return none
*/
static void centralConnIistStartDiscovery_0( void )
{
uint8 uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(SIMPLEPROFILE_SERV_UUID),
HI_UINT16(SIMPLEPROFILE_SERV_UUID) };
// uint8 uuid[ATT_UUID_SIZE] = { 0xFB,
// 0x34,
// 0x9B,
// 0x5F,
// 0x80,
// 0x00,
// 0x00,
// 0x80,
// 0x00,
// 0x10,
// 0x00,
// 0x00,
// 0xE0,
// 0xFF,
// 0x00,
// 0x00,
// };
// Initialize cached handles
centralConnList[CONNECT0_ITEM].svcStartHdl = centralConnList[CONNECT0_ITEM].svcEndHdl = centralConnList[CONNECT0_ITEM].charHdl = 0;
centralConnList[CONNECT0_ITEM].discState = BLE_DISC_STATE_SVC;
// Discovery simple BLE service
GATT_DiscPrimaryServiceByUUID( centralConnList[CONNECT0_ITEM].connHandle,
uuid,
ATT_BT_UUID_SIZE,
centralTaskId );
}
/*********************************************************************
* @fn centralGATTDiscoveryEvent
*
* @brief Process GATT discovery event
*
* @return none
*/
static void centralGATTDiscoveryEvent( uint8 connItem, gattMsgEvent_t *pMsg )
{
attReadByTypeReq_t req;
// 连接0的枚举
if( connItem == CONNECT0_ITEM)
{
if ( centralConnList[connItem].discState == BLE_DISC_STATE_SVC )
{
// Service found, store handles
if ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&
pMsg->msg.findByTypeValueRsp.numInfo > 0 )
{
centralConnList[connItem].svcStartHdl = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo,0);
centralConnList[connItem].svcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo,0);
//GPIOB_SetBits(GPIO_Pin_6); //示波器测量口 服务发现完 拉高
// Display Profile Service handle range
PRINT("Found Profile Service handle : %x ~ %x \n",centralConnList[connItem].svcStartHdl,centralConnList[connItem].svcEndHdl);
}
// If procedure complete
if ( ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&
pMsg->hdr.status == bleProcedureComplete ) ||
( pMsg->method == ATT_ERROR_RSP ) )
{
if ( centralConnList[connItem].svcStartHdl != 0 )
{
// Discover characteristic
centralConnList[connItem].discState = BLE_DISC_STATE_CHAR;
req.startHandle = centralConnList[connItem].svcStartHdl;
req.endHandle = centralConnList[connItem].svcEndHdl;
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);
// req.type.uuid[0] = LO_UINT16(GATT_CLIENT_CHAR_CFG_UUID);
// req.type.uuid[1] = HI_UINT16(GATT_CLIENT_CHAR_CFG_UUID);
PRINT("开始发现特征\n");
GATT_ReadUsingCharUUID( centralConnList[connItem].connHandle, &req, centralTaskId );
}
}
}
else if ( centralConnList[connItem].discState == BLE_DISC_STATE_CHAR )
{
PRINT("pMsg->method:%d pMsg->msg.readByTypeRsp.numPairs:%d\n", pMsg->method, pMsg->msg.readByTypeRsp.numPairs);
// Characteristic found, store handle
if ( pMsg->method == ATT_READ_BY_TYPE_RSP &&
pMsg->msg.readByTypeRsp.numPairs > 0 )
{
centralConnList[connItem].charHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.pDataList[0],
pMsg->msg.readByTypeRsp.pDataList[1] );
centralConnList[connItem].procedureInProgress = FALSE;
// Start do read or write
//tmos_start_task( centralConnList[connItem].taskID, START_READ_OR_WRITE_EVT, DEFAULT_READ_OR_WRITE_DELAY);
// Display Characteristic 1 handle
PRINT("Found Characteristic 1 handle : %x \n",centralConnList[0].charHdl);
}
centralConnList[connItem].discState = BLE_DISC_STATE_IDLE;
//GPIOB_ResetBits(GPIO_Pin_6); //示波器测量口 //服务特征发现拉低PB6示波器测量
// ble_send_info.sendDATA[0] = 0x01;
// ble_send_info.sendDATA[1] = 0x00; //打开通知
// ble_send_info.sendLEN = 2;
// ble_send_info.char_handle = 0x2D; //通知特征的CCC句柄
// //PRINT("ble_send_info.char_handle:%X\n", ble_send_info.char_handle);
// tmos_start_task( centralConnList[connItem].taskID, START_READ_OR_WRITE_EVT, 243);
}
}
// 连接1的枚举
else if( connItem == CONNECT1_ITEM)
{
}
// 连接2的枚举
else if( connItem == CONNECT2_ITEM)
{
}
}
/*********************************************************************
* @fn centralAddDeviceInfo
*
* @brief Add a device to the device discovery result list
*
* @return none
*/
static void centralAddDeviceInfo( uint8 *pAddr, uint8 addrType )
{
uint8 i;
// If result count not at max
if ( centralScanRes < DEFAULT_MAX_SCAN_RES ) //小于最大扫描响应数
{
// Check if device is already in scan results
//检查设备是否已在扫描结果中
for ( i = 0; i < centralScanRes; i++ )
{
if ( tmos_memcmp( pAddr, centralDevList[i].addr , B_ADDR_LEN ) )
{
return;
}
}
// Add addr to scan result list
tmos_memcpy( centralDevList[centralScanRes].addr, pAddr, B_ADDR_LEN );
centralDevList[centralScanRes].addrType = addrType;
// Increment scan result count
centralScanRes++;
// Display device addr
PRINT("Device %d - Addr %02x %02x %02x %02x %02x %02x \n",centralScanRes,
centralDevList[centralScanRes-1].addr[0],
centralDevList[centralScanRes-1].addr[1],
centralDevList[centralScanRes-1].addr[2],
centralDevList[centralScanRes-1].addr[3],
centralDevList[centralScanRes-1].addr[4],
centralDevList[centralScanRes-1].addr[5]);
}
}
/*********************************************************************
* @fn centralAddrCmp
*
* @brief none
*
* @return none
*/
static uint8 centralAddrCmp(/* peerAddrDefItem_t *PeerAddrDef, */uint8 *addr )
{
// uint8 i;
// for(i=0; i<CENTRAL_MAX_CONNECTION; i++)
// {
// if ( tmos_memcmp( PeerAddrDef[i].peerAddr, addr , B_ADDR_LEN ) )
// break;
// }
// if( i == CENTRAL_MAX_CONNECTION )
// {
// return FALSE;
// }
// else
// {
// return TRUE;
// }
BLE_DEVICE_CONFIG* Device_Info_List = Ble_Device_Head; //此链表使用头插法
while(Device_Info_List)
{
if( tmos_memcmp( Device_Info_List->mac, addr , B_ADDR_LEN ) && Device_Info_List->connecting == CENTRAL_IDLE) //地址匹配且未发起连接
{
//PRINT("找到对应的mac地址\n");
return TRUE;
}
Device_Info_List = Device_Info_List->next; //寻找下一个节点
}
return FALSE;
}
void Device_Add_List(BLE_DEVICE_CONFIG* Device_node)
{
if(Device_node == NULL) return; //未分配内存,返回
// BLE_DEVICE_CONFIG* Device_Info_List = Ble_Device_Head; //头节点
// while(Device_Info_List) //遍历整张表,直到找到空的为止
// {
// if(Device_Info_List->device_type == Device_node->device_type && Device_Info_List->device_addr == Device_node->device_addr) return; //类型地址相同,不挂载
// Device_Info_List = Device_Info_List->next; //寻找下一个节点
// }
Device_node->next = Ble_Device_Head;
Ble_Device_Head = Device_node;
}
/************************************************
**函 数IS_Empty_Connection
**作 用:查询指定设备是否已连接
**参 数device_type: 设备类型, device_addr设备地址
**返回值0:未连接 ; 1:已连接 ; 4:设备不存在
**************************************************/
uint8 IS_Empty_Connection(u8 device_type, u8 device_addr)
{
BLE_DEVICE_CONFIG* Device_Info_List = Ble_Device_Head; //头节点
while(Device_Info_List)
{
if(Device_Info_List->device_type == device_type && Device_Info_List->device_addr == device_addr) //寻找对应的设备
{
int i = 0;
for( ; i < CENTRAL_MAX_CONNECTION; i++)
{
if( memcmp(Device_Info_List->mac, centralConnList[i].peerAddr, 6) == 0)
break;
}
if( i == CENTRAL_MAX_CONNECTION ) //设备未连接
return 0;
return 1;
}
Device_Info_List = Device_Info_List->next; //寻找下一个节点
}
return BLE_ERR_DEVICE_Not_EXIST; //设备不存在
}
/************************************************
**函 数Connect_Peripheral_Device
**作 用:与指定设备建立连接
**参 数device_type: 设备类型, device_addr设备地址
**返回值BLE_ERR_WAITING_CONNECT:正在连接 ; BLE_ERR_DEVICE_Not_EXIST:设备不存在 ; BLE_ERR_INVALID:操作无效(已经连接)
**************************************************/
uint8 Connect_Peripheral_Device(u8 device_type, u8 device_addr)
{
BLE_DEVICE_CONFIG* Device_Info_List = Ble_Device_Head; //头节点
while(Device_Info_List)
{
if(Device_Info_List->device_type == device_type && Device_Info_List->device_addr == device_addr) //寻找对应的设备
{
int i = 0;
for( ; i < CENTRAL_MAX_CONNECTION; i++)
{
if( memcmp(Device_Info_List->mac, centralConnList[i].peerAddr, 6) == 0)
break;
}
if( i == CENTRAL_MAX_CONNECTION ) //设备未连接
{
if ( centralScanRes < DEFAULT_MAX_SCAN_RES ) //小于最大扫描响应数
{
// Check if device is already in scan results
//检查设备是否已在扫描结果中
int j = 0;
for ( ; j < centralScanRes; j++ )
{
if ( tmos_memcmp( Device_Info_List->mac, centralDevList[j].addr , B_ADDR_LEN ) )
{
break;
}
}
if(j == centralScanRes) //扫描设备列表没有找到该设备
{
return BLE_ERR_DEVICE_Not_EXIST;
}
else //
{
GAPRole_CentralEstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE, //建立链接 (不使用高扫描占空比、不使用白名单创建连接)
DEFAULT_LINK_WHITE_LIST,
centralDevList[j].addrType,
centralDevList[j].addr );
// Start establish link timeout event
//开始建立链接超时事件
tmos_start_task( centralTaskId, ESTABLISH_LINK_TIMEOUT_EVT, ESTABLISH_LINK_TIMEOUT);
PRINT( "Connecting...\n" );
return BLE_ERR_WAITING_CONNECT; //状态,正在连接
}
}
}
else //已经连接
{
return BLE_ERR_INVALID; //操作无效
}
}
Device_Info_List = Device_Info_List->next; //寻找下一个节点
}
return BLE_ERR_DEVICE_Not_EXIST;
}
/************************************************
**函 数Disconnect_Peripheral_Device
**作 用:断开与指定设备的连接
**参 数device_type: 设备类型, device_addr设备地址
**返回值:
**************************************************/
uint8 Disconnect_Peripheral_Device(u8 device_type, u8 device_addr)
{
BLE_DEVICE_CONFIG* Device_Info_List = Ble_Device_Head; //头节点
while(Device_Info_List)
{
if(Device_Info_List->device_type == device_type && Device_Info_List->device_addr == device_addr) //寻找对应的设备
{
int i = 0;
for( ; i < CENTRAL_MAX_CONNECTION; i++)
{
if( memcmp(Device_Info_List->mac, centralConnList[i].peerAddr, 6) == 0)
break;
}
if( i == CENTRAL_MAX_CONNECTION ) //设备未连接
{
return BLE_ERR_INVALID; //操作无效
}
else //已经连接
{
GAPRole_TerminateLink(centralConnList[i].connHandle); //终止该连接
return BLE_ERR_SUCCESS; //操作成功
}
}
Device_Info_List = Device_Info_List->next; //寻找下一个节点
}
return BLE_ERR_DEVICE_Not_EXIST;
}
/************************************************
**函 数Peripheral_Notify_Control
**作 用打开或关闭指定连接的·从机NOTIFY
**参 数device_type: 设备类型, device_addr设备地址state :0 关闭 1 打开 ,notify_id: 通知特征编号只有一个填0
**返回值:无
**************************************************/
void Peripheral_Notify_Control(u8 device_type, u8 device_addr, u8 notify_id, u8 state)
{
if(state != 0)
{
SRAM_Write_Byte(0x01, ble_send_info.BLE_SendAddr+1); //打开通知
}
else SRAM_Write_Byte(0x00, ble_send_info.BLE_SendAddr+1); //关闭通知
SRAM_Write_Byte(0x01, ble_send_info.BLE_SendAddr+2);
SRAM_Write_Byte(2, ble_send_info.BLE_SendAddr); //发送长度
ble_send_info.device_type = device_type; //设备类型
ble_send_info.device_addr = device_addr; //设备地址
ble_send_info.data_type = BLE_DATA_TYPE_CMD; //数据类型:命令
ble_send_info.ble_type = BLE_TYPE_PERIPHERAL; //目标蓝牙类型:从机
ble_send_info.notify_id = notify_id; //特征id
ble_send_info.send_flg = 1;
}
void Set_Connecting_flg(u8* addr)
{
BLE_DEVICE_CONFIG* Device_Info_List = Ble_Device_Head; //此链表使用头插法
while(Device_Info_List)
{
if( tmos_memcmp( Device_Info_List->mac, addr, B_ADDR_LEN )) //地址匹配
{
//PRINT("找到对应的mac地址\n");
Device_Info_List->connecting = CENTRAL_CONNECTING; //正在连接标志
}
Device_Info_List = Device_Info_List->next; //寻找下一个节点
}
}
void Clear_Connecting_flg(u8* addr)
{
BLE_DEVICE_CONFIG* Device_Info_List = Ble_Device_Head; //此链表使用头插法
while(Device_Info_List)
{
if( tmos_memcmp( Device_Info_List->mac, addr, B_ADDR_LEN )) //地址匹配
{
//PRINT("找到对应的mac地址\n");
Device_Info_List->connecting = CENTRAL_IDLE; //清除正在连接标志
}
Device_Info_List = Device_Info_List->next; //寻找下一个节点
}
}
/************************************************
**函 数BLE_Send_Task
**作 用:蓝牙数据发送任务函数
**参 数:无
**返回值:无
**************************************************/
void BLE_Send_Task()
{
uint8_t len = SRAM_Read_Byte(ble_send_info.BLE_SendAddr);
if(ble_send_info.send_flg == 1 && len > 0 && len <= BLE_BUFF_MAX_LEN)
{
if(ble_send_info.ble_type == BLE_TYPE_CENTRAL) //目标BLE设备为主机
{
// if(peripheralConnList.connHandle != GAP_CONNHANDLE_INIT) //当前有主机设备连接
{
uint8* data = malloc(len);
if(data == NULL) return;
SRAM_Read_Buff(data, len, ble_send_info.BLE_SendAddr +1); //数据内容
// peripheralChar4Notify(data, len); //发给主机的数据固定使用 特征4的NOTIFY
free(data);
ble_send_info.send_state = BLE_ERR_SUCCESS; //发送成功
}
// else
{
ble_send_info.send_state = BLE_ERR_DEVICE_Not_EXIST; //设备不存在
}
// ble_send_info.send_flg = 0;
}
else //目标BLE设备为从机
{
BLE_DEVICE_CONFIG* Device_Info_List = Ble_Device_Head; //此链表使用头插法
while(Device_Info_List)
{
if(Device_Info_List->device_type == ble_send_info.device_type && Device_Info_List->device_addr == ble_send_info.device_addr) //寻找对应的设备
{
// 查询该设备是否已经连接
int i = 0;
for( ; i < CENTRAL_MAX_CONNECTION; i++)
{
if( memcmp(Device_Info_List->mac, centralConnList[i].peerAddr, 6) == 0)
break;
}
if( i == CENTRAL_MAX_CONNECTION ) //设备未连接
{
// if ( centralScanRes < DEFAULT_MAX_SCAN_RES ) //小于最大扫描响应数
{
// Check if device is already in scan results
//检查设备是否已在扫描结果中
// int j = 0;
// for ( ; j < centralScanRes; j++ )
// {
// if ( tmos_memcmp( Device_Info_List->mac, centralDevList[j].addr , B_ADDR_LEN ) )
// {
// break;
// }
// }
// if(j == centralScanRes) //扫描设备列表没有找到该设备
// {
// ble_send_info.send_state = BLE_ERR_DEVICE_Not_EXIST; //设备不存在
// ble_send_info.send_flg = 0;
// }
// else //
{
if(ble_send_info.wait_connected == 1) //已经发起连接
{
// ble_send_info.wait_count++; //开始计数
//
// if(ble_send_info.wait_count < 1000)
// {
// return;
// }
// else //发起连接,超时
// {
// ble_send_info.wait_count = 0;
// ble_send_info.wait_connected = 0; //等待连接标志清零
// ble_send_info.send_flg = 0; //清除发送标志
// ble_send_info.send_state = BLE_ERR_CONNECT_FAIL; //状态,发起连接失败
// }
}
else
{
// GAPRole_CentralEstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE, //建立链接 (不使用高扫描占空比、不使用白名单创建连接)
// DEFAULT_LINK_WHITE_LIST,
// centralDevList[j].addrType,
// centralDevList[j].addr );
GAPRole_CentralEstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE, //建立链接 (不使用高扫描占空比、不使用白名单创建连接)
DEFAULT_LINK_WHITE_LIST,
Device_Info_List->addr_type,
Device_Info_List->mac );
Set_Connecting_flg(Device_Info_List->mac); //标记正在连接
// Start establish link timeout event
//开始建立链接超时事件
tmos_start_task( centralTaskId, ESTABLISH_LINK_TIMEOUT_EVT, ESTABLISH_LINK_TIMEOUT);
ble_send_info.send_state = BLE_ERR_WAITING_CONNECT; //状态,正在连接
ble_send_info.send_flg = 0; //清除发送标志
ble_send_info.wait_connected = 1; //标记等待连接
PRINT( "Connecting...\n" );
}
}
}
}
else //设备已经连接
{
ble_send_info.wait_connected = 0; //等待连接标志清零
ble_send_info.wait_count = 0; //等待计数清零
if(ble_send_info.wait_send == 1) //还未发送完
{
break;
}
else
{
// attWriteReq_t req;
// req.cmd = FALSE;
// req.sig = FALSE;
// req.handle = centralConnList[i].charHdl; //发送的特征uuid
// //req.handle = ble_send_info.char_uuid; //发送的特征uuid
// req.len = ble_send_info.sendLEN; //发送数据长度
// req.pValue = GATT_bm_alloc(centralConnList[i].connHandle, ATT_WRITE_REQ, req.len, NULL, 0);
// if ( req.pValue != NULL )
// {
// memcpy(req.pValue, ble_send_info.sendDATA, ble_send_info.sendLEN); //需要发送的数据
//
// if( GATT_WriteCharValue(centralConnList[i].connHandle, &req, /*centralTaskId*/centralConnList[i].taskID) == SUCCESS ) //发送完成
// {
//// centralConnList[i].procedureInProgress = TRUE;
//// tmos_start_task( centralConnList[CONNECT0_ITEM].taskID, START_READ_OR_WRITE_EVT, DEFAULT_READ_OR_WRITE_DELAY);
// ble_send_info.send_state = BLE_ERR_SUCCESS; //发送成功
// ble_send_info.send_flg = 0;
// }
// else
// {
// ble_send_info.send_state = BLE_ERR_SEND_FAIL; //发送失败
// ble_send_info.send_flg = 0;
// GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);
// }
// }
PRINT( "开始发送任务%d\n", i);
centralConnList[i].procedureInProgress = FALSE;
if(ble_send_info.data_type == BLE_DATA_TYPE_CMD) //命令
{
if(Device_Info_List->uuid_type == UUID_TYPE_128BIT) //128bit
{
UINT8 uuid_128bit[16] = { 0x9E,0xCA,0xDC,0x24,0x0E,0x00,0x00,0x80,0x00,0x10,0x00,0x00,0xE0,0xFE,0x00,0x00 }; //128bit服务UUID
if(memcmp(Device_Info_List->uuid_128bit, uuid_128bit, 16) == 0)
{
switch(ble_send_info.notify_id)
{
case 0: ble_send_info.char_handle = 0x10; //通知特征1的CCC句柄
break;
case 1: ble_send_info.char_handle = 0x15; //通知特征2的CCC句柄
break;
default: break;
}
}
PRINT("打开通知0x%X\n", ble_send_info.char_handle);
}
else
{
switch(Device_Info_List->server_uuid)
{
case SIMPLEPROFILE_SERV_UUID: //0xFFE0
switch(ble_send_info.notify_id)
{
case 0: ble_send_info.char_handle = 0x2d; //通知特征CCC句柄
break;
case 1:
break;
default: break;
}
break;
default: break;
}
}
}
else //数据
{
if(Device_Info_List->uuid_type == UUID_TYPE_128BIT) //128bit
{
UINT8 uuid_128bit[16] = { 0x9E,0xCA,0xDC,0x24,0x0E,0x00,0x00,0x80,0x00,0x10,0x00,0x00,0xE0,0xFE,0x00,0x00 }; //128bit服务UUID
if(memcmp(Device_Info_List->uuid_128bit, uuid_128bit, 16) == 0)
{
ble_send_info.char_handle = 0x0D; //写特征1句柄
}
}
else
{
switch(Device_Info_List->server_uuid)
{
case SIMPLEPROFILE_SERV_UUID: //0xFFE0
ble_send_info.char_handle = 0x23; //写特征句柄
break;
default: break;
}
}
}
tmos_start_task( centralConnList[i].taskID, START_READ_OR_WRITE_EVT, DEFAULT_READ_OR_WRITE_DELAY);
ble_send_info.send_state = BLE_ERR_WAITING_SEND; //状态,正在发送
ble_send_info.wait_send = 1; //等待发送
}
}
break;
}
Device_Info_List = Device_Info_List->next; //寻找下一个节点
}
if(Device_Info_List == NULL)
{
ble_send_info.send_state = BLE_ERR_DEVICE_Not_EXIST; //设备链表中不存在该设备
ble_send_info.send_flg = 0;
}
}
ble_send_info.send_flg = 0;
if(ble_send_info.send_state != BLE_ERR_SUCCESS)
{
PRINT("BLE_STA:%d\n", ble_send_info.send_state);
}
}
}
/************************ endfile @ central **************************/