/********************************** (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; 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.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; 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 **************************/
