static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context) { uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle; uint16_t role = ble_conn_state_role(conn_handle); #if __USER_1_DEBUG__ test_printf("role = %d\r\n", role); #endif // Based on the role this device plays in the connection, dispatch to the right handler. if (role == BLE_GAP_ROLE_PERIPH || ble_evt_is_advertising_timeout(p_ble_evt)) { ble_evt_dispatch(p_ble_evt, p_context); } else if ((role == BLE_GAP_ROLE_CENTRAL) || (p_ble_evt->header.evt_id == BLE_GAP_EVT_ADV_REPORT)) { ble_module_central_evt(p_ble_evt, p_context); } }

时间: 2023-10-23 17:10:54 浏览: 45
这段代码实现了一个 BLE 事件处理函数,当发生 BLE 事件时,该函数会被调用。函数首先通过连接句柄获取 BLE 设备的角色(是从设备还是主设备),然后根据角色类型分发事件到不同的事件处理函数中。 如果该设备是从设备(BLE_GAP_ROLE_PERIPH),或者广播超时(ble_evt_is_advertising_timeout(p_ble_evt)),则直接调用 ble_evt_dispatch() 函数处理该事件。 如果该设备是主设备(BLE_GAP_ROLE_CENTRAL),或者事件 ID 是 BLE_GAP_EVT_ADV_REPORT,则调用 ble_module_central_evt() 函数处理该事件。 其中,p_ble_evt 是一个 BLE 事件结构体指针,包含了 BLE 事件的各种信息,而 p_context 则是一个用户定义的上下文指针,可以用来传递一些额外的参数或数据。
相关问题

esp32 蓝牙启动流程_ESP32教你简单进行蓝牙串口调试

ESP32的蓝牙启动流程如下: 1. 初始化蓝牙协议栈 2. 配置蓝牙参数,如设备名称、服务UUID等 3. 注册蓝牙事件回调函数 4. 启动蓝牙广播 5. 开启蓝牙可见性 6. 等待连接 以下是一个简单的ESP32蓝牙串口调试的示例: ```C #include "esp_bt.h" #include "esp_bt_main.h" #include "esp_gap_ble_api.h" #define GATTS_TAG "GATTS_DEMO" #define TEST_DEVICE_NAME "ESP32_BLE_UART" #define TEST_MANUFACTURER_DATA_LEN 17 /* The max length of characteristic value. When the gatt client write or prepare write, * the data length must be less than MAX_VALUE_LENGTH. */ #define MAX_VALUE_LENGTH 500 /* Declare global variable */ static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x4c, 0x00, 0x02, 0x15, 0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4, 0xA1, 0x2F, 0x17, 0xD1, 0xAD}; static uint8_t test_service_uuid128[32] = { /* LSB <--------------------------------------------------------------------------------> MSB */ //first uuid, 16bit, [12],[13] is the value 0x13, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB, //second uuid, 32bit, [12], [13], [14], [15] is the value 0x14, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB, }; static uint8_t test_service_uuid[16] = { /* LSB <--------------------------------------------------------------------------------> MSB */ //first uuid, 16bit, [12],[13] is the value 0x01, 0x2B, //second uuid, 32bit, [12], [13], [14], [15] is the value 0x01, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB, }; static uint8_t test_char_uuid[16] = { /* LSB <--------------------------------------------------------------------------------> MSB */ //first uuid, 16bit, [12],[13] is the value 0x02, 0x2B, //second uuid, 32bit, [12], [13], [14], [15] is the value 0x02, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB, }; static esp_gatt_char_prop_t test_property = 0; static uint8_t char1_str[] = {0x11,0x22,0x33}; static esp_attr_value_t gatts_demo_char1_val = { .attr_max_len = MAX_VALUE_LENGTH, .attr_len = sizeof(char1_str), .attr_value = char1_str, }; static uint16_t gatts_demo_handle_table[3]; /* Full Database Description - Used to add attributes into the database */ static const esp_gatts_attr_db_t gatt_db[HRS_IDX_NB] = { // Service Declaration [IDX_SVC] = { {ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ, sizeof(test_service_uuid), sizeof(test_service_uuid), (uint8_t *)&test_service_uuid}, ESP_GATT_UUID_PRI_SERVICE, ESP_GATT_PERM_READ, sizeof(test_service_uuid), sizeof(test_service_uuid), (uint8_t *)&test_service_uuid, 0 }, /* Characteristic Declaration */ [IDX_CHAR_READ] = { {ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&test_property}, ESP_GATT_UUID_CHAR_DECLARE, ESP_GATT_PERM_READ, CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&test_property, 0 }, /* Characteristic Value */ [IDX_CHAR_VAL_READ] = { {ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_128, (uint8_t *)&test_char_uuid, ESP_GATT_PERM_READ, MAX_VALUE_LENGTH, sizeof(gatts_demo_char1_val), gatts_demo_char1_val.attr_value}, ESP_UUID_LEN_128, ESP_GATT_PERM_READ, MAX_VALUE_LENGTH, sizeof(gatts_demo_char1_val), gatts_demo_char1_val.attr_value, 0 }, }; static esp_ble_adv_data_t adv_data = { .set_scan_rsp = false, .include_name = true, .include_txpower = true, .min_interval = 0x20, .max_interval = 0x40, .appearance = 0x00, .manufacturer_len = TEST_MANUFACTURER_DATA_LEN, .p_manufacturer_data = test_manufacturer, .service_data_len = 0, .p_service_data = NULL, .service_uuid_len = sizeof(test_service_uuid), .p_service_uuid = test_service_uuid, .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT), }; static esp_ble_adv_params_t adv_params = { .adv_int_min = 0x20, .adv_int_max = 0x40, .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .peer_addr = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, .peer_addr_type = BLE_ADDR_TYPE_PUBLIC, .channel_map = ADV_CHNL_ALL, .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, }; static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { switch (event) { case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: esp_ble_gap_start_advertising(&adv_params); break; case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { ESP_LOGE(GATTS_TAG, "advertising start failed"); } break; default: break; } } static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { switch (event) { case ESP_GATTS_REG_EVT: esp_ble_gap_set_device_name(TEST_DEVICE_NAME); esp_ble_gap_config_adv_data(&adv_data); break; case ESP_GATTS_CREAT_ATTR_TAB_EVT: if (param->add_attr_tab.status != ESP_GATT_OK){ ESP_LOGE(GATTS_TAG, "create attribute table failed, error code=0x%x", param->add_attr_tab.status); } else if (param->add_attr_tab.num_handle != HRS_IDX_NB) { ESP_LOGE(GATTS_TAG, "create attribute table abnormally, num_handle (%d) \ doesn't equal to HRS_IDX_NB(%d)", param->add_attr_tab.num_handle, HRS_IDX_NB); } else { ESP_LOGI(GATTS_TAG, "create attribute table successfully, the number handle = %d\n",param->add_attr_tab.num_handle); memcpy(gatts_demo_handle_table, param->add_attr_tab.handles, sizeof(gatts_demo_handle_table)); esp_ble_gatts_start_service(gatts_demo_handle_table[IDX_SVC]); } break; case ESP_GATTS_CONNECT_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT"); break; case ESP_GATTS_DISCONNECT_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_DISCONNECT_EVT"); esp_ble_gap_start_advertising(&adv_params); break; case ESP_GATTS_WRITE_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_WRITE_EVT"); break; case ESP_GATTS_MTU_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu); break; case ESP_GATTS_CONF_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONF_EVT"); break; case ESP_GATTS_EXEC_WRITE_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_EXEC_WRITE_EVT"); break; case ESP_GATTS_START_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_START_EVT"); break; case ESP_GATTS_STOP_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_STOP_EVT"); break; case ESP_GATTS_OPEN_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_OPEN_EVT"); break; case ESP_GATTS_CANCEL_OPEN_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_CANCEL_OPEN_EVT"); break; case ESP_GATTS_CLOSE_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_CLOSE_EVT"); break; case ESP_GATTS_LISTEN_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_LISTEN_EVT"); break; case ESP_GATTS_CONGEST_EVT: ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONGEST_EVT"); break; case ESP_GATTS_UNREG_EVT: case ESP_GATTS_DELETE_EVT: default: break; } } void app_main() { esp_err_t ret; ESP_LOGI(GATTS_TAG, "ESP_BLUETOOTH_BLE example started."); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); ret = esp_bt_controller_init(&bt_cfg); if (ret) { ESP_LOGE(GATTS_TAG, "%s initialize controller failed\n", __func__); return; } ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); if (ret) { ESP_LOGE(GATTS_TAG, "%s enable controller failed\n", __func__); return; } ret = esp_bluedroid_init(); if (ret) { ESP_LOGE(GATTS_TAG, "%s init bluetooth failed\n", __func__); return; } ret = esp_bluedroid_enable(); if (ret) { ESP_LOGE(GATTS_TAG, "%s enable bluetooth failed\n", __func__); return; } ret = esp_ble_gatts_register_callback(gatts_event_handler); if (ret){ ESP_LOGE(GATTS_TAG, "gatts register error, error code = %x", ret); return; } ret = esp_ble_gap_register_callback(gap_event_handler); if (ret){ ESP_LOGE(GATTS_TAG, "gap register error, error code = %x", ret); return; } ret = esp_ble_gatts_app_register(ESP_APP_ID); if (ret){ ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret); return; } esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500); if (local_mtu_ret){ ESP_LOGE(GATTS_TAG, "set local MTU failed, error code = %x", local_mtu_ret); } ret = esp_ble_gatts_create_attr_tab(gatt_db, gatts_if, HRS_IDX_NB, ESP_APP_ID); if (ret){ ESP_LOGE(GATTS_TAG, "create attr table failed, error code = %x", ret); } } ``` 在这个示例中,我们使用了ESP-IDF提供的蓝牙协议栈和GATT Server框架,实现了一个简单的GATT Server,并且开启了蓝牙广播和可见性,使得其他蓝牙设备可以扫描到并连接我们的设备。在连接建立后,我们可以向GATT Server中的特定Characteristic写入数据,也可以从特定Characteristic读取数据。

请给出Nordic nRF5 SDK中创建新的BLE服务的详细示例

好的,下面是使用Nordic nRF5 SDK创建新的BLE服务的详细示例: 1. 首先,在nRF5 SDK中打开“examples\ble_peripheral\ble_app_template”示例。 2. 在“ble_app”文件夹中,打开“ble_srv_common.h”文件。此文件包含了一些常用的BLE服务定义,你可以通过阅读该文件来了解BLE服务的实现方式。 3. 在“ble_app”文件夹中,打开“ble_srv_common.c”文件。此文件包含了一些常用的BLE服务实现代码,你可以通过阅读该文件来了解BLE服务的实现方式。 4. 在“ble_app”文件夹中,创建一个新的文件夹,命名为“my_service”。 5. 在“my_service”文件夹中,创建一个新的文件,命名为“my_service.h”。在该文件中,你需要定义你的自定义BLE服务的UUID,以及相关的特性和属性等信息。例如: ``` #ifndef MY_SERVICE_H #define MY_SERVICE_H #include "ble.h" #include "ble_srv_common.h" #define BLE_UUID_MY_SERVICE 0x1234 // 自定义服务的UUID // 自定义服务的特性UUID #define BLE_UUID_MY_SERVICE_CHARACTERISTIC 0x5678 // 自定义服务的特性值结构体 typedef struct { uint8_t value; } ble_my_service_characteristic_t; // 自定义服务的事件结构体 typedef struct { ble_my_service_characteristic_t char_value; } ble_my_service_evt_t; // 自定义服务的事件句柄类型 typedef void (*ble_my_service_evt_handler_t) (ble_my_service_evt_t * p_evt); // 自定义服务的初始化函数 uint32_t ble_my_service_init(void); // 自定义服务的事件注册函数 void ble_my_service_evt_handler_register(ble_my_service_evt_handler_t evt_handler); #endif // MY_SERVICE_H ``` 6. 在“my_service”文件夹中,创建一个新的文件,命名为“my_service.c”。在该文件中,你需要实现你的自定义BLE服务的初始化、事件处理等功能。例如: ``` #include "my_service.h" static uint16_t m_service_handle; // 自定义服务的句柄 static ble_gatts_char_handles_t m_char_handles; // 自定义服务的特性句柄 static ble_my_service_evt_handler_t m_evt_handler; // 自定义服务的事件处理函数 // 自定义服务的事件回调函数 static void my_service_evt_handler(ble_evt_t const * p_ble_evt) { switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: break; case BLE_GAP_EVT_DISCONNECTED: break; case BLE_GATTS_EVT_WRITE: if (p_ble_evt->evt.gatts_evt.params.write.handle == m_char_handles.value_handle) { ble_my_service_evt_t evt; evt.char_value.value = p_ble_evt->evt.gatts_evt.params.write.data[0]; m_evt_handler(&evt); } break; default: break; } } // 自定义服务的事件注册函数 void ble_my_service_evt_handler_register(ble_my_service_evt_handler_t evt_handler) { m_evt_handler = evt_handler; } // 自定义服务的初始化函数 uint32_t ble_my_service_init(void) { uint32_t err_code; ble_uuid_t ble_uuid; ble_uuid128_t base_uuid = {BLE_UUID_MY_SERVICE_BASE}; // 生成自定义服务的UUID err_code = sd_ble_uuid_vs_add(&base_uuid, &ble_uuid.type); VERIFY_SUCCESS(err_code); ble_uuid.uuid = BLE_UUID_MY_SERVICE; // 添加自定义服务 err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &m_service_handle); VERIFY_SUCCESS(err_code); // 添加自定义服务的特性 ble_gatts_char_md_t char_md; memset(&char_md, 0, sizeof(char_md)); char_md.char_props.read = 1; char_md.char_props.write = 1; ble_gatts_attr_md_t attr_md; memset(&attr_md, 0, sizeof(attr_md)); attr_md.read_perm = BLE_GAP_CONN_SEC_MODE_OPEN; attr_md.write_perm = BLE_GAP_CONN_SEC_MODE_OPEN; attr_md.vloc = BLE_GATTS_VLOC_STACK; ble_uuid_t char_uuid; char_uuid.uuid = BLE_UUID_MY_SERVICE_CHARACTERISTIC; char_uuid.type = ble_uuid.type; ble_gatts_attr_t attr; memset(&attr, 0, sizeof(attr)); attr.p_uuid = &char_uuid; attr.p_attr_md = &attr_md; attr.init_len = sizeof(ble_my_service_characteristic_t); attr.max_len = sizeof(ble_my_service_characteristic_t); attr.p_value = NULL; err_code = sd_ble_gatts_characteristic_add(m_service_handle, &char_md, &attr, &m_char_handles); VERIFY_SUCCESS(err_code); // 注册事件回调函数 err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_TAG); VERIFY_SUCCESS(err_code); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *) DEVICE_NAME, strlen(DEVICE_NAME)); VERIFY_SUCCESS(err_code); err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_adv_handle, TX_POWER); VERIFY_SUCCESS(err_code); err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_SCAN_INIT, 0, TX_POWER); VERIFY_SUCCESS(err_code); err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_CONN, 0, TX_POWER); VERIFY_SUCCESS(err_code); err_code = sd_ble_gap_ppcp_set(&ppcp); VERIFY_SUCCESS(err_code); return NRF_SUCCESS; } ``` 7. 在“main.c”文件中,包含“my_service.h”头文件,并在初始化函数中调用“ble_my_service_init()”函数来初始化你的自定义BLE服务。例如: ``` #include "my_service.h" int main(void) { uint32_t err_code; // 初始化BLE协议栈 ble_stack_init(); // 初始化GAP参数 gap_params_init(); // 初始化GATT参数 gatt_init(); // 初始化自定义服务 err_code = ble_my_service_init(); APP_ERROR_CHECK(err_code); // 启动广播 advertising_start(); // 进入主循环 for (;;) { idle_state_handle(); } } ``` 到此为止,我们已经完成了一个简单的自定义BLE服务的创建实例。你可以根据自己的需要修改“my_service.h”和“my_service.c”文件,来实现更加复杂的自定义BLE服务。

相关推荐

最新推荐

管理系统系列--游戏运营管理系统SpringMVC.zip

管理系统系列--游戏运营管理系统SpringMVC

downloadfile.pdf

downloadfile.pdf

【Java毕业设计】爱慈善公益平台(love-charity)是一个基于 SpringBoot 开发的标准 Java.zip

【Java毕业设计】爱慈善公益平台(love-charity)是一个基于 SpringBoot 开发的标准 Java

自动化与电气工程学院-轨道交通信号与控制专业-郑智怀.pdf

自动化与电气工程学院-轨道交通信号与控制专业-郑智怀.pdf

多语言U-S-D-T交易市场源码/U-S-D-T理财系统源码/排单系统源码

多语言U-S-D-T交易市场源码/U-S-D-T理财系统源码/排单系统源码

三相电压型逆变器工作原理分析.pptx

运动控制技术及应用

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire

液位控制技术在换热站工程中的应用与案例分析

# 1. 引言 ### 1.1 研究背景 在工程领域中,液位控制技术作为一项重要的自动化控制技术,广泛应用于各种工业生产和设备操作中。其中,液位控制技术在换热站工程中具有重要意义和价值。本文将针对液位控制技术在换热站工程中的应用展开深入研究和分析。 ### 1.2 研究意义 换热站作为工业生产中的关键设备,其性能稳定性和安全运行对于整个生产系统至关重要。液位控制技术作为一项可以实现对液体介质在容器内的准确控制的技术,在换热站工程中可以起到至关重要的作用。因此,深入研究液位控制技术在换热站工程中的应用对于提升工程效率、降低生产成本具有重要意义。 ### 1.3 研究目的 本文旨在通过

vue this.tagsList判断是否包含某个值

你可以使用JavaScript中的`includes()`方法来判断一个数组是否包含某个值。在Vue中,你可以使用以下代码来判断`this.tagsList`数组中是否包含某个值: ```javascript if (this.tagsList.includes('某个值')) { // 数组包含该值的处理逻辑 } else { // 数组不包含该值的处理逻辑 } ``` 其中,将`某个值`替换为你要判断的值即可。

数据中心现状与趋势-201704.pdf

2 2 IDC发展驱动力 一、IDC行业发展现状 3 3 IDC发展驱动力 4 4 ü 2011年以前,全球IDC增长迅速,2012-2013年受经济影响放慢了增长速度,但从2014年开始,技术创新 驱动的智能终端、VR、人工智能、可穿戴设备、物联网以及基因测序等领域快速发展,带动数据存储规模 、计算能力以及网络流量的大幅增加,全球尤其是亚太地区云计算拉动的新一代基础设施建设进入加速期。 ü 2016 年全球 IDC 市场规模达到 451.9 亿美元,增速达 17.5%。从市场总量来看,美国和欧洲地区占据了 全球 IDC 市场规模的 50%以上。从增速来看,全球市场规模增速趋缓,亚太地区继续在各区域市场中保持 领先,其中以中国、印度和新加坡增长最快。 2010-2016年全球IDC市场规模 IDC市场现状-全球 5 5 IDC市场现状-国内 ü 中国2012、2013年IDC市场增速下滑,但仍高于全球平均增速。2014年以来,政府加强政策引导、开放 IDC牌照,同时移动互联网、视频、游戏等新兴行业发展迅速,推动IDC行业发展重返快车道。 ü 2016 年中国 IDC 市场继续保持高速增