damiaa 发表于 2023-9-7 16:58

【stm32wba】+10 stm32wba低功耗蓝牙软件app部分分析之三

<div class='showpostmsg'> 本帖最后由 damiaa 于 2023-9-8 09:23 编辑

<p><strong><span style="font-size:22px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size:18px;">【stm32wba】+10 stm32wba低功耗蓝牙软件app部分分析之三</span></strong></p>

<p>&nbsp;</p>

<p><a href="https://bbs.eeworld.com.cn/thread-1250745-1-1.html">【NUCLEO-WBA52CG】+1开箱贴</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1250558-1-1.html">【STM32WBA52CG】+2 STM32WBA Web Bluetooth试玩</a></p>

<p><a href="https://bbs.eeworld.com.cn/forum.php?mod=viewthread&amp;tid=1252139&amp;page=1&amp;extra=#pid3251401">【STM32WBA52CG】+3 STM32WBA 外设应用一 按键和点灯</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1252142-1-1.html">【STM32WBA52CG】+4 外设应用二 串口使用</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1252882-1-1.html">【STM32WBA52CG】+5 THREADX使用</a></p>

<p><span style="font-size:12px;"><a href="https://bbs.eeworld.com.cn/thread-1255128-1-1.html">【STM32WBA52CG】+6 SEQUENCER调度器</a></span></p>

<p><span style="font-size:12px;"><a href="https://bbs.eeworld.com.cn/thread-1255338-1-1.html">【stm32wba】+7 stm32wba低功耗蓝牙软件基本架构</a></span></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1255401-1-1.html#pid3259425">【stm32wba】+8 stm32wba低功耗蓝牙软件app部分分析之一</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1255590-1-1.html">【stm32wba】+9 stm32wba低功耗蓝牙软件app部分分析之二</a><strong>之后继续</strong></p>

<p><strong>今天主要了解一下和STM32_WPAM==&gt;APP里面的三个文件的一些代码相关。</strong></p>

<p></p>

<p>这三个文件主要功能就是各种初始化和相关的蓝牙用户事情的响应和处理,等等,对应的软件框架部分是GAP和GATT/ATT。</p>

<p></p>

<p><strong>通用访问配置文件(</strong><strong>GAP</strong><strong>)</strong></p>

<p>蓝牙系统为所有的蓝牙设备定义了一个基础配置文件,叫做通用访问配置文件(GAP)。</p>

<p>名称发现流程 用于从可连接设备检索&ldquo;蓝牙设备名称&rdquo;的流程 角色为中央设备</p>

<p><strong>属性配置文件(</strong><strong>ATT</strong><strong>)</strong></p>

<p>属性配置文件(ATT)允许设备向另一设备公开某些数据,即属性。公开属性的设备被称为服务器,而使用它们的对端设备被称为客户端。</p>

<p><strong>通用属性配置文件(</strong><strong>GATT</strong><strong>) </strong></p>

<p>通用属性配置文件(GATT)定义了使用 ATT 协议的框架,它被用于服务、特征、描述符发现、特征读取、写入、指示和通知。</p>

<p>&nbsp;</p>

<p>p2p_server_app.c 负责gatt/att 的具体实现,</p>

<p>p2p_server.c gatt/att的几个具体函数的实现函数:</p>

<p></p>

<p></p>

<p>&nbsp;</p>

<p>Peer to Peer Profile基于通用属性简档(GATT)的低能量Profile</p>

<p>广泛用于直接连接的对等配置文件定义了对等服务器设备的GATT服务器与GATT客户端收集器设备(如智能手机、STM32WBA对等客户端或对等路由器设备)之间的通信。</p>

<p>&nbsp;</p>

<p></p>

<p>&nbsp;</p>

<p><strong><span style="font-size:22px;"><span style="color:#2c3e50;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span></span><span style="font-size:24px;"><span style="color:#2c3e50;"> &nbsp;</span></span></strong></p>

<p><strong><span style="font-size:24px;"><span style="color:#2c3e50;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;app.ble.c</span></span><span style="font-size:22px;"><span style="color:#2c3e50;"> </span></span></strong></p>

<p>&nbsp;</p>

<p><span style="font-size:16px;"><span style="color:#2c3e50;">主要负责各种初始化和gap的初始化,事件响应等。</span></span></p>

<p>&nbsp;</p>

<p></p>

<p>/* Security parameters structure */ /*安全参数结构*/</p>

<pre>
<code>typedef struct
{
/* IO capability of the device */
uint8_t ioCapability;
/**
* Authentication requirement of the device
* Man In the Middle protection required?
*/
uint8_t mitm_mode;
/* Bonding mode of the device */
uint8_t bonding_mode;
/**
* this variable indicates whether to use a fixed pin
* during the pairing process or a passkey has to be
* requested to the application during the pairing process
* 0 implies use fixed pin and 1 implies request for passkey
*/
uint8_t Use_Fixed_Pin;
/* Minimum encryption key size requirement */
uint8_t encryptionKeySizeMin;
/* Maximum encryption key size requirement */
uint8_t encryptionKeySizeMax;
/**
* fixed pin to be used in the pairing process if
* Use_Fixed_Pin is set to 1
*/
uint32_t Fixed_Pin;
/**
* this flag indicates whether the host has to initiate
* the security, wait for pairing or does not have any security
* requirements.
* 0x00 : no security required
* 0x01 : host should initiate security by sending the slave security
* request command
* 0x02 : host need not send the clave security request but it
* has to wait for paiirng to complete before doing any other
* processing
*/
uint8_t initiateSecurity;
/* USER CODE BEGIN tSecurityParams*/
/* USER CODE END tSecurityParams */
}SecurityParams_t;</code></pre>

<p>/* Global context contains all BLE common variables. 所有BLE公共变量全局上下文结构*/</p>

<pre>
<code class="language-cpp">typedef struct
{
/* Security requirements of the host */
SecurityParams_t bleSecurityParam;
/* GAP service handle */
uint16_t gapServiceHandle;
/* Device name characteristic handle */
uint16_t devNameCharHandle;
/* Appearance characteristic handle */
uint16_t appearanceCharHandle;
/**
* connection handle of the current active connection
* When not in connection, the handle is set to 0xFFFF
*/
uint16_t connectionHandle;
/* USER CODE BEGIN BleGlobalContext_t*/
/* USER CODE END BleGlobalContext_t */
}BleGlobalContext_t;</code></pre>

<p>/* 蓝牙应用上下文结构 */</p>

<pre>
<code>typedef struct
{
BleGlobalContext_t BleApplicationContext_legacy;
APP_BLE_ConnStatus_t Device_Connection_Status;
/* USER CODE BEGIN PTD_1*/
/* Advertising timeout timerID*/
UTIL_TIMER_Object_t Advertising_mgr_timer_Id;
/* Led Timeout timerID */
UTIL_TIMER_Object_t SwitchOffGPIO_timer_Id;
uint8_t connIntervalFlag;
/* USER CODE END PTD_1 */
}BleApplicationContext_t;</code></pre>

<p>/* Private defines -----------------------------------------------------------*/</p>

<p>/* GATT buffer size (in bytes) GATT 缓存大小*/</p>

<p>#define BLE_GATT_BUF_SIZE \</p>

<p>&nbsp; &nbsp;BLE_TOTAL_BUFFER_SIZE_GATT(CFG_BLE_NUM_GATT_ATTRIBUTES, \</p>

<p>&nbsp; &nbsp;CFG_BLE_NUM_GATT_SERVICES, \</p>

<p>&nbsp; CFG_BLE_ATT_VALUE_ARRAY_SIZE)</p>

<p>#define MBLOCK_COUNT (BLE_MBLOCKS_CALC(PREP_WRITE_LIST_SIZE, \</p>

<p>&nbsp; CFG_BLE_ATT_MTU_MAX, \</p>

<p>&nbsp; CFG_BLE_NUM_LINK) \</p>

<p>&nbsp; + CFG_BLE_MBLOCK_COUNT_MARGIN)</p>

<p>#define BLE_DYN_ALLOC_SIZE \</p>

<p>&nbsp;(BLE_TOTAL_BUFFER_SIZE(CFG_BLE_NUM_LINK, MBLOCK_COUNT))</p>

<p>/*led ON adv 超时时间*/</p>

<p>#define LED_ON_TIMEOUT_MS (5)</p>

<p>#define ADV_TIMEOUT_MS (60 * 1000)</p>

<p>static tListNode BleAsynchEventQueue;</p>

<p>/*48位蓝牙设备地址</p>

<p>BD_ADDR(Bluetooth Device Address)。BD_ADDR分为三个部分,分别为24个位元的LAP(Lower Address Part)、8个位元的UAP(Upper Address Part)段落、以及16个位元的NAP(Non-significant Address Part)。*/</p>

<p>static const uint8_t a_MBdAddr =</p>

<p>{</p>

<p>&nbsp; (uint8_t)((CFG_BD_ADDRESS &amp; 0x0000000000FF)),</p>

<p>&nbsp; (uint8_t)((CFG_BD_ADDRESS &amp; 0x00000000FF00) &gt;&gt; 8),</p>

<p>&nbsp; (uint8_t)((CFG_BD_ADDRESS &amp; 0x000000FF0000) &gt;&gt; 16),</p>

<p>&nbsp; (uint8_t)((CFG_BD_ADDRESS &amp; 0x0000FF000000) &gt;&gt; 24),</p>

<p>&nbsp; (uint8_t)((CFG_BD_ADDRESS &amp; 0x00FF00000000) &gt;&gt; 32),</p>

<p>&nbsp; (uint8_t)((CFG_BD_ADDRESS &amp; 0xFF0000000000) &gt;&gt; 40)</p>

<p>};</p>

<p>static uint8_t a_BdAddrUdn;</p>

<p>/* Identity root key used to derive LTK and CSRK用于导出LTK和CSRK的标识根密钥 */</p>

<p>static const uint8_t a_BLE_CfgIrValue = CFG_BLE_IRK;</p>

<p>/* Encryption root key used to derive LTK and CSRK用于导出LTK和CSRK的加密根密钥 */</p>

<p>static const uint8_t a_BLE_CfgErValue = CFG_BLE_ERK;</p>

<p>static BleApplicationContext_t bleAppContext;</p>

<p>/*P2P_SERVER_APP_ConnHandleNotEvt_t句柄 用与Notification*/</p>

<p>P2P_SERVER_APP_ConnHandleNotEvt_t P2P_SERVERHandleNotification;</p>

<p>/*Gap 设备名*/</p>

<p>static const char a_GapDeviceName[] = { &#39;P&#39;, &#39;e&#39;, &#39;e&#39;, &#39;r&#39;, &#39; &#39;, &#39;t&#39;, &#39;o&#39;, &#39; &#39;, &#39;P&#39;, &#39;e&#39;, &#39;e&#39;, &#39;r&#39;, &#39; &#39;, &#39;S&#39;, &#39;e&#39;, &#39;r&#39;, &#39;v&#39;, &#39;e&#39;, &#39;r&#39; }; /* Gap Device Name */</p>

<p>/* Advertising Data 广播数据 */</p>

<p>uint8_t a_AdvData =</p>

<p>{</p>

<p>&nbsp; 8, AD_TYPE_COMPLETE_LOCAL_NAME, &#39;p&#39;, &#39;2&#39;, &#39;p&#39;, &#39;S&#39;, &#39;_&#39;, &#39;X&#39;, &#39;X&#39;, /* Complete name */</p>

<p>&nbsp; 15, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x30, 0x00, 0x00 /* */, 0x00 /* */, 0x00 /* */, 0x00 /* */, 0x00 /* */, 0x00 /* */, 0x00 /* */, 0x00 /* */, 0x00 /* */, 0x00 /* */, 0x00 /* */, 0x00 /* */,</p>

<p>};</p>

<p>uint64_t buffer_nvm = {0};</p>

<p>static AMM_VirtualMemoryCallbackFunction_t APP_BLE_ResumeFlowProcessCb;</p>

<p>/* Host stack init variables */</p>

<p>static uint32_t buffer;</p>

<p>static uint32_t gatt_buffer;</p>

<p>static BleStack_init_t pInitParams;</p>

<p>static void BleStack_Process_BG(void);</p>

<p>static void Ble_UserEvtRx(void);</p>

<p>static void Ble_Hci_Gap_Gatt_Init(void);</p>

<p>static const uint8_t* BleGetBdAddress(void);</p>

<p>static void gap_cmd_resp_wait(void);</p>

<p>static void gap_cmd_resp_release(void);</p>

<p>static void BLE_ResumeFlowProcessCallback(void);</p>

<p>static void BLE_NvmCallback (SNVMA_Callback_Status_t);</p>

<p>static uint8_t HOST_BLE_Init(void);</p>

<p>static void Adv_Cancel_Req(void *arg);</p>

<p>static void Adv_Cancel(void);</p>

<p>static void Switch_OFF_GPIO(void *arg);</p>

<p>static void fill_advData(uint8_t *p_adv_data, uint8_t tab_size, const uint8_t*p_bd_addr);</p>

<p>/* USER CODE END PFP */</p>

<p>&nbsp;</p>

<p>/* 这个函数初始化蓝牙设备 由main函数调用*/</p>

<p><span style="color:#2ecc71;">void APP_BLE_Init(void)</span></p>

<p>{</p>

<p>&nbsp; tBleStatus ret = BLE_STATUS_INVALID_PARAMS;</p>

<p>&nbsp;<span style="color:#2ecc71;"> LST_init_head(&amp;BleAsynchEventQueue);</span></p>

<p>&nbsp; //注册两个任务</p>

<p>&nbsp; <span style="color:#2ecc71;">UTIL_SEQ_RegTask(1U &lt;&lt; CFG_TASK_BLE_HOST, UTIL_SEQ_RFU, BleStack_Process_BG);</span></p>

<p><span style="color:#2ecc71;">&nbsp; UTIL_SEQ_RegTask(1U &lt;&lt; CFG_TASK_HCI_ASYNCH_EVT_ID, UTIL_SEQ_RFU, Ble_UserEvtRx);</span></p>

<p>&nbsp; /* NVM emulation in RAM initialization 初始化*/</p>

<p>&nbsp; NVM_Init(buffer_nvm, 0, CFG_BLEPLAT_NVM_MAX_SIZE);</p>

<p>&nbsp; /* First register the APP BLE buffer 等级APP BLE 缓存 */</p>

<p>&nbsp;<span style="color:#2ecc71;"> SNVMA_Register (APP_BLE_NvmBuffer,(uint32_t *)buffer_nvm,&nbsp;(CFG_BLEPLAT_NVM_MAX_SIZE * 2));</span></p>

<p>&nbsp; /* Realize a restore */</p>

<p>&nbsp; SNVMA_Restore (APP_BLE_NvmBuffer);</p>

<p>&nbsp; /* Check consistency */</p>

<p>&nbsp; if (NVM_Get (NVM_FIRST, 0xFF, 0, 0, 0) != NVM_EOF){&nbsp; NVM_Discard (NVM_ALL);&nbsp;}</p>

<p>&nbsp; /* Initialize the BLE Host 初始化the BLE Host */</p>

<p>&nbsp; if (<span style="color:#2ecc71;">HOST_BLE_Init() </span>== 0u)</p>

<p>&nbsp; {</p>

<p>&nbsp; &nbsp; /* Initialization of HCI &amp; GATT &amp; GAP layer 初始化gap gatt*/</p>

<p>&nbsp; &nbsp;<span style="color:#2ecc71;"> Ble_Hci_Gap_Gatt_Init();</span></p>

<p>&nbsp; &nbsp; /* Initialization of the BLE Services 初始化ble服务*/</p>

<p>&nbsp; <span style="color:#2ecc71;">&nbsp;SVCCTL_Init();</span></p>

<p>&nbsp; &nbsp; /* Initialization of the BLE App Context the BLE App Context初始化*/</p>

<p>&nbsp; &nbsp; bleAppContext.Device_Connection_Status = APP_BLE_IDLE;</p>

<p>&nbsp; &nbsp; bleAppContext.BleApplicationContext_legacy.connectionHandle = 0xFFFF;</p>

<p>&nbsp; &nbsp; /* From here, all initialization are BLE application specific 这里所有蓝牙应用的初始化配置*/</p>

<p>&nbsp; &nbsp;<span style="color:#2ecc71;"> UTIL_SEQ_RegTask(1&lt;&lt;CFG_TASK_ADV_CANCEL_ID, UTIL_SEQ_RFU, Adv_Cancel);</span>//ADV_CANCEL任务注册</p>

<p>&nbsp; &nbsp; /* Create timer to handle the Advertising Stop 创建处理广播停止的定时器*/</p>

<p>&nbsp; &nbsp; <span style="color:#2ecc71;">UTIL_TIMER_Create(&amp;(bleAppContext.Advertising_mgr_timer_Id),0,(UTIL_TIMER_Mode_t)hw_ts_SingleShot,&amp;Adv_Cancel_Req,0);</span></p>

<p>&nbsp; &nbsp; /* Create timer to handle the Led Switch OFF 创建led关闭定时器 */</p>

<p>&nbsp; &nbsp; <span style="color:#2ecc71;">UTIL_TIMER_Create(&amp;(bleAppContext.SwitchOffGPIO_timer_Id),0,(UTIL_TIMER_Mode_t)hw_ts_SingleShot,&amp;Switch_OFF_GPIO,0);</span></p>

<p>&nbsp; &nbsp; /* Initialize Services and Characteristics. 初始化服务和特性*/</p>

<p>&nbsp; &nbsp; APP_DBG_MSG(&quot;\n&quot;);</p>

<p>&nbsp; &nbsp; APP_DBG_MSG(&quot;Services and Characteristics creation\n&quot;);</p>

<p>&nbsp; &nbsp; <span style="color:#2ecc71;">P2P_SERVER_APP_Init();</span></p>

<p>&nbsp; &nbsp; APP_DBG_MSG(&quot;End of Services and Characteristics creation\n&quot;);</p>

<p>&nbsp; &nbsp; APP_DBG_MSG(&quot;\n&quot;)</p>

<p>&nbsp; &nbsp; /* 设置硬件射频活动*/</p>

<p>&nbsp; &nbsp; <span style="color:#2ecc71;">ret = aci_hal_set_radio_activity_mask(0x0006);</span></p>

<p>&nbsp; &nbsp; if (ret != BLE_STATUS_SUCCESS){&nbsp; &nbsp; APP_DBG_MSG(&quot; Fail : aci_hal_set_radio_activity_mask command, result: 0x%2X\n&quot;, ret);&nbsp;}</p>

<p>&nbsp; &nbsp; else&nbsp;{&nbsp; &nbsp; APP_DBG_MSG(&quot; Success: aci_hal_set_radio_activity_mask command\n\r&quot;);&nbsp;}</p>

<p>&nbsp; &nbsp; /* Start to Advertise to accept a connection 启动广播接受一个连接*/</p>

<p>&nbsp; &nbsp; <span style="color:#2ecc71;">APP_BLE_Procedure_Gap_Peripheral(PROC_GAP_PERIPH_ADVERTISE_START_FAST);</span></p>

<p>&nbsp; &nbsp; /* Start a timer to stop advertising after a while 启动定时器过一会ADV_TIMEOUT_MS 停止广播*/</p>

<p>&nbsp; &nbsp;<span style="color:#2ecc71;"> UTIL_TIMER_StartWithPeriod(&amp;bleAppContext.Advertising_mgr_timer_Id, ADV_TIMEOUT_MS);</span></p>

<p>&nbsp; }</p>

<p>&nbsp; bleAppContext.connIntervalFlag = 0;</p>

<p>&nbsp; return;</p>

<p>}</p>

<p>&nbsp;</p>

<p>/*************************************处理gap事件函数*********************************************/</p>

<pre>
<code>SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void *p_Pckt)
{
tBleStatus ret = BLE_STATUS_ERROR;
hci_event_pckt    *p_event_pckt;
evt_le_meta_event *p_meta_evt;
evt_blecore_aci   *p_blecore_evt;

p_event_pckt = (hci_event_pckt*) ((hci_uart_pckt *) p_Pckt)-&gt;data;
UNUSED(ret);
/* USER CODE BEGIN SVCCTL_App_Notification */

/* USER CODE END SVCCTL_App_Notification */

switch (p_event_pckt-&gt;evt)
{
    case HCI_DISCONNECTION_COMPLETE_EVT_CODE:
    {
      hci_disconnection_complete_event_rp0 *p_disconnection_complete_event;
      p_disconnection_complete_event = (hci_disconnection_complete_event_rp0 *) p_event_pckt-&gt;data;

      if (p_disconnection_complete_event-&gt;Connection_Handle == bleAppContext.BleApplicationContext_legacy.connectionHandle)
      {
      bleAppContext.BleApplicationContext_legacy.connectionHandle = 0;
      bleAppContext.Device_Connection_Status = APP_BLE_IDLE;
      APP_DBG_MSG("&gt;&gt;== HCI_DISCONNECTION_COMPLETE_EVT_CODE\n");
      APP_DBG_MSG("   - Connection Handle:   0x%02X\n   - Reason:    0x%02X\n",
                  p_disconnection_complete_event-&gt;Connection_Handle,
                  p_disconnection_complete_event-&gt;Reason);

      /* USER CODE BEGIN EVT_DISCONN_COMPLETE_2 */

      /* USER CODE END EVT_DISCONN_COMPLETE_2 */
      }

      gap_cmd_resp_release();

      /* USER CODE BEGIN EVT_DISCONN_COMPLETE_1 */

      /* USER CODE END EVT_DISCONN_COMPLETE_1 */
      P2P_SERVERHandleNotification.EvtOpcode = P2P_SERVER_DISCON_HANDLE_EVT;
      P2P_SERVERHandleNotification.ConnectionHandle = p_disconnection_complete_event-&gt;Connection_Handle;
      P2P_SERVER_APP_EvtRx(&amp;P2P_SERVERHandleNotification);
      /* USER CODE BEGIN EVT_DISCONN_COMPLETE */
      APP_BLE_Procedure_Gap_Peripheral(PROC_GAP_PERIPH_ADVERTISE_START_FAST);
      UTIL_TIMER_StartWithPeriod(&amp;bleAppContext.Advertising_mgr_timer_Id, ADV_TIMEOUT_MS);
      /* USER CODE END EVT_DISCONN_COMPLETE */
      break; /* HCI_DISCONNECTION_COMPLETE_EVT_CODE */
    }

    case HCI_LE_META_EVT_CODE:
    {
      p_meta_evt = (evt_le_meta_event*) p_event_pckt-&gt;data;
      /* USER CODE BEGIN EVT_LE_META_EVENT */

      /* USER CODE END EVT_LE_META_EVENT */
      switch (p_meta_evt-&gt;subevent)
      {
      case HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE:
      {
          hci_le_connection_update_complete_event_rp0 *p_conn_update_complete;
          p_conn_update_complete = (hci_le_connection_update_complete_event_rp0 *) p_meta_evt-&gt;data;
          APP_DBG_MSG("&gt;&gt;== HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE\n");
          APP_DBG_MSG("   - Connection Interval:   %.2f ms\n   - Connection latency:    %d\n   - Supervision Timeout:   %d ms\n",
                     p_conn_update_complete-&gt;Conn_Interval*1.25,
                     p_conn_update_complete-&gt;Conn_Latency,
                     p_conn_update_complete-&gt;Supervision_Timeout*10);
          UNUSED(p_conn_update_complete);
          /* USER CODE BEGIN EVT_LE_CONN_UPDATE_COMPLETE */

          /* USER CODE END EVT_LE_CONN_UPDATE_COMPLETE */
          break;
      }
      case HCI_LE_PHY_UPDATE_COMPLETE_SUBEVT_CODE:
      {
          hci_le_phy_update_complete_event_rp0 *p_le_phy_update_complete;
          p_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)p_meta_evt-&gt;data;
          UNUSED(p_le_phy_update_complete);

          gap_cmd_resp_release();

          /* USER CODE BEGIN EVT_LE_PHY_UPDATE_COMPLETE */

          /* USER CODE END EVT_LE_PHY_UPDATE_COMPLETE */
          break;
      }
      case HCI_LE_ENHANCED_CONNECTION_COMPLETE_SUBEVT_CODE:
      {
          hci_le_enhanced_connection_complete_event_rp0 *p_enhanced_conn_complete;
          p_enhanced_conn_complete = (hci_le_enhanced_connection_complete_event_rp0 *) p_meta_evt-&gt;data;

          APP_DBG_MSG("&gt;&gt;== HCI_LE_ENHANCED_CONNECTION_COMPLETE_SUBEVT_CODE - Connection handle: 0x%04X\n", p_enhanced_conn_complete-&gt;Connection_Handle);
          APP_DBG_MSG("   - Connection established with @:%02x:%02x:%02x:%02x:%02x:%02x\n",
                      p_enhanced_conn_complete-&gt;Peer_Address,
                      p_enhanced_conn_complete-&gt;Peer_Address,
                      p_enhanced_conn_complete-&gt;Peer_Address,
                      p_enhanced_conn_complete-&gt;Peer_Address,
                      p_enhanced_conn_complete-&gt;Peer_Address,
                      p_enhanced_conn_complete-&gt;Peer_Address);
          APP_DBG_MSG("   - Connection Interval:   %.2f ms\n   - Connection latency:    %d\n   - Supervision Timeout: %d ms\n",
                      p_enhanced_conn_complete-&gt;Conn_Interval * 1.25,
                      p_enhanced_conn_complete-&gt;Conn_Latency,
                      p_enhanced_conn_complete-&gt;Supervision_Timeout * 10
                     );

          if (bleAppContext.Device_Connection_Status == APP_BLE_LP_CONNECTING)
          {
            /* Connection as client */
            bleAppContext.Device_Connection_Status = APP_BLE_CONNECTED_CLIENT;
          }
          else
          {
            /* Connection as server */
            bleAppContext.Device_Connection_Status = APP_BLE_CONNECTED_SERVER;
          }
          bleAppContext.BleApplicationContext_legacy.connectionHandle = p_enhanced_conn_complete-&gt;Connection_Handle;

          P2P_SERVERHandleNotification.EvtOpcode = P2P_SERVER_CONN_HANDLE_EVT;
          P2P_SERVERHandleNotification.ConnectionHandle = p_enhanced_conn_complete-&gt;Connection_Handle;
          P2P_SERVER_APP_EvtRx(&amp;P2P_SERVERHandleNotification);

          /* USER CODE BEGIN HCI_EVT_LE_ENHANCED_CONN_COMPLETE */
          /* The connection is done, there is no need anymore to schedule the LP ADV */
          UTIL_TIMER_Stop(&amp;(bleAppContext.Advertising_mgr_timer_Id));
          /* USER CODE END HCI_EVT_LE_ENHANCED_CONN_COMPLETE */
          break; /* HCI_LE_ENHANCED_CONNECTION_COMPLETE_SUBEVT_CODE */
      }
      case HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE:
      {
          hci_le_connection_complete_event_rp0 *p_conn_complete;
          p_conn_complete = (hci_le_connection_complete_event_rp0 *) p_meta_evt-&gt;data;

          APP_DBG_MSG("&gt;&gt;== HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE - Connection handle: 0x%04X\n", p_conn_complete-&gt;Connection_Handle);
          APP_DBG_MSG("   - Connection established with @:%02x:%02x:%02x:%02x:%02x:%02x\n",
                      p_conn_complete-&gt;Peer_Address,
                      p_conn_complete-&gt;Peer_Address,
                      p_conn_complete-&gt;Peer_Address,
                      p_conn_complete-&gt;Peer_Address,
                      p_conn_complete-&gt;Peer_Address,
                      p_conn_complete-&gt;Peer_Address);
          APP_DBG_MSG("   - Connection Interval:   %.2f ms\n   - Connection latency:    %d\n   - Supervision Timeout: %d ms\n",
                      p_conn_complete-&gt;Conn_Interval * 1.25,
                      p_conn_complete-&gt;Conn_Latency,
                      p_conn_complete-&gt;Supervision_Timeout * 10
                     );

          if (bleAppContext.Device_Connection_Status == APP_BLE_LP_CONNECTING)
          {
            /* Connection as client */
            bleAppContext.Device_Connection_Status = APP_BLE_CONNECTED_CLIENT;
          }
          else
          {
            /* Connection as server */
            bleAppContext.Device_Connection_Status = APP_BLE_CONNECTED_SERVER;
          }
          bleAppContext.BleApplicationContext_legacy.connectionHandle = p_conn_complete-&gt;Connection_Handle;

          P2P_SERVERHandleNotification.EvtOpcode = P2P_SERVER_CONN_HANDLE_EVT;
          P2P_SERVERHandleNotification.ConnectionHandle = p_conn_complete-&gt;Connection_Handle;
          P2P_SERVER_APP_EvtRx(&amp;P2P_SERVERHandleNotification);

          /* USER CODE BEGIN HCI_EVT_LE_CONN_COMPLETE */
          /* The connection is done, there is no need anymore to schedule the LP ADV */
          UTIL_TIMER_Stop(&amp;(bleAppContext.Advertising_mgr_timer_Id));
          /* USER CODE END HCI_EVT_LE_CONN_COMPLETE */
          break; /* HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE */
      }
      default:
          /* USER CODE BEGIN SUBEVENT_DEFAULT */

          /* USER CODE END SUBEVENT_DEFAULT */
          break;
      }

      /* USER CODE BEGIN META_EVT */

      /* USER CODE END META_EVT */
    }
      break; /* HCI_LE_META_EVT_CODE */

    case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE:
    {
      p_blecore_evt = (evt_blecore_aci*) p_event_pckt-&gt;data;
      /* USER CODE BEGIN EVT_VENDOR */

      /* USER CODE END EVT_VENDOR */
      switch (p_blecore_evt-&gt;ecode)
      {
      /* USER CODE BEGIN ecode */

      /* USER CODE END ecode */
      case ACI_L2CAP_CONNECTION_UPDATE_RESP_VSEVT_CODE:
      {
          aci_l2cap_connection_update_resp_event_rp0 *p_l2cap_conn_update_resp;
          p_l2cap_conn_update_resp = (aci_l2cap_connection_update_resp_event_rp0 *) p_blecore_evt-&gt;data;
          UNUSED(p_l2cap_conn_update_resp);
          /* USER CODE BEGIN EVT_L2CAP_CONNECTION_UPDATE_RESP */

          /* USER CODE END EVT_L2CAP_CONNECTION_UPDATE_RESP */
          break;
      }
      case ACI_GAP_PROC_COMPLETE_VSEVT_CODE:
      {
          APP_DBG_MSG("&gt;&gt;== ACI_GAP_PROC_COMPLETE_VSEVT_CODE\n");
          aci_gap_proc_complete_event_rp0 *p_gap_proc_complete;
          p_gap_proc_complete = (aci_gap_proc_complete_event_rp0*) p_blecore_evt-&gt;data;
          UNUSED(p_gap_proc_complete);
          /* USER CODE BEGIN EVT_GAP_PROCEDURE_COMPLETE */

          /* USER CODE END EVT_GAP_PROCEDURE_COMPLETE */
          break; /* ACI_GAP_PROC_COMPLETE_VSEVT_CODE */
      }
      case ACI_HAL_END_OF_RADIO_ACTIVITY_VSEVT_CODE:
          /* USER CODE BEGIN RADIO_ACTIVITY_EVENT*/
          BSP_LED_On(LED_GREEN);
          UTIL_TIMER_StartWithPeriod(&amp;bleAppContext.SwitchOffGPIO_timer_Id, LED_ON_TIMEOUT_MS);
          /* USER CODE END RADIO_ACTIVITY_EVENT*/
          break; /* ACI_HAL_END_OF_RADIO_ACTIVITY_VSEVT_CODE */
      case ACI_GAP_KEYPRESS_NOTIFICATION_VSEVT_CODE:
      {
          APP_DBG_MSG("&gt;&gt;== ACI_GAP_KEYPRESS_NOTIFICATION_VSEVT_CODE\n");
          /* USER CODE BEGIN ACI_GAP_KEYPRESS_NOTIFICATION_VSEVT_CODE*/

          /* USER CODE END ACI_GAP_KEYPRESS_NOTIFICATION_VSEVT_CODE*/
          break;
      }
      case ACI_GAP_PASS_KEY_REQ_VSEVT_CODE:
      {
          APP_DBG_MSG("&gt;&gt;== ACI_GAP_PASS_KEY_REQ_VSEVT_CODE\n");

          ret = aci_gap_pass_key_resp(bleAppContext.BleApplicationContext_legacy.connectionHandle, CFG_FIXED_PIN);
          if (ret != BLE_STATUS_SUCCESS)
          {
            APP_DBG_MSG("==&gt;&gt; aci_gap_pass_key_resp : Fail, reason: 0x%02X\n", ret);
          }
          else
          {
            APP_DBG_MSG("==&gt;&gt; aci_gap_pass_key_resp : Success\n");
          }
          /* USER CODE BEGIN ACI_GAP_PASS_KEY_REQ_VSEVT_CODE*/

          /* USER CODE END ACI_GAP_PASS_KEY_REQ_VSEVT_CODE*/
          break;
      }
      case ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE:
      {
          uint8_t confirm_value;
          APP_DBG_MSG("&gt;&gt;== ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE\n");
          APP_DBG_MSG("   - numeric_value = %ld\n",
                      ((aci_gap_numeric_comparison_value_event_rp0 *)(p_blecore_evt-&gt;data))-&gt;Numeric_Value);
          APP_DBG_MSG("   - Hex_value = %lx\n",
                      ((aci_gap_numeric_comparison_value_event_rp0 *)(p_blecore_evt-&gt;data))-&gt;Numeric_Value);

          /* Set confirm value to 1(YES) */
          confirm_value = 1;
          /* USER CODE BEGIN ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE_0*/

          /* USER CODE END ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE_0*/

          ret = aci_gap_numeric_comparison_value_confirm_yesno(bleAppContext.BleApplicationContext_legacy.connectionHandle, confirm_value);
          if (ret != BLE_STATUS_SUCCESS)
          {
            APP_DBG_MSG("==&gt;&gt; aci_gap_numeric_comparison_value_confirm_yesno : Fail, reason: 0x%02X\n", ret);
          }
          else
          {
            APP_DBG_MSG("==&gt;&gt; aci_gap_numeric_comparison_value_confirm_yesno : Success\n");
          }
          /* USER CODE BEGIN ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE*/

          /* USER CODE END ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE*/
          break;
      }
      case ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE:
      {
          APP_DBG_MSG("&gt;&gt;== ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE\n");
          aci_gap_pairing_complete_event_rp0 *p_pairing_complete;
          p_pairing_complete = (aci_gap_pairing_complete_event_rp0*)p_blecore_evt-&gt;data;

          if (p_pairing_complete-&gt;Status != 0)
          {
            APP_DBG_MSG("   - Pairing KO\n   - Status: 0x%02X\n   - Reason: 0x%02X\n",
                         p_pairing_complete-&gt;Status, p_pairing_complete-&gt;Reason);
          }
          else
          {
            APP_DBG_MSG("   - Pairing Success\n");
          }
          APP_DBG_MSG("\n");

          /* USER CODE BEGIN ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE*/

          /* USER CODE END ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE*/
          break;
      }
      case ACI_GAP_BOND_LOST_VSEVT_CODE:
      {
          APP_DBG_MSG("&gt;&gt;== ACI_GAP_BOND_LOST_EVENT\n");
          ret = aci_gap_allow_rebond(bleAppContext.BleApplicationContext_legacy.connectionHandle);
          if (ret != BLE_STATUS_SUCCESS)
          {
            APP_DBG_MSG("==&gt;&gt; aci_gap_allow_rebond : Fail, reason: 0x%02X\n", ret);
          }
          else
          {
            APP_DBG_MSG("==&gt;&gt; aci_gap_allow_rebond : Success\n");
          }
          /* USER CODE BEGIN ACI_GAP_BOND_LOST_VSEVT_CODE*/

          /* USER CODE END ACI_GAP_BOND_LOST_VSEVT_CODE*/
          break;
      }
      /* USER CODE BEGIN EVT_VENDOR_1 */

      /* USER CODE END EVT_VENDOR_1 */
      break; /* HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE */
      }
    }
      /* USER CODE BEGIN EVENT_PCKT */

      /* USER CODE END EVENT_PCKT */

    default:
      /* USER CODE BEGIN ECODE_DEFAULT*/

      /* USER CODE END ECODE_DEFAULT*/
      break;
}

return (SVCCTL_UserEvtFlowEnable);
}</code></pre>

<p>&nbsp;</p>

<p>/*获取蓝牙服务连接状态*/</p>

<p>APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status(void)</p>

<p>{&nbsp;</p>

<p>&nbsp; return bleAppContext.Device_Connection_Status;</p>

<p>}</p>

<p>/***************************处理常用gap*********************************************/</p>

<pre>
<code>void APP_BLE_Procedure_Gap_General(ProcGapGeneralId_t ProcGapGeneralId)
{
tBleStatus status;
uint8_t phy_tx, phy_rx;

switch(ProcGapGeneralId)
{
    case PROC_GAP_GEN_PHY_TOGGLE:
    {
      status = hci_le_read_phy(bleAppContext.BleApplicationContext_legacy.connectionHandle, &amp;phy_tx, &amp;phy_rx);
      if (status != BLE_STATUS_SUCCESS)
      {
      APP_DBG_MSG("hci_le_read_phy failure: reason=0x%02X\n",status);
      }
      else
      {
      APP_DBG_MSG("==&gt;&gt; hci_le_read_phy - Success\n");
      APP_DBG_MSG("==&gt;&gt; PHY ParamTX= %d, RX= %d\n", phy_tx, phy_rx);
      if ((phy_tx == HCI_TX_PHY_LE_2M) &amp;&amp; (phy_rx == HCI_RX_PHY_LE_2M))
      {
          APP_DBG_MSG("==&gt;&gt; hci_le_set_phy PHY ParamTX= %d, RX= %d - ", HCI_TX_PHY_LE_1M, HCI_RX_PHY_LE_1M);
          status = hci_le_set_phy(bleAppContext.BleApplicationContext_legacy.connectionHandle, 0, HCI_TX_PHYS_LE_1M_PREF, HCI_RX_PHYS_LE_1M_PREF, 0);
          if (status != BLE_STATUS_SUCCESS)
          {
            APP_DBG_MSG("Fail\n");
          }
          else
          {
            APP_DBG_MSG("Success\n");
            gap_cmd_resp_wait();/* waiting for HCI_LE_PHY_UPDATE_COMPLETE_SUBEVT_CODE */
          }
      }
      else
      {
          APP_DBG_MSG("==&gt;&gt; hci_le_set_phy PHY ParamTX= %d, RX= %d - ", HCI_TX_PHYS_LE_2M_PREF, HCI_RX_PHYS_LE_2M_PREF);
          status = hci_le_set_phy(bleAppContext.BleApplicationContext_legacy.connectionHandle, 0, HCI_TX_PHYS_LE_2M_PREF, HCI_RX_PHYS_LE_2M_PREF, 0);
          if (status != BLE_STATUS_SUCCESS)
          {
            APP_DBG_MSG("Fail\n");
          }
          else
          {
            APP_DBG_MSG("Success\n");
            gap_cmd_resp_wait();/* waiting for HCI_LE_PHY_UPDATE_COMPLETE_SUBEVT_CODE */
          }
      }
      }
      break;
    }/* PROC_GAP_GEN_PHY_TOGGLE */
    case PROC_GAP_GEN_CONN_TERMINATE:
    {
      status = aci_gap_terminate(bleAppContext.BleApplicationContext_legacy.connectionHandle, HCI_REMOTE_USER_TERMINATED_CONNECTION_ERR_CODE);
      if (status != BLE_STATUS_SUCCESS)
      {
         APP_DBG_MSG("aci_gap_terminate failure: reason=0x%02X\n", status);
      }
      else
      {
      APP_DBG_MSG("==&gt;&gt; aci_gap_terminate : Success\n");
      }
      gap_cmd_resp_wait();/* waiting for HCI_DISCONNECTION_COMPLETE_EVT_CODE */
      break;
    }/* PROC_GAP_GEN_CONN_TERMINATE */
    case PROC_GATT_EXCHANGE_CONFIG:
    {
      status = aci_gatt_exchange_config(bleAppContext.BleApplicationContext_legacy.connectionHandle);
      if (status != BLE_STATUS_SUCCESS)
      {
      APP_DBG_MSG("aci_gatt_exchange_config failure: reason=0x%02X\n", status);
      }
      else
      {
      APP_DBG_MSG("==&gt;&gt; aci_gatt_exchange_config : Success\n");
      }
      break;
    }
    /* USER CODE BEGIN GAP_GENERAL */

    /* USER CODE END GAP_GENERAL */
    default:
      break;
}
return;
}</code></pre>

<p>&nbsp;</p>

<p>/*处理gap设备*/</p>

<pre>
<code>void APP_BLE_Procedure_Gap_Peripheral(ProcGapPeripheralId_t ProcGapPeripheralId)
{
tBleStatus status;
uint32_t paramA = ADV_INTERVAL_MIN;
uint32_t paramB = ADV_INTERVAL_MAX;
uint32_t paramC, paramD;

/* First set parameters before calling ACI APIs, only if needed */
switch(ProcGapPeripheralId)
{
    case PROC_GAP_PERIPH_ADVERTISE_START_FAST:
    {
      paramA = ADV_INTERVAL_MIN;
      paramB = ADV_INTERVAL_MAX;
      paramC = APP_BLE_ADV_FAST;

      break;
    }/* PROC_GAP_PERIPH_ADVERTISE_START_FAST */
    case PROC_GAP_PERIPH_ADVERTISE_START_LP:
    {
      paramA = ADV_LP_INTERVAL_MIN;
      paramB = ADV_LP_INTERVAL_MAX;
      paramC = APP_BLE_ADV_LP;

      break;
    }/* PROC_GAP_PERIPH_ADVERTISE_START_LP */
    case PROC_GAP_PERIPH_ADVERTISE_STOP:
    {
      paramC = APP_BLE_IDLE;

      break;
    }/* PROC_GAP_PERIPH_ADVERTISE_STOP */
    case PROC_GAP_PERIPH_CONN_PARAM_UPDATE:
    {
      paramA = CONN_INT_MS(1000);
      paramB = CONN_INT_MS(1000);
      paramC = 0x0000;
      paramD = 0x01F4;

      /* USER CODE BEGIN CONN_PARAM_UPDATE */
      if (bleAppContext.connIntervalFlag != 0)
      {
      bleAppContext.connIntervalFlag = 0;
      paramA = CONN_INT_MS(50);
      paramB = CONN_INT_MS(50);
      }
      else
      {
      bleAppContext.connIntervalFlag = 1;
      paramA = CONN_INT_MS(1000);
      paramB = CONN_INT_MS(1000);
      }
      /* USER CODE END CONN_PARAM_UPDATE */
      break;
    }/* PROC_GAP_PERIPH_CONN_PARAM_UPDATE */
    default:
      break;
}

/* Call ACI APIs */
switch(ProcGapPeripheralId)
{
    case PROC_GAP_PERIPH_ADVERTISE_START_FAST:
    case PROC_GAP_PERIPH_ADVERTISE_START_LP:
    {
      /* Start Fast or Low Power Advertising */
      status = aci_gap_set_discoverable(ADV_TYPE,
                                        paramA,
                                        paramB,
                                        CFG_BD_ADDRESS_TYPE,
                                        ADV_FILTER,
                                        0, 0, 0, 0, 0, 0);
      if (status != BLE_STATUS_SUCCESS)
      {
      APP_DBG_MSG("==&gt;&gt; aci_gap_set_discoverable - fail, result: 0x%02X\n", status);
      }
      else
      {
      bleAppContext.Device_Connection_Status = (APP_BLE_ConnStatus_t)paramC;
      APP_DBG_MSG("==&gt;&gt; aci_gap_set_discoverable - Success\n");
      }

      status = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL);
      if (status != BLE_STATUS_SUCCESS)
      {
      APP_DBG_MSG("==&gt;&gt; delete tx power level - fail, result: 0x%02X\n", status);
      }

      /* Update Advertising data */
      status = aci_gap_update_adv_data(sizeof(a_AdvData), (uint8_t*) a_AdvData);
      if (status != BLE_STATUS_SUCCESS)
      {
      APP_DBG_MSG("==&gt;&gt; Start Advertising Failed, result: 0x%02X\n", status);
      }
      else
      {
      APP_DBG_MSG("==&gt;&gt; Success: Start Advertising\n");
      }
      break;
    }
    case PROC_GAP_PERIPH_ADVERTISE_STOP:
    {
      status = aci_gap_set_non_discoverable();
      if (status != BLE_STATUS_SUCCESS)
      {
      bleAppContext.Device_Connection_Status = (APP_BLE_ConnStatus_t)paramC;
      APP_DBG_MSG("aci_gap_set_non_discoverable - fail, result: 0x%02X\n",status);
      }
      else
      {
      APP_DBG_MSG("==&gt;&gt; aci_gap_set_non_discoverable - Success\n");
      }
      break;
    }/* PROC_GAP_PERIPH_ADVERTISE_STOP */
    case PROC_GAP_PERIPH_ADVERTISE_DATA_UPDATE:
    {
      status = aci_gap_update_adv_data(sizeof(a_AdvData), (uint8_t*) a_AdvData);
      if (status != BLE_STATUS_SUCCESS)
      {
      APP_DBG_MSG("aci_gap_update_adv_data - fail, result: 0x%02X\n",status);
      }
      else
      {
      APP_DBG_MSG("==&gt;&gt; aci_gap_update_adv_data - Success\n");
      }

      break;
    }/* PROC_GAP_PERIPH_ADVERTISE_DATA_UPDATE */
    case PROC_GAP_PERIPH_CONN_PARAM_UPDATE:
    {
       status = aci_l2cap_connection_parameter_update_req(
                                                       bleAppContext.BleApplicationContext_legacy.connectionHandle,
                                                       paramA,
                                                       paramB,
                                                       paramC,
                                                       paramD);
      if (status != BLE_STATUS_SUCCESS)
      {
      APP_DBG_MSG("aci_l2cap_connection_parameter_update_req - fail, result: 0x%02X\n",status);
      }
      else
      {
      APP_DBG_MSG("==&gt;&gt; aci_l2cap_connection_parameter_update_req - Success\n");
      }

      break;
    }/* PROC_GAP_PERIPH_CONN_PARAM_UPDATE */

    case PROC_GAP_PERIPH_SET_BROADCAST_MODE:
    {

      break;
    }/* PROC_GAP_PERIPH_SET_BROADCAST_MODE */
    default:
      break;
}
return;
}</code></pre>

<p>&nbsp;</p>

<p>/* 一些本文件调用的内部函数*/</p>

<p>/* 由<strong>APP_BLE_Init</strong><strong>调用</strong>*/</p>

<p>uint8_t HOST_BLE_Init(void)</p>

<p>/* 由<strong>APP_BLE_Init</strong><strong>调用</strong>*/</p>

<p>static void Ble_Hci_Gap_Gatt_Init(void)</p>

<p>static void Ble_UserEvtRx( void)</p>

<p>const uint8_t* BleGetBdAddress(void)</p>

<p>static void BleStack_Process_BG(void)</p>

<p>static void gap_cmd_resp_release(void)</p>

<p>static void gap_cmd_resp_wait(void)</p>

<p>/*通知LL恢复流程*/</p>

<p>static void BLE_ResumeFlowProcessCallback(void)</p>

<p>static void BLE_NvmCallback (SNVMA_Callback_Status_t CbkStatus)</p>

<p>static void Adv_Cancel_Req(void *arg)</p>

<p>static void Switch_OFF_GPIO(void *arg)</p>

<p>static void Adv_Cancel(void)</p>

<p>static void fill_advData(uint8_t *p_adv_data, uint8_t tab_size, const uint8_t* p_bd_addr)</p>

<p>/* 蓝牙回调指示函数 */</p>

<p>tBleStatus BLECB_Indication( const uint8_t* data,</p>

<p>uint16_t length,</p>

<p>const uint8_t* ext_data,</p>

<p>uint16_t ext_length )</p>

<p>/*按键响应函数*/</p>

<p>void APPE_Button1Action(void)</p>

<p>void APPE_Button2Action(void)</p>

<p>void APPE_Button3Action(void)</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:22px;">p2p_server.c 和p2p_server_app.c</span></strong><strong><span style="font-size:22px;">&nbsp; &nbsp;</span></strong>实现p2p_server的具体蓝牙功能</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:20px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;p2p_server.c&nbsp;&nbsp;</span></strong></p>

<p>中的函数主要有以下几个,在p2p_server_app.c中调用</p>

<p>/*Event handler 事件处理*/</p>

<p><strong>static</strong> SVCCTL_EvtAckStatus_t <strong>P2P_SERVER_EventHandler</strong>(<strong>void</strong> *p_Event)</p>

<p>/*Service initialization服务初始化*/</p>

<p><strong>void</strong> <strong>P2P_SERVER_Init</strong>(<strong>void</strong>)</p>

<p>/*Characteristic update特征值update*/</p>

<p>tBleStatus <strong>P2P_SERVER_UpdateValue</strong>(P2P_SERVER_CharOpcode_t CharOpcode, P2P_SERVER_Data_t *pData)</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:22px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p2p_server_app.c</span></strong></p>

<p>/*Led和按键结构*/</p>

<p><strong>typedef</strong> <strong>struct</strong>{</p>

<p>&nbsp; &nbsp; uint8_t Device_Led_Selection;</p>

<p>&nbsp; &nbsp; uint8_t Led1;</p>

<p>}P2P_LedCharValue_t;</p>

<p><strong>typedef</strong> <strong>struct</strong>{</p>

<p>&nbsp; &nbsp; uint8_t Device_Button_Selection;</p>

<p>&nbsp; &nbsp; uint8_t ButtonStatus;</p>

<p>}P2P_ButtonCharValue_t;</p>

<p>/*按键发送信息结构*/</p>

<p><strong>typedef</strong> <strong>enum</strong></p>

<p>{</p>

<p><em>&nbsp; &nbsp; Switch_c_NOTIFICATION_OFF</em>,</p>

<p><em>&nbsp; &nbsp; Switch_c_NOTIFICATION_ON</em>,</p>

<p><em>&nbsp; &nbsp; P2P_SERVER_APP_SENDINFORMATION_LAST</em></p>

<p>} P2P_SERVER_APP_SendInformation_t;</p>

<p>/*P2P_SERVER_APP上下文结构*/</p>

<p><strong>typedef</strong> <strong>struct</strong></p>

<p>{</p>

<p>&nbsp; &nbsp; P2P_SERVER_APP_SendInformation_t Switch_c_Notification_Status;</p>

<p>&nbsp; &nbsp; /* USER CODE BEGIN Service1_APP_Context_t */</p>

<p>&nbsp; &nbsp; P2P_LedCharValue_t LedControl;</p>

<p>&nbsp; &nbsp; P2P_ButtonCharValue_t ButtonControl;</p>

<p>&nbsp; &nbsp; /* USER CODE END Service1_APP_Context_t */</p>

<p>&nbsp; &nbsp; uint16_t ConnectionHandle;</p>

<p>} P2P_SERVER_APP_Context_t;</p>

<p>&nbsp;</p>

<p>/*<strong>void</strong> <strong>P2P_SERVER_Notification</strong>(P2P_SERVER_NotificationEvt_t *p_Notification)&nbsp; &nbsp; Notify 服务事件处理*/</p>

<pre>
<code>void P2P_SERVER_Notification(P2P_SERVER_NotificationEvt_t *p_Notification)
{
    /* USER CODE BEGIN Service1_Notification_1 */
    /* USER CODE END Service1_Notification_1 */
    switch(p_Notification-&gt;EvtOpcode)
    {
    /* USER CODE BEGIN Service1_Notification_Service1_EvtOpcode */
    /* USER CODE END Service1_Notification_Service1_EvtOpcode */
    case P2P_SERVER_LED_C_READ_EVT:
      /* USER CODE BEGIN Service1Char1_READ_EVT */
      /* USER CODE END Service1Char1_READ_EVT */
    break;
    case P2P_SERVER_LED_C_WRITE_NO_RESP_EVT:
      /* USER CODE BEGIN Service1Char1_WRITE_NO_RESP_EVT */
      if(p_Notification-&gt;DataTransfered.p_Payload == 0x01)
      {
      BSP_LED_On(LED_BLUE);
      APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 ON\n");
      P2P_SERVER_APP_Context.LedControl.Led1 = 0x01; /* LED1 ON */
      }
      if(p_Notification-&gt;DataTransfered.p_Payload == 0x00)
      {
      BSP_LED_Off(LED_BLUE);
      APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 OFF\n");
      P2P_SERVER_APP_Context.LedControl.Led1 = 0x00; /* LED1 OFF */
      }
      /* USER CODE END Service1Char1_WRITE_NO_RESP_EVT */
    break;
    case P2P_SERVER_SWITCH_C_NOTIFY_ENABLED_EVT:
      /* USER CODE BEGIN Service1Char2_NOTIFY_ENABLED_EVT */
      P2P_SERVER_APP_Context.Switch_c_Notification_Status = Switch_c_NOTIFICATION_ON;
      APP_DBG_MSG("-- P2P APPLICATION SERVER : NOTIFICATION ENABLED\n");
      APP_DBG_MSG(" \n\r");
      /* USER CODE END Service1Char2_NOTIFY_ENABLED_EVT */
    break;
    case P2P_SERVER_SWITCH_C_NOTIFY_DISABLED_EVT:
      /* USER CODE BEGIN Service1Char2_NOTIFY_DISABLED_EVT */
      P2P_SERVER_APP_Context.Switch_c_Notification_Status = Switch_c_NOTIFICATION_OFF;
      APP_DBG_MSG("-- P2P APPLICATION SERVER : NOTIFICATION DISABLED\n");
      APP_DBG_MSG(" \n\r");
      /* USER CODE END Service1Char2_NOTIFY_DISABLED_EVT */
    break;
    default:
    /* USER CODE BEGIN Service1_Notification_default */
    /* USER CODE END Service1_Notification_default */
    break;
}
/* USER CODE BEGIN Service1_Notification_2 */
/* USER CODE END Service1_Notification_2 */
return;
}</code></pre>

<p>/*<strong>void</strong> <strong>P2P_SERVER_APP_EvtRx</strong>(P2P_SERVER_APP_ConnHandleNotEvt_t *p_Notification) Notify事件接收 连接 断开事件*/</p>

<pre>
<code>void P2P_SERVER_APP_EvtRx(P2P_SERVER_APP_ConnHandleNotEvt_t *p_Notification)
{
/* USER CODE BEGIN Service1_APP_EvtRx_1 */
/* USER CODE END Service1_APP_EvtRx_1 */
switch(p_Notification-&gt;EvtOpcode)
{
    /* USER CODE BEGIN Service1_APP_EvtRx_Service1_EvtOpcode */
    /* USER CODE END Service1_APP_EvtRx_Service1_EvtOpcode */
    case P2P_SERVER_CONN_HANDLE_EVT :
      /* USER CODE BEGIN Service1_APP_CONN_HANDLE_EVT */
      /* USER CODE END Service1_APP_CONN_HANDLE_EVT */
    break;
    case P2P_SERVER_DISCON_HANDLE_EVT :
      /* USER CODE BEGIN Service1_APP_DISCON_HANDLE_EVT */
      P2P_SERVER_APP_LED_BUTTON_context_Init();
      /* USER CODE END Service1_APP_DISCON_HANDLE_EVT */
    break;
    default:
      /* USER CODE BEGIN Service1_APP_EvtRx_default */
      /* USER CODE END Service1_APP_EvtRx_default */
    break;
}
/* USER CODE BEGIN Service1_APP_EvtRx_2 */
/* USER CODE END Service1_APP_EvtRx_2 */
return;
}</code></pre>

<p><strong>/*void</strong> <strong>P2P_SERVER_APP_Init</strong>(<strong>void</strong>)*/</p>

<pre>
<code class="language-cpp">void P2P_SERVER_APP_Init(void)
{
UNUSED(P2P_SERVER_APP_Context);
P2P_SERVER_Init();
/* USER CODE BEGIN Service1_APP_Init */
UTIL_SEQ_RegTask( 1U &lt;&lt; CFG_TASK_SEND_NOTIF_ID, UTIL_SEQ_RFU,      P2P_SERVER_Switch_c_SendNotification);
/**
* Initialize LedButton Service
*/
P2P_SERVER_APP_Context.Switch_c_Notification_Status= Switch_c_NOTIFICATION_OFF;
P2P_SERVER_APP_LED_BUTTON_context_Init();
/* USER CODE END Service1_APP_Init */
return;
}</code></pre>

<p>&nbsp;</p>

<p>/*void P2P_SERVER_APP_LED_BUTTON_context_Init(void) led button初始化*/</p>

<pre>
<code class="language-cpp">void P2P_SERVER_APP_LED_BUTTON_context_Init(void)
{
BSP_LED_Off(LED_BLUE);
P2P_SERVER_APP_Context.LedControl.Device_Led_Selection=0x01; /* Device1 */
P2P_SERVER_APP_Context.LedControl.Led1=0x00; /* led OFF */
P2P_SERVER_APP_Context.ButtonControl.Device_Button_Selection=0x01;/* Device1 */
P2P_SERVER_APP_Context.ButtonControl.ButtonStatus=0x00;
return;
}</code></pre>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>/*<strong>P2P_SERVER_Switch_c_SendNotification&nbsp; &nbsp;根据switch按键状态发送notifiy</strong>*/</p>

<pre>
<code>__USED void P2P_SERVER_Switch_c_SendNotification(void) /* Property Notification */
{
P2P_SERVER_APP_SendInformation_t notification_on_off = Switch_c_NOTIFICATION_OFF;
P2P_SERVER_Data_t p2p_server_notification_data;
p2p_server_notification_data.p_Payload = (uint8_t*)a_P2P_SERVER_UpdateCharData;
p2p_server_notification_data.Length = 0;
/* USER CODE BEGIN Service1Char2_NS_1*/
if(P2P_SERVER_APP_Context.ButtonControl.ButtonStatus == 0x00)
{
    P2P_SERVER_APP_Context.ButtonControl.ButtonStatus = 0x01;
}
else
{
    P2P_SERVER_APP_Context.ButtonControl.ButtonStatus = 0x00;
}
a_P2P_SERVER_UpdateCharData = 0x01; /* Device Led selection */
a_P2P_SERVER_UpdateCharData = P2P_SERVER_APP_Context.ButtonControl.ButtonStatus;
/* Update notification data length */
p2p_server_notification_data.Length = (p2p_server_notification_data.Length) + 2;
if(P2P_SERVER_APP_Context.Switch_c_Notification_Status == Switch_c_NOTIFICATION_ON)
{
    APP_DBG_MSG("-- P2P APPLICATION SERVER : INFORM CLIENT BUTTON 1 PUSHED\n");
    notification_on_off = Switch_c_NOTIFICATION_ON;
}
else
{
    APP_DBG_MSG("-- P2P APPLICATION SERVER : CAN'T INFORM CLIENT - NOTIFICATION DISABLED\n");
}
/* USER CODE END Service1Char2_NS_1*/
if (notification_on_off != Switch_c_NOTIFICATION_OFF)
{
    P2P_SERVER_UpdateValue(P2P_SERVER_SWITCH_C, &amp;p2p_server_notification_data);
}
return;
}</code></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size:18px;"><span style="color:#2c3e50;">总结:</span></span></p>

<p>&nbsp;<strong><span style="color:#2ecc71;">app_ble.c主要干的是各种初始化和gap事件处理:下面三个函数我们可以重点关注。</span></strong></p>

<p>&nbsp;<span style="color:#2980b9;">void APP_BLE_Init(void)</span></p>

<p><span style="color:#2980b9;">&nbsp;SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void *p_Pckt)</span></p>

<p><span style="color:#2980b9;">&nbsp;tBleStatus BLECB_Indication( const uint8_t* data,uint16_t length,const uint8_t* ext_data,uint16_t ext_length )</span></p>

<p>&nbsp;</p>

<p><span style="color:#8e44ad;">&nbsp;p2p_server.c&nbsp; 和p2p_server_app.c对于gatt/att</span></p>

<p>&nbsp;</p>

<p><strong>&nbsp;</strong><span style="color:#2ecc71;">p2p_server.c&nbsp; 中主要实现下面三个函数,在p2p_server_app.c中调用:</span></p>

<p>&nbsp;<span style="color:#2980b9;">static SVCCTL_EvtAckStatus_t P2P_SERVER_EventHandler(void *p_Event)</span></p>

<p><span style="color:#2980b9;">&nbsp;void P2P_SERVER_Init(void)</span></p>

<p><span style="color:#2980b9;">&nbsp;tBleStatus P2P_SERVER_UpdateValue(P2P_SERVER_CharOpcode_t CharOpcode, P2P_SERVER_Data_t *pData) </span></p>

<p>&nbsp;</p>

<p>&nbsp;<span style="color:#2ecc71;">p2p_server_app.c中实现gatt/att具体功能,我们应该重点关注,也是具体应用最相关的东西。</span></p>

<p>&nbsp;</p>

<p><span style="color:#2ecc71;">期间我们也应该熟悉<span style="white-space: pre">UTIL_SEQ任务管理的一些概念和使用方法。</span></span></p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 谢谢</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>
页: [1]
查看完整版本: 【stm32wba】+10 stm32wba低功耗蓝牙软件app部分分析之三