关于主机的程序框架其实和从机都是一样的,都是基于事件驱动的框架,main函数中完成初始化,从机的话就启动广播,主机就启动扫描,之后都是基于事件的驱动方式将

ble相关事件返回给上层APP,并且再通过ble_evt_dispatch函数将事件分发给各个处理函数

Android 蓝牙主设备和从设备两种模式下的开发流程_服务端

Android 蓝牙主设备和从设备两种模式下的开发流程_服务端_02

 

 

蓝牙的使用无非就是进行数据通信,从机通常都是作为服务端,而主机通常都是作为客户端,从机和主机的概念是针对链路层来说的,而客户端和服务端是针对GATT层来说的

之前的教程中从机例子中都是作为服务端的,我们发送数据给手机时都是使用notify方式或者indication方式并通过sd_ble_gatts_hvx函数发送。

 

而这里主机例子作为客户端,客户端不仅可以发送数据给服务端,也可以从服务端读取数据使用有读写函数

Android 蓝牙主设备和从设备两种模式下的开发流程_客户端_03

下面来分析sdk中的主从通信demo是如何建立连接并通信的

1.主机怎么判断哪个从机是我要连接的哪个设备?

2.如何实现连接多个设备?

3.因为连接上后 从机上按键时会通过notify发送数据给主机,所以主机要先使能从机上的notify功能,具体就是写从机上的CCCD描述符,该功能如何实现?

4.连接上后如何通信?

 

下面首先解决第一个问题:主机怎么判断哪个从机是我要连接的设备。

在主机工程当初始化完成后就会调用scan_start()开始监听BLE广播,没当监听到BLE广播时协议栈就会给上层广播事件,该事件有ble_evt_dispatch派发给函数递交给on_ble_central_evt函数。

Android 蓝牙主设备和从设备两种模式下的开发流程_初始化_04

 

Android 蓝牙主设备和从设备两种模式下的开发流程_初始化_05

主机连接有两种方式:1.寻找设备名配对,2.寻找UUID配对,从广播的数据中寻找设备名,是否找到要配对的设备名,名字可以完整的也可以是短名字形式,所以这里找不到完整的就找短名字形式,找到了就发起连接。

 

第二个问题:如何实现连接多个设备?

在蓝牙连接上后会对主机个数判断,如果达到最大连接个数就停止扫描,没达到就继续扫描

/** Update LEDs status, and check if we should be looking for more
              *  peripherals to connect to. */
             ///LEDS_ON(CENTRAL_CONNECTED_LED);判断是否最大连接数,没有继续扫描
             if (ble_conn_state_n_centrals() == CENTRAL_LINK_COUNT)
             {
                /// LEDS_OFF(CENTRAL_SCANNING_LED);
             
             }
             else
             {
                 // Resume scanning.
               ///  LEDS_ON(CENTRAL_SCANNING_LED);
                 scan_start();
             }

device_manager_event_handler函数并不是由函数ble_evt_dispatch调用,而是派发函数ble_evt_dispatch先调用了dm_ble_evt_handler(p_ble_evt),而该函数内部会调用device_manager_event_handler函数关系链如下,main中首先调用了device_manager_init()初始化函数,该初始化函数会将device_manager_event_handler函数设置回调函数,当连接完成或ble_evt_dispatch函数将连接事件派发给dm_ble_evt_handler函数,来最终处理关于连接事件的后续工作,