Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2112778
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: 嵌入式

2014-09-08 21:12:37

一. central流程分析
1. 初始化的过程
osal_init_system
    -->osalInitTasks
        --> SimpleBLECentral_Init( taskID );
            -->  //设置自定义事件START_DEVICE_EVT 
                  osal_set_event( simpleBLETaskId, START_DEVICE_EVT );
osal_start_system
    --> 死循环调用osal_run_system  
    --> SimpleBLECentral_ProcessEvent //这是一个用户自定义处理函数,可以处理所有用户自定义事件
SimpleBLECentral_ProcessEvent
{
    SYS_EVENT_MSG    --> 按键与gatt事件
    START_DEVICE_EVT  
        -->处理在初始化时osal_set_event设置的事件
        -->并注册两个回调,但只关心 simpleBLECentralEventCB
        -->产生一个GAP_DEVICE_INIT_DONE_EVENT事件
    START_DISCOVERY_EVT
}

2. 当有按键按下时:
SimpleBLECentral_ProcessEvent会收到SYS_EVENT_MSG
 -->simpleBLECentral_ProcessOSALMsg //区分按键与gatt事件
  --> simpleBLECentral_HandleKeys   //进行按键处理
  {
      //上: 未连接则进行或停止扫描,己连接则进行数据读写
      //左:
      //右: UpdateLink
      //中: 未连接则建立连接;己连接则中断连接
      //下: 如果己连接,输出rssi
  }
2.1 状态回调函数simpleBLECentralEventCB
simpleBLECentralEventCB
{
    GAP_DEVICE_INIT_DONE_EVENT: //START_DEVICE_EVT完成后会产生
    GAP_DEVICE_INFO_EVENT     : //主机收到一个从机的广播包时产生
    GAP_DEVICE_DISCOVERY_EVENT: //主机扫描结束时产生
    GAP_LINK_ESTABLISHED_EVENT: //建立连接后产生
    GAP_LINK_TERMINATED_EVENT : //结束连接后产生
    GAP_LINK_PARAM_UPDATE_EVENT    
}

3. 当己连接时
SimpleBLECentral_ProcessEvent会收到SYS_EVENT_MSG
 -->simpleBLECentral_ProcessOSALMsg //区分按键与gatt事件
  --> simpleBLEGATTDiscoveryEvent   //进行按键处理
simpleBLEGATTDiscoveryEvent
{

}


二.代码分析

2.1 初始化跟 SimpleBLEPeripheral 的初始化基本类似,
osal_init_system
    -->osalInitTasks
        --> SimpleBLECentral_Init( taskID );
在APP->simpleBLECentral.c中,功能:
a.配置GAP,GAP Bond manager的参数
b.初始化GATT client
  1. void SimpleBLECentral_Init( uint8 task_id )
  2. {
  3.   simpleBLETaskId = task_id;

  4.   //串口初始化
  5.   UartInit();
  6.   // Setup Central Profile
  7.   {
  8.     uint8 scanRes = DEFAULT_MAX_SCAN_RES;
  9.     GAPCentralRole_SetParameter ( GAPCENTRALROLE_MAX_SCAN_RES, sizeof( uint8 ), &scanRes );
  10.   }
  11.   
  12.   // Setup GAP
  13.   GAP_SetParamValue( TGAP_GEN_DISC_SCAN, DEFAULT_SCAN_DURATION );
  14.   GAP_SetParamValue( TGAP_LIM_DISC_SCAN, DEFAULT_SCAN_DURATION );
  15.   GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, (uint8 *) simpleBLEDeviceName );

  16.   // Setup the GAP Bond Manager
  17.   {
  18.     uint32 passkey = DEFAULT_PASSCODE;
  19.     uint8 pairMode = DEFAULT_PAIRING_MODE;
  20.     uint8 mitm = DEFAULT_MITM_MODE;
  21.     uint8 ioCap = DEFAULT_IO_CAPABILITIES;
  22.     uint8 bonding = DEFAULT_BONDING_MODE;
  23.     GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof( uint32 ), &passkey );
  24.     GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof( uint8 ), &pairMode );
  25.     GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof( uint8 ), &mitm );
  26.     GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof( uint8 ), &ioCap );
  27.     GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof( uint8 ), &bonding );
  28.   }

  29.   //初始化GATT client
  30.   VOID GATT_InitClient();

  31.   // Register to receive incoming ATT Indications/Notifications
  32.   GATT_RegisterForInd( simpleBLETaskId );

  33.   // Initialize GATT attributes
  34.   GGS_AddService( GATT_ALL_SERVICES ); // GAP
  35.   GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes

  36.   //注册按键事件,只有在这儿注册了才能触发
  37.   RegisterForKeys( simpleBLETaskId );
  38.   
  39.   //关led灯
  40.   HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );
  41.   
  42.   //设置事件START_DEVICE_EVT,这个事件是用户自定义的,所以在用户自定义task中
  43.   osal_set_event( simpleBLETaskId, START_DEVICE_EVT );
  44. }
2.2 进入用户自定义处理函数中
osal_start_system
    --> 死循环调用osal_run_system   //这个到下面这个再看一下
    --> SimpleBLECentral_ProcessEvent  //因为这个函数加到了tasksArr中,所以每次系统loop都会调用到
  1. uint16 SimpleBLECentral_ProcessEvent( uint8 task_id, uint16 events )
  2. {
  3.   if ( events & SYS_EVENT_MSG )
  4.   {
  5.     uint8 *pMsg;
  6.     if ( (pMsg = osal_msg_receive( simpleBLETaskId )) != NULL )
  7.     {
  8.       simpleBLECentral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
  9.       VOID osal_msg_deallocate( pMsg );
  10.     }
  11.     return (events ^ SYS_EVENT_MSG);
  12.   }
  13.   //事件START_DEVICE_EVT的处理,开机启动主机  
  14.   if ( events & START_DEVICE_EVT )
  15.   { 
  16.     VOID GAPCentralRole_StartDevice( (gapCentralRoleCB_t *) &simpleBLERoleCB );
  17.     //向bond manager注册回调
  18.     GAPBondMgr_Register( (gapBondCBs_t *) &simpleBLEBondCB );
  19.     return ( events ^ START_DEVICE_EVT );
  20.   }

  21.   if ( events & START_DISCOVERY_EVT )
  22.   { //按中键建立连接后,在建立连接的事件回调函数simpleBLECentralEventCB,在处理时加的时间定时器产生
  23.     simpleBLECentralStartDiscovery();    //这个函数用来获取gatt server的句柄
  24.     return ( events ^ START_DISCOVERY_EVT );
  25.   }
  26.   return 0;
  27. }
这儿注册了回调函数simpleBLERoleCB,这实际上是个函数数组,包含两个函数
  simpleBLECentralRssiCB,       // RSSI callback,这个会打印rssi信息,不关心
  simpleBLECentralEventCB       // Event callback

  1. static void simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent )
  2. {
  3.   switch ( pEvent->gap.opcode )
  4.   {
  5.     case GAP_DEVICE_INIT_DONE_EVENT:   //START_DEVICE_EVT事件处理完,设备初始化成功就会产生
  6.       {
  7.       }
  8.       break;
  9.     //在扫描过程中每发现一个设备就会产生
  10.     case GAP_DEVICE_INFO_EVENT:
  11.       {  //这个事件是按下key_up键的处理函数执行完后会产生
  12.         if ( DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE )
  13.         {
  14.           //此时pEvent->deviceInfo.pEvtData就是Peripheral发的advertData,len就是advertData的长度
  15.           //下面这个函数就是解析Peripheral发送的advertData这个字符串,找到与SIMPLEPROFILE_SERV_UUID配匹的项  
  16.           if ( simpleBLEFindSvcUuid( SIMPLEPROFILE_SERV_UUID, pEvent->deviceInfo.pEvtData, pEvent->deviceInfo.dataLen ) )
  17.           {
  18.             //然后把Peripheral的设备地址存到simpleBLEDevList中
  19.             simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType );
  20.           }
  21.         }
  22.       }
  23.       break;
  24.       
  25.     case GAP_DEVICE_DISCOVERY_EVENT:
  26.       {
  27.         simpleBLEScanning = FALSE;
  28.         if ( DEFAULT_DEV_DISC_BY_SVC_UUID == FALSE )
  29.         {
  30.           simpleBLEScanRes = pEvent->discCmpl.numDevs;
  31.           osal_memcpy( simpleBLEDevList, pEvent->discCmpl.pDevList, (sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) );
  32.         }
  33.         simpleBLEScanIdx = simpleBLEScanRes;
  34.       }
  35.       break;
  36.     case GAP_LINK_ESTABLISHED_EVENT:
  37.       { //这个事件是按下中键的处理函数执行完后会产生
  38.         if ( pEvent->gap.hdr.status == SUCCESS )
  39.         {
  40.           simpleBLEState = BLE_STATE_CONNECTED;
  41.           simpleBLEConnHandle = pEvent->linkCmpl.connectionHandle;
  42.           simpleBLEProcedureInProgress = TRUE;

  43.           if ( simpleBLECharHdl == 0 )
  44.           { //定时器函数,产生一个START_DISCOVERY_EVT事件,会在SimpleBLECentral_ProcessEvent中处理
  45.             osal_start_timerEx( simpleBLETaskId, START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY );
  46.           }
  47.         }
  48.         else
  49.         {
  50.           simpleBLEState = BLE_STATE_IDLE;
  51.           simpleBLEConnHandle = GAP_CONNHANDLE_INIT;
  52.           simpleBLERssi = FALSE;
  53.           simpleBLEDiscState = BLE_DISC_STATE_IDLE;
  54.         }
  55.       }
  56.       break;

  57.     case GAP_LINK_TERMINATED_EVENT:
  58.       {
  59.         simpleBLEState = BLE_STATE_IDLE;
  60.         simpleBLEConnHandle = GAP_CONNHANDLE_INIT;
  61.         simpleBLERssi = FALSE;
  62.         simpleBLEDiscState = BLE_DISC_STATE_IDLE;
  63.         simpleBLECharHdl = 0;
  64.         simpleBLEProcedureInProgress = FALSE;
  65.       }
  66.       break;

  67.     case GAP_LINK_PARAM_UPDATE_EVENT:
  68.       {
  69.       }
  70.       break;
  71.       
  72.     default:
  73.       break;
  74.   }
  75. }
在这个事件的处理函数中
  1. static void simpleBLECentral_ProcessOSALMsg( osal_event_hdr_t *pMsg )
  2. {
  3.   switch ( pMsg->event )
  4.   {
  5.     case KEY_CHANGE: //只处理按键事件
  6.       simpleBLECentral_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
  7.       break;

  8.     case GATT_MSG_EVENT: //与GATT事件
  9.       simpleBLECentralProcessGATTMsg( (gattMsgEvent_t *) pMsg );
  10.       break;
  11.   }
  12. }
按键事件
  1. static void simpleBLECentral_HandleKeys( uint8 shift, uint8 keys )
  2. {
  3.   (void)shift; // Intentionally unreferenced parameter

  4.   if ( keys & HAL_KEY_UP )    //如果是向上的按键
  5.   {
  6.      if (没有建立连接)
  7.      {
  8.           GAPCentralRole_StartDiscovery();       //进行扫描,每扫到一个设备就会产生GAP_DEVICE_INFO_EVENT
  9.           再按一次GAPCentralRole_CancelDiscovery(); //停止扫描
  10.      }
  11.      else if (己建立连接)
  12.         GATT_WriteCharValue(); 或者 GATT_ReadCharValue();          
  13.    }
  14.    

  15.   if ( keys & HAL_KEY_LEFT )  //如果是向左的按键
  16.   {  //key_up按下时就simpleBLEScanning=true;当扫描到设备时simpleBLEScanRes++
  17.     if ( !simpleBLEScanning && simpleBLEScanRes > 0 )
  18.     {
  19.         simpleBLEScanIdx++;
  20.         if ( simpleBLEScanIdx >= simpleBLEScanRes )
  21.         {
  22.           simpleBLEScanIdx = 0;
  23.         }
  24.     }
  25.   }

  26.   if ( keys & HAL_KEY_RIGHT )
  27.   {
  28.     // Connection update
  29.     if ( simpleBLEState == BLE_STATE_CONNECTED )
  30.     {
  31.       GAPCentralRole_UpdateLink( simpleBLEConnHandle,
  32.                                  DEFAULT_UPDATE_MIN_CONN_INTERVAL,
  33.                                  DEFAULT_UPDATE_MAX_CONN_INTERVAL,
  34.                                  DEFAULT_UPDATE_SLAVE_LATENCY,
  35.                                  DEFAULT_UPDATE_CONN_TIMEOUT );
  36.     }
  37.   }
  38.   
  39.   if ( keys & HAL_KEY_CENTER )
  40.   {  //中键建立或断开连接
  41.     if ( simpleBLEState == BLE_STATE_IDLE )
  42.     {
  43.       if ( simpleBLEScanRes > 0 )
  44.       {  //未连接则建立连接
  45.         peerAddr = simpleBLEDevList[simpleBLEScanIdx].addr;
  46.         addrType = simpleBLEDevList[simpleBLEScanIdx].addrType;
  47.         simpleBLEState = BLE_STATE_CONNECTING;
  48.         GAPCentralRole_EstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE, DEFAULT_LINK_WHITE_LIST, addrType, peerAddr );
  49.       }
  50.     }
  51.     else if ( simpleBLEState == BLE_STATE_CONNECTING || simpleBLEState == BLE_STATE_CONNECTED )
  52.     {  //己连接,则断开连接
  53.       simpleBLEState = BLE_STATE_DISCONNECTING;
  54.       gStatus = GAPCentralRole_TerminateLink( simpleBLEConnHandle );
  55.     }
  56.   }
  57.   
  58.   if ( keys & HAL_KEY_DOWN )
  59.   {
  60.     // Start or cancel RSSI polling
  61.     if ( simpleBLEState == BLE_STATE_CONNECTED )
  62.     {
  63.       if ( !simpleBLERssi )
  64.       {
  65.         simpleBLERssi = TRUE;
  66.         GAPCentralRole_StartRssi( simpleBLEConnHandle, DEFAULT_RSSI_PERIOD );
  67.       }
  68.       else
  69.       {
  70.         simpleBLERssi = FALSE;
  71.         GAPCentralRole_CancelRssi( simpleBLEConnHandle );
  72.         
  73.         LCD_WRITE_STRING( "RSSI Cancelled", HAL_LCD_LINE_1 );
  74.       }
  75.     }
  76.   }
  77. }

当建立连接后会收到GATTMsg
SimpleBLECentral_ProcessEvent //系统接收到SYS_EVENT_MSG
   --> simpleBLECentral_ProcessOSALMsg  //区分按键与gatt
      --> simpleBLECentralProcessGATTMsg   //对于gatt事件
  1. static void simpleBLECentralProcessGATTMsg( gattMsgEvent_t *pMsg )
  2. {
  3.   if ( simpleBLEState != BLE_STATE_CONNECTED )
  4.   {  //未连接,直接返回
  5.      return;
  6.   }
  7.   //gatt中read与write完成之后,会到这儿,对结果进行处理
  8.   //有错的报错,没有错的打印read,write的value
  9.   if ( ( pMsg->method == ATT_READ_RSP ) || (( pMsg->method == ATT_ERROR_RSP ) && ( pMsg->msg.errorRsp.reqOpcode == ATT_READ_REQ ) ) )
  10.   {
  11.     if ( pMsg->method == ATT_ERROR_RSP )
  12.       uint8 status = pMsg->msg.errorRsp.errCode;
  13.     else
  14.       uint8 valueRead = pMsg->msg.readRsp.value[0];
  15.     simpleBLEProcedureInProgress = FALSE;
  16.   }
  17.   else if ( ( pMsg->method == ATT_WRITE_RSP ) || ( ( pMsg->method == ATT_ERROR_RSP ) && ( pMsg->msg.errorRsp.reqOpcode == ATT_WRITE_REQ ) ) )
  18.   {   
  19.     if ( pMsg->method == ATT_ERROR_RSP == ATT_ERROR_RSP )
  20.       uint8 status = pMsg->msg.errorRsp.errCode;
  21.     else
  22.       printV( "Write sent:", simpleBLECharVal++, 10);  
  23.     simpleBLEProcedureInProgress = FALSE;
  24.   }
  25.   else if ( simpleBLEDiscState != BLE_DISC_STATE_IDLE )
  26.   { //非read,write的事件就是系统产生的GATT discovery event
  27.     simpleBLEGATTDiscoveryEvent( pMsg );
  28.   } 
  29. }


  1. static void simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg )
  2. {
  3.   attReadByTypeReq_t req;
  4.   
  5.   if ( simpleBLEDiscState == BLE_DISC_STATE_SVC )
  6.   {
  7.     if ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->msg.findByTypeValueRsp.numInfo > 0 )
  8.     {
  9.       simpleBLESvcStartHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].handle;
  10.       simpleBLESvcEndHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle;
  11.     }
  12.     
  13.     if ( ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->hdr.status == bleProcedureComplete ) ||
  14.          ( pMsg->method == ATT_ERROR_RSP ) )
  15.     {
  16.       if ( simpleBLESvcStartHdl != 0 )
  17.       {
  18.         simpleBLEDiscState = BLE_DISC_STATE_CHAR;
  19.         req.startHandle = simpleBLESvcStartHdl;
  20.         req.endHandle = simpleBLESvcEndHdl;
  21.         req.type.len = ATT_BT_UUID_SIZE;
  22.         req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR1_UUID);
  23.         req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR1_UUID);
  24.         //发送获取charsimpleBLECharHdl的命令,成功后会产生一个GATT_MSG_EVENT
  25.         //其type=ATT_READ_BY_TYPE_RSP,即到了下面的这个else if
  26.         GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId ); 
  27.       }
  28.     }
  29.   }
  30.   else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR )
  31.   { //上面的GATT_ReadUsingCharUUID成功后,产生一个ATT_READ_BY_TYPE_RSP
  32.     //那么就可以获取simpleBLECharHdl了=0x25
  33.     if ( pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->msg.readByTypeRsp.numPairs > 0 )
  34.     {
  35.       simpleBLECharHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0], pMsg->msg.readByTypeRsp.dataList[1] );     
  36.       simpleBLEProcedureInProgress = FALSE;
  37.     }
  38.     simpleBLEDiscState = BLE_DISC_STATE_IDLE;
  39.   }
  40. }





阅读(8994) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~