/********************************** (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.625)ms 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; connItemconnecting = 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.25ms)20 DEFAULT_UPDATE_MAX_CONN_INTERVAL, //最大连接间隔(单位:1.25ms)100 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; connItemconnHandle ) 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; connItemlinkCmpl.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; connItemgap.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; connItemlinkTerminate.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; imac, 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 **************************/