#include "zble_module.h" #include #include #include "znordic.h" /******************************************************************************* * 广播包é…ç½? * *******************************************************************************/ #define MIN_CONN_INTERVAL MSEC_TO_UNITS(20, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */ #define MAX_CONN_INTERVAL MSEC_TO_UNITS(75, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */ #define SLAVE_LATENCY 0 /**< Slave latency. */ #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */ #define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */ static ble_uuid_t m_adv_uuids[] = /**< Universally unique service identifier. */ {{BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}}; #define APP_ADV_INTERVAL 64 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */ #define APP_ADV_DURATION 18000 /**< The advertising duration (180 seconds) in units of 10 milliseconds. */ BLE_ADVERTISING_DEF(m_advertising); /**< Advertising module instance. */ /******************************************************************************* * GATTé…ç½® * *******************************************************************************/ NRF_BLE_GATT_DEF(m_gatt); /**< GATT module instance. */ /******************************************************************************* * è¿žæŽ¥å‚æ•°é…ç½® * *******************************************************************************/ #define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */ #define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(30000) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */ #define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */ /******************************************************************************* * CODE * *******************************************************************************/ static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< 当å‰è¿žæŽ¥å¥æŸ„ */ static uint16_t m_mtu_size = BLE_GATT_ATT_MTU_DEFAULT - 3; static void ble_evt_handler(ble_evt_t const* p_ble_evt, void* p_context) { uint32_t err_code; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: m_conn_handle = BLE_CONN_HANDLE_INVALID; break; case BLE_GAP_EVT_PHY_UPDATE_REQUEST: { NRF_LOG_DEBUG("PHY update request."); ble_gap_phys_t const phys = { .rx_phys = BLE_GAP_PHY_AUTO, .tx_phys = BLE_GAP_PHY_AUTO, }; err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys); ZERROR_CHECK(err_code); } break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: // Pairing not supported err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); ZERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: // No system attributes have been stored. err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); ZERROR_CHECK(err_code); break; case BLE_GATTC_EVT_TIMEOUT: // 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); ZERROR_CHECK(err_code); break; case BLE_GATTS_EVT_TIMEOUT: // Disconnect on GATT Server timeout event. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); ZERROR_CHECK(err_code); break; default: // No implementation needed. break; } } static void gatt_evt_handler(nrf_ble_gatt_t* p_gatt, nrf_ble_gatt_evt_t const* p_evt) { /******************************************************************************* * MTU SIZE æ›´æ–° * *******************************************************************************/ if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)) { m_mtu_size = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH; NRF_LOG_DEBUG("ATT MTU exchange completed. central %d peripheral %d", p_gatt->att_mtu_desired_central, p_gatt->att_mtu_desired_periph); } } static void on_conn_params_evt(ble_conn_params_evt_t* p_evt) { uint32_t err_code; if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) { err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); ZERROR_CHECK(err_code); } } static void conn_params_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); } static void on_adv_evt(ble_adv_evt_t ble_adv_evt) { switch (ble_adv_evt) { case BLE_ADV_EVT_FAST: // err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING); // ZERROR_CHECK(err_code); break; case BLE_ADV_EVT_IDLE: // sleep_mode_enter(); break; default: break; } } void zble_module_start_adv() { uint32_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST); ZERROR_CHECK(err_code); } void zble_module_stop_adv() { uint32_t err_code = sd_ble_gap_adv_stop(m_advertising.adv_handle); ZERROR_CHECK(err_code); } /******************************************************************************* * INIT * *******************************************************************************/ void zble_module_init(zble_module_cfg_t* cfg) { /** * @brief * åˆå§‹åŒ–è“牙å议栈,并注册è“牙事件处ç†å‡½æ•°ï¼Œå›ºå®šä»£ç ï¼Œå‹¿ä¿®æ”? */ { NRF_SDH_BLE_OBSERVER(m_ble_observer, 3, ble_evt_handler, NULL); } /******************************************************************************* * GAPåˆå§‹åŒ? * *******************************************************************************/ { uint32_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t*)cfg->deviceName, strlen(cfg->deviceName)); ZERROR_CHECK(err_code); memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); ZERROR_CHECK(err_code); } /******************************************************************************* * GATT åˆå§‹åŒ? * *******************************************************************************/ { ret_code_t err_code; err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler); ZERROR_CHECK(err_code); err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE); ZERROR_CHECK(err_code); } /******************************************************************************* * è“牙æœåŠ¡åˆå§‹åŒ? * *******************************************************************************/ { if (cfg->on_service_init) cfg->on_service_init(); } /******************************************************************************* * 广播åˆå§‹åŒ? * *******************************************************************************/ { uint32_t err_code; ble_advertising_init_t init; memset(&init, 0, sizeof(init)); init.advdata.name_type = BLE_ADVDATA_FULL_NAME; init.advdata.include_appearance = false; // init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE; init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]); init.srdata.uuids_complete.p_uuids = m_adv_uuids; init.config.ble_adv_fast_enabled = true; init.config.ble_adv_fast_interval = APP_ADV_INTERVAL; init.config.ble_adv_fast_timeout = 0; init.evt_handler = on_adv_evt; err_code = ble_advertising_init(&m_advertising, &init); ZERROR_CHECK(err_code); ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG); } /******************************************************************************* * è¿žæŽ¥å‚æ•°åˆå§‹åŒ? * *******************************************************************************/ { uint32_t err_code; ble_conn_params_init_t cp_init; memset(&cp_init, 0, sizeof(cp_init)); cp_init.p_conn_params = NULL; cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; cp_init.disconnect_on_fail = false; cp_init.evt_handler = on_conn_params_evt; cp_init.error_handler = conn_params_error_handler; err_code = ble_conn_params_init(&cp_init); ZERROR_CHECK(err_code); } // zble_module_start_adv(); }