一、背景

链路层(LL) 控制设备的射频状态,有五个设备状态:待机、广播、扫描、初始化和连接。

广播 为广播数据包,而 扫描 则是监听广播。

GAP通信中角色,中心设备(Central - 主机) 用来扫描和连接 外围设备(Peripheral - 从机)

二、配置连接参数

定义连接的参数,这个参数将在sd_ble_gap_connect()函数中被调用。

// 定义连接参数
static ble_gap_conn_params_t m_conn_params =
{.min_conn_interval  = MSEC_TO_UNITS(NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL, UNIT_1_25_MS),  // 最小连接间隔7.5ms.max_conn_interval  = MSEC_TO_UNITS(NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL, UNIT_1_25_MS),  // 最大连接间隔30ms  .slave_latency      = NRF_BLE_SCAN_SLAVE_LATENCY,                                         // 隐藏周期0 .conn_sup_timeout   = MSEC_TO_UNITS(NRF_BLE_SCAN_SUPERVISION_TIMEOUT, UNIT_10_MS),        // 超时时间4000ms
};
12345678

三、连接相关函数

3.1 nrf_ble_scan_stop

配置好准备连接的设备的MAC信息,在发起连接之前,我们一定要先调用nrf_ble_scan_stop()函数去停止扫描,不然会出错。

停止扫描之后,我们调用sd_ble_gap_connect()函数,发起对从机设备的连接。

3.2 sd_ble_gap_connect

3.3 sd_ble_gap_disconnect

调用该方法就可以主动断开蓝牙的连接
sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);

四、发起连接

在扫描回调事件处理的函数中,前面一部分就是获取扫描到的从机设备的信息。

我们对扫描到的从机设备的RSSI进行了判断,我们人为定义,当设备的RSSI大于-30dBm的时候,也就是信号强度非常好,我们就默认连接该设备。

首先,我们先定义准备连接的从机设备的地址和信息,配置m_addr.addr_type为BLE_GAP_ADDR_TYPE_RANDOM_STATIC,配置m_addr.addr为扫描到的设备地址p_scan_evt->params.p_not_found->peer_addr.addr。

配置好准备连接的设备的MAC信息,在发起连接之前,我们一定要先调用nrf_ble_scan_stop()函数去停止扫描,不然会出错。

停止扫描之后,我们调用sd_ble_gap_connect()函数,发起对从机设备的连接。

char *Util_convertBdAddr2Str(uint8_t *pAddr)
{uint8_t     charCnt;char        hex[] = "0123456789ABCDEF";static char str[(2*B_ADDR_LEN)+3];char        *pStr = str;*pStr++ = '0';*pStr++ = 'x';// Start from end of addrpAddr += B_ADDR_LEN;for (charCnt = B_ADDR_LEN; charCnt > 0; charCnt--){*pStr++ = hex[*--pAddr >> 4];*pStr++ = hex[*pAddr & 0x0F];}*pStr = NULL;return str;
}//******************************************************************
// fn : scan_evt_handler
//
// brief : 处理扫描回调事件
//
// param : scan_evt_t  扫描事件结构体
//
// return : none
static void scan_evt_handler(scan_evt_t const * p_scan_evt)
{switch(p_scan_evt->scan_evt_id){// 未过滤的扫描数据case NRF_BLE_SCAN_EVT_NOT_FOUND:{// 判断是否为扫描回调数据if(p_scan_evt->params.p_not_found->type.scan_response){if(p_scan_evt->params.p_not_found->data.len)    // 存在扫描回调数据{NRF_LOG_INFO("scan data:  %s",Util_convertHex2Str(p_scan_evt->params.p_not_found->data.p_data,p_scan_evt->params.p_not_found->data.len));}else{NRF_LOG_INFO("scan data:  %s","NONE");}NRF_LOG_INFO("rssi:  %ddBm",p_scan_evt->params.p_not_found->rssi);}else  // 否则为广播数据{// 打印扫描的设备MACNRF_LOG_INFO("Device MAC:  %s",Util_convertBdAddr2Str((uint8_t*)p_scan_evt->params.p_not_found->peer_addr.addr));if(p_scan_evt->params.p_not_found->data.len)    // 存在广播数据{NRF_LOG_INFO("adv data:  %s",Util_convertHex2Str(p_scan_evt->params.p_not_found->data.p_data,p_scan_evt->params.p_not_found->data.len));}else{NRF_LOG_INFO("adv data:  %s","NONE");}}// 如果扫描到的设备信号强度大于-30dBmif(p_scan_evt->params.p_not_found->rssi > (-30)){ret_code_t          err_code;// 配置准备连接的设备MACble_gap_addr_t m_addr;m_addr.addr_id_peer = 1;m_addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC;memcpy(m_addr.addr,p_scan_evt->params.p_not_found->peer_addr.addr,BLE_GAP_ADDR_LEN);// 停止扫描nrf_ble_scan_stop();// 发起连接err_code = sd_ble_gap_connect(&m_addr,&m_scan_params,&m_conn_params,APP_BLE_CONN_CFG_TAG);APP_ERROR_CHECK(err_code);}} break;default:break;}
}
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798

五、连接事件处理

当我们的主机设备进行连接,或者断开连接的时候,BLE的事件回调中,都会给我们状态事件提示。

连接成功的状态 BLE_GAP_EVT_CONNECTED,我们可以在这边获取到连接的设备的MAC、连接参数等等。

断开连接的状态 BLE_GAP_EVT_DISCONNECTED,我们可以获取到断开的连接的原因等等。

BLE_GAP_EVT_TIMEOUT GAP连接超时事件。当主从机连接一直不成功,超过了连接事件最大的时间,则协议栈触发GAP连接超时事件。这个连接最大的事件就是GAP中的监督超时时间(连接超时时间)。

BLE_GATT_EVT_TIMEOUT 主机GATT连接超时事件。本质上不属于连接时发生的事情,而是连接中发生的事情。当正在连接的主从机由于某种原因发生断开,主机设备发起多次连接请求没有回应就会发生GATT连接超时事件。协议栈将禁用所有ATT流量并将ATT连接标记为down,但是由应用程序必须主动的使用sd_ble_gap_disconnect()完成最后的断开连接。

char *Util_convertBdAddr2Str(uint8_t *pAddr)
{uint8_t     charCnt;char        hex[] = "0123456789ABCDEF";static char str[(2*B_ADDR_LEN)+3];char        *pStr = str;*pStr++ = '0';*pStr++ = 'x';// Start from end of addrpAddr += B_ADDR_LEN;for (charCnt = B_ADDR_LEN; charCnt > 0; charCnt--){*pStr++ = hex[*--pAddr >> 4];*pStr++ = hex[*pAddr & 0x0F];}*pStr = NULL;return str;
}//******************************************************************
// fn : ble_evt_handler
//
// brief : BLE事件回调
// details : 包含以下几种事件类型:COMMON、GAP、GATT Client、GATT Server、L2CAP
//
// param : ble_evt_t  事件类型
//         p_context  未使用
//
// return : none
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;ble_gap_evt_connected_t const * p_connected_evt = &p_gap_evt->params.connected;switch (p_ble_evt->header.evt_id){// 连接case BLE_GAP_EVT_CONNECTED:NRF_LOG_INFO("Connected. conn_DevAddr: %s\nConnected. conn_handle: 0x%04x\nConnected. conn_Param: %d,%d,%d,%d",Util_convertBdAddr2Str((uint8_t*)p_connected_evt->peer_addr.addr),p_gap_evt->conn_handle,p_connected_evt->conn_params.min_conn_interval,p_connected_evt->conn_params.max_conn_interval,p_connected_evt->conn_params.slave_latency,p_connected_evt->conn_params.conn_sup_timeout);break;// 断开连接case BLE_GAP_EVT_DISCONNECTED:NRF_LOG_INFO("Disconnected. conn_handle: 0x%x, reason: 0x%04x",p_gap_evt->conn_handle,p_gap_evt->params.disconnected.reason);// 如果需要异常断开重连,可以打开下面的注释// scan_start();  // 重新开始扫描break;case BLE_GAP_EVT_TIMEOUT:{                    // We have not specified a timeout for scanning, so only connection attemps can timeout.if(p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN){NRF_LOG_DEBUG("Connection request timed out.");}err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);// Start scanningscan_start();} break;case BLE_GATTC_EVT_TIMEOUT:{NRF_LOG_INFO("{0x%x BLE_GATTC_EVT_TIMEOUT}", p_gap_evt->conn_handle);// Disconnect on GATT Client timeout event.err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);APP_ERROR_CHECK(err_code);scan_start();} break;default:break;}
}
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889

NRF52832学习笔记(23)——GAP主机端连接相关推荐

  1. nrf52832 学习笔记(四)蓝牙主机扫描

    nrf52832 学习笔记(四)蓝牙主机扫描 从机发出广播后就需要主机进行扫描了,主机扫描之前和从机一样,也需要协议栈初始化.GAP初始化.GATT初始化,这些和从机类似,参考 nrf52832 学习 ...

  2. nrf52832 学习笔记(九)蓝牙主机发现服务

    nrf52832 学习笔记(九)蓝牙主机发现服务 服务发现流程 数据如同下表一样存储在服务端,客户端首先要获取表中的Handle和Type列,从而知道服务端中存在哪些数据,以便后面读.写.通知等操作. ...

  3. nrf52832 学习笔记(五)蓝牙主从机连接和连接参数更新

    nrf52832 学习笔记(五)蓝牙主从机连接和连接参数更新 主机连接 nrf52832 SDK中主机连接从机需要使用 sd_ble_gap_connect(ble_gap_addr_t const ...

  4. nrf52832 学习笔记(三)蓝牙从机广播

    nrf52832 学习笔记(三)蓝牙从机广播 蓝牙从机要想被主机连接,首先需要发送广播信息,周围主机通过扫描广播信号,根据从机的广播信息,判断是否连接. 蓝牙协议栈初始化 不管是主机还是从机,要想使用 ...

  5. nrf52832 学习笔记(六)配对和绑定

    nrf52832 学习笔记(六)配对和绑定 配对绑定推荐博客低功耗蓝牙配对绑定解读和实践 蓝牙在配对之前都是明文通信的,也就是说主从机之间传输的数据包可以被第三方抓取分析逆向,而且如果没有配对,谁都可 ...

  6. nrf52832 学习笔记(七)蓝牙协议层级理解

    nrf52832 学习笔记(七)蓝牙协议层级理解 本文主要由一下几篇文档摘录汇总而成 ,如有错误欢迎斧正 da14531 蓝牙协议文档 深入浅出低功耗蓝牙(BLE)协议栈 低功耗蓝牙ATT/GATT/ ...

  7. NRF52832学习笔记(38)——修改发射功率

    一.背景 蓝牙接收信号强度 RSSI 的直接影响因素就是蓝牙信号的发射功率.发射功率就是你所使用的设备(开发板.手机)所发射出来给主机或从机设备的信号强度.同时在实际应用当中,时常也需要修改蓝牙的发射 ...

  8. NRF52832学习笔记(35)——4G模块EC200S使用

    一.简介 EC200S-CN 是移远通信最近推出的 LTE Cat 1 无线通信模块,支持最大下行速率 10Mbps 和最大上行速率 5Mbps,具有超高的性价比:同时在封装上兼容移远通信多网络制式 ...

  9. NRF52832学习笔记(40)——RFID RC522使用

    一.简介 MF RC522 是应用于 13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员.是 NXP 公司针对"三表"应用推出的一款低电压.低成本.体积小的非接触式读写 ...

  10. nrf52832 学习笔记(一)开发资料汇总

    nrf52832 学习笔记(一)开发资料汇总 协议栈和SDK下载地址 nordic官方的sdk分为ncs(nRF Connect SDK)和sdk17(nRF5 SDK)两种,区别是: sdk17不会 ...

最新文章

  1. Java中主线程如何捕获子线程抛出的异常
  2. 机器学习算法基础——逻辑回归
  3. Highcharts图表-ajax-获取json数据生成图表
  4. python循环遍历所有目录_python 遍历文件夹
  5. android 7 apk 安装程序,Android安装apk文件并适配Android 7.0详解
  6. cad完全卸载教程_AutoCAD 2019 如何卸载,彻底卸载CAD教程
  7. highcharts注销
  8. Rhino使JavaScript应用程序更灵动
  9. win7连接远程服务器特别慢,技术员告诉您win7远程桌面连接速度慢的具体解决法子...
  10. 航天晨光:永中DCS与原有OA系统整合,文件阅览效率大幅提升!
  11. 天津仁爱学院2021级高职升本科新生报到须知
  12. 学习————运算符!
  13. 在Visual Studio上开启自己的C++学习之旅
  14. matlab三维螺旋,如何在MATLAB或Python中生成三维螺旋线?
  15. ajaxSubmit的使用总结
  16. 阿里巴巴合伙人制度阿里巴巴现任合伙人一览表
  17. SSH远程登录RaspberryPi命令行响应缓慢问题
  18. python是开源的.它可以被移植_免费搜尔雅网课答案的公众号
  19. 安全防御——IDS(入侵检测系统)
  20. 微信修复聊天记录,可惜99%的人都不知道!

热门文章

  1. RFID反向不归零编码(NRZ)
  2. Coursera | Introduction to Data Science in Python(University of Michigan)| Assignment2
  3. TCP长连接和HTTP长连接对比
  4. word不能读出html表格,WORD里面表格不能自动跳到下一页解决方案
  5. 红米5plus刷android one,手机知识:红米5plus如何 红米5plus配置参数
  6. 一次递减代码matlab,DEA算法学习系列之三:一次性求解CCR模型所有DMU参数——效率、规模效益、有效性特征、调整值的matlab代码...
  7. n1盒子openwrt某个容器无法启动 启动直接死机
  8. Python 串级PID代码
  9. 面向数据发布和分析的差分隐私保护 -- 张啸剑
  10. 【优化求解】基于遗传算法优化PARSEC 方法的翼型形状附matlab代码