123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959 |
- #include "ble_peripheral.h"
- #include "ble_conn_state.h"
- #include "peer_manager.h"
- #include "peer_manager_handler.h"
- //DFU需要引用的头文件
- #if NRF_MODULE_ENABLED(BLE_DFU)
- #include "nrf_power.h"
- #include "nrf_bootloader_info.h"
- #include "ble_dfu.h"
- #include "nrf_sdm.h"
- #include "nrf_dfu_ble_svci_bond_sharing.h"
- #include "nrf_svci_async_function.h"
- #include "nrf_svci_async_handler.h"
- static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event);
- #endif
- #if NRF_MODULE_ENABLED(BLE_MY_UARTS)
- #include "my_ble_uarts.h"
- #endif
- BLE_ADVERTISING_DEF(m_advertising); /**< ************** Advertising module instance. **************/
- int8_t tx_power_level=NRF_BLE_ADVDATA_NOREG_TX_POWER; /**< *********************** ble发射功率 **********************/
- uint32_t ble_adv_interval=NRF_BLE_ADV_NOREG_INTERVAL; /**< *********************ble蓝牙广播时间 *********************/
- uint32_t ble_adv_duration=NRF_BLE_ADV_DURATION;
- static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< ************ Handle of the current connection. ***********/
- static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< ****** Buffer for storing an encoded advertising set. ****/
- static uint8_t m_enc_scan_response_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< ********* Buffer for storing an encoded scan data. *******/
- bool ble_adv_stat=false;
- #if NRF_SEC_PARAM_BLE==1
- static ble_gap_sec_params_t m_sec_params;
- static ble_gap_sec_keyset_t m_sec_keyset;
- static ble_gap_enc_key_t m_own_enc_key;
- static ble_gap_enc_key_t m_peer_enc_key;
- static ble_gap_sec_params_t m_sec_params_auth;
- #endif
- #if NRF_BLE_ADVDATA_WHITELIST_ENABLE==1
- static pm_peer_id_t m_peer_id;
- static pm_peer_id_t m_whitelist_peers[NRF_BLE_ADVDATA_WHITELIST_MAX_COUNT]; /**< ******* List of peers currently in the whitelist. ********/
- static uint32_t m_whitelist_peer_cnt; /**< ****** Number of peers currently in the whitelist. *******/
- #endif
- extern uint8_t m_addl_adv_manuf_data[];
- static void advertising_start(void);
-
- /**@brief Struct that contains pointers to the encoded advertising data. */
- static ble_gap_adv_data_t m_adv_data =
- {
- .adv_data =
- {
- .p_data = m_enc_advdata,
- .len = BLE_GAP_ADV_SET_DATA_SIZE_MAX
- },
- .scan_rsp_data =
- {
- .p_data = m_enc_scan_response_data,
- .len = BLE_GAP_ADV_SET_DATA_SIZE_MAX
- }
- };
- static ble_peripheral_s ble_per_s=
- {
- .dfu_func=NULL,
- .dfu_stat=false,
- };
- // 添加私有服务时,需更改NRF_SDH_BLE_VS_UUID_COUNT
- static ble_uuid_t owned_adv_uuids[] = /**< ******** Universally unique service identifiers. *********/
- {
- #if WECHAT_SERVER_ENABLED==1
- {BLE_UUID_WECHAT_SERVICE, BLE_UUID_TYPE_BLE},
- #else
- #if OWNED_SERVER_ENABLED==1
- {BLE_UUID_OWNED_BASE, BLE_UUID_TYPE_BLE},
- #endif
- #endif
-
- #if NRF_MODULE_ENABLED(BLE_MY_UARTS)
- {BLE_UUID_UARTS_SERVICE, BLE_UUID_TYPE_VENDOR_BEGIN},
- #endif
- };
- /**@brief Function for the Noreg GAP initialization.
- *
- * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
- * device including the device name, appearance, and the preferred connection parameters.
- */
- static void gap_params_init(void)
- {
- ret_code_t err_code;
- ble_gap_conn_params_t gap_conn_params;
- ble_gap_conn_sec_mode_t sec_mode;
- #if NRF_SEC_PARAM_BLE==1
- ble_opt_t passkey_opt;
- uint8_t passkey[] = "12345678";
- #endif
- BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
- err_code = sd_ble_gap_device_name_set(&sec_mode,
- (const uint8_t *)BLE_DEVICE_NAME,
- strlen(BLE_DEVICE_NAME));
- APP_ERROR_CHECK(err_code);
- memset(&gap_conn_params, 0, sizeof(gap_conn_params));
- gap_conn_params.min_conn_interval = NRF_BLE_MIN_CONN_INTERVAL;
- gap_conn_params.max_conn_interval = NRF_BLE_MAX_CONN_INTERVAL;
- gap_conn_params.slave_latency = NRF_BLE_CONN_SLAVE_LATENCY;
- gap_conn_params.conn_sup_timeout = NRF_BLE_CONN_SUP_TIMEOUT;
- err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
- APP_ERROR_CHECK(err_code);
-
- #if NRF_SEC_PARAM_BLE==1
- passkey_opt.gap_opt.passkey.p_passkey = passkey;
- err_code = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &passkey_opt);
- APP_ERROR_CHECK(err_code);
- #endif
- }
- //ble_gap_addr_t whitelist_addrs_gap[1];
- /**@brief Function for handling Queued Write Module errors.
- *
- * @details A pointer to this function will be passed to each service which may need to inform the
- * application about an error.
- *
- * @param[in] nrf_error Error code containing information about what went wrong.
- */
- static void nrf_qwr_error_handler(uint32_t nrf_error)
- {
- APP_ERROR_HANDLER(nrf_error);
- }
- #if NRF_BLE_ADVDATA_WHITELIST_ENABLE==1
- /**@brief Function for setting filtered whitelist.
- *
- * @param[in] skip Filter passed to @ref pm_peer_id_list.
- */
- static void whitelist_set(pm_peer_id_list_skip_t skip)
- {
- pm_peer_id_t peer_ids[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
- uint32_t peer_id_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
- ret_code_t err_code = pm_peer_id_list(peer_ids, &peer_id_count, PM_PEER_ID_INVALID, skip);
- APP_ERROR_CHECK(err_code);
- NRF_LOG_INFO("\tm_whitelist_peer_cnt %d, MAX_PEERS_WLIST %d",
- peer_id_count + 1,
- BLE_GAP_WHITELIST_ADDR_MAX_COUNT);
- err_code = pm_whitelist_set(peer_ids, peer_id_count);
- APP_ERROR_CHECK(err_code);
- }
- #endif
- #if NRF_SEC_PARAM_BLE==1
- /**@brief Function for setting filtered device identities.
- *
- * @param[in] skip Filter passed to @ref pm_peer_id_list.
- */
- static void identities_set(pm_peer_id_list_skip_t skip)
- {
- pm_peer_id_t peer_ids[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT];
- uint32_t peer_id_count = BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT;
- ret_code_t err_code = pm_peer_id_list(peer_ids, &peer_id_count, PM_PEER_ID_INVALID, skip);
- APP_ERROR_CHECK(err_code);
- err_code = pm_device_identities_list_set(peer_ids, peer_id_count);
- APP_ERROR_CHECK(err_code);
- }
- #endif
- /**@brief Function for handling advertising events.
- *
- * @details This function will be called for advertising events which are passed to the application.
- *
- * @param[in] ble_adv_evt Advertising event.
- */
- static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
- {
- uint32_t err_code;
- switch (ble_adv_evt)
- {
- case BLE_ADV_EVT_FAST:
- NRF_LOG_INFO("Fast advertising");
- break;
- #if NRF_BLE_ADVDATA_WHITELIST_ENABLE==1
- case BLE_ADV_EVT_FAST_WHITELIST:
- NRF_LOG_INFO("Fast advertising with WhiteList");
- break;
- case BLE_ADV_EVT_SLOW_WHITELIST:
- NRF_LOG_INFO("Slow advertising with WhiteList");
- break;
- #endif
- case BLE_ADV_EVT_SLOW:
- NRF_LOG_INFO("Slow advertising");
- break;
- case BLE_ADV_EVT_IDLE:
- NRF_LOG_INFO("Enter BLE Idle");
- ble_adv_stat=false;
- break;
- #if NRF_BLE_ADVDATA_WHITELIST_ENABLE==1
- case BLE_ADV_EVT_WHITELIST_REQUEST:
- {
- ble_gap_addr_t whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
- ble_gap_irk_t whitelist_irks[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
- uint32_t addr_cnt = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
- uint32_t irk_cnt = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
- err_code = pm_whitelist_get(whitelist_addrs, &addr_cnt,
- whitelist_irks, &irk_cnt);
- APP_ERROR_CHECK(err_code);
- NRF_LOG_DEBUG("pm_whitelist_get returns %d addr in whitelist and %d irk whitelist",
- addr_cnt, irk_cnt);
- // Set the correct identities list (no excluding peers with no Central Address Resolution).
- identities_set(PM_PEER_ID_LIST_SKIP_NO_IRK);
- // Apply the whitelist.
- err_code = ble_advertising_whitelist_reply(&m_advertising,
- whitelist_addrs,
- addr_cnt,
- whitelist_irks,
- irk_cnt);
- APP_ERROR_CHECK(err_code);
- break;
- }
- #endif
- default:
- break;
- }
- }
- #if NRF_SEC_PARAM_BLE==1
- /**@brief Fetch the list of peer manager peer IDs.
- *
- * @param[inout] p_peers The buffer where to store the list of peer IDs.
- * @param[inout] p_size In: The size of the @p p_peers buffer.
- * Out: The number of peers copied in the buffer.
- */
- static void peer_list_get(pm_peer_id_t * p_peers, uint32_t * p_size)
- {
- pm_peer_id_t peer_id;
- uint32_t peers_to_copy;
- peers_to_copy = (*p_size < NRF_BLE_ADVDATA_WHITELIST_MAX_COUNT) ?
- *p_size : NRF_BLE_ADVDATA_WHITELIST_MAX_COUNT;
- peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
- *p_size = 0;
- while ((peer_id != PM_PEER_ID_INVALID) && (peers_to_copy--))
- {
- p_peers[(*p_size)++] = peer_id;
- peer_id = pm_next_peer_id_get(peer_id);
- }
- }
- /**@brief Clear bond information from persistent storage.
- */
- static void delete_bonds(void)
- {
- ret_code_t err_code;
- NRF_LOG_INFO("Erase bonds!");
- err_code = pm_peers_delete();
- APP_ERROR_CHECK(err_code);
- }
- /**@brief Function for handling Peer Manager events.
- *
- * @param[in] p_evt Peer Manager event.
- */
- static void pm_evt_handler(pm_evt_t const * p_evt)
- {
- ret_code_t err_code;
- pm_handler_on_pm_evt(p_evt);
- pm_handler_flash_clean(p_evt);
- switch (p_evt->evt_id)
- {
- case PM_EVT_CONN_SEC_SUCCEEDED:
- {
- m_peer_id = p_evt->peer_id;
- // Discover peer's services.
- err_code = ble_db_discovery_start(&m_ble_db_discovery, p_evt->conn_handle);
- APP_ERROR_CHECK(err_code);
- } break;
- case PM_EVT_PEERS_DELETE_SUCCEEDED:
- {
- advertising_start();
- } break;
- case PM_EVT_CONN_SEC_CONFIG_REQ:
- {
- pm_conn_sec_config_t pm_conn;
- pm_conn.allow_repairing=true;
- pm_conn_sec_config_reply(p_evt->conn_handle,&pm_conn);
- break;
- }
- case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
- {
- // Note: You should check on what kind of white list policy your application should use.
- if ( p_evt->params.peer_data_update_succeeded.flash_changed
- && (p_evt->params.peer_data_update_succeeded.data_id == PM_PEER_DATA_ID_BONDING))
- {
- NRF_LOG_INFO("New Bond, add the peer to the whitelist if possible");
- // Note: You should check on what kind of white list policy your application should use.
- whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR);
- }
- } break;
- default:
- break;
- }
- }
- #endif
- extern uint8_t bat_percent;//电池电量
- extern uint8_t dev_reg_stat;//设备激活状态
- #include "user_config.h"
-
- //广播初始化
- uint32_t advertising_init(void)
- {
- ret_code_t ret;
- ble_advdata_t advdata;
- ble_advdata_t srdata;
- uint8_t adv_server_count=0;
-
- memset(&advdata, 0, sizeof(advdata));
- memset(&srdata, 0, sizeof(srdata));
- //设备名称类型
- advdata.name_type = NRF_BLE_ADVDATA_NAME_TYPE;
- //是否包含外观
- advdata.include_appearance = NRF_BLE_ADVDATA_INCLUDE_APPEARANCE;
- //Flag:一般可发现模式,不支持BR/EDR
- advdata.flags = NRF_BLE_ADVDATA_FLAGS;
-
- //发射功率等级
- advdata.p_tx_power_level = &tx_power_level;
-
- ble_advdata_manuf_data_t manuf_data;
- //制造商ID,0x0059是Nordic的ID
- manuf_data.company_identifier = NRF_BLE_ADVDATA_COMPANY_ID;
- manuf_data.data.size = sizeof(ble_adv_manuf_data);
- //指向制造商自定义的数据
- ble_adv_manuf_data adv_manuf_data={
- .m_addr={0},
- .product_type=NRF_DEV_PRODUCT,
- .dev_version=(NRF_BLE_ADV_DEV_VERSION_MAIN<<4)| NRF_BLE_ADV_DEV_VERSION_SLAVE,
- .dev_reg_stat=(NRF_DEV_TYPE<<4) | dev_reg_stat,
- .bat_percent=bat_percent
- };
- //#ifdef user_config_param
- memcpy(adv_manuf_data.m_addr,m_addl_adv_manuf_data,BLE_GAP_ADDR_LEN);
- //#else
- // memcpy(adv_manuf_data.m_addr,m_addl_adv_manuf_data,BLE_GAP_ADDR_LEN);
- //#endif
- manuf_data.data.p_data = (uint8_t *)&adv_manuf_data;
- // manuf_data.data.size = BLE_GAP_ADDR_LEN;
- // manuf_data.data.p_data = m_addl_adv_manuf_data;
-
- NRF_LOG_INFO("mac addr.");
- NRF_LOG_HEXDUMP_INFO(manuf_data.data.p_data, manuf_data.data.size);
-
- advdata.p_manuf_specific_data=&manuf_data;
- // memcpy(&advdata.p_manuf_specific_data,&manuf_data,sizeof(ble_advdata_manuf_data_t));
- #if NRF_BLE_ADVDATA_INCLUDE_BAT == 1
- //定义服务数据结构体
- ble_advdata_service_data_t service_data;
- //电池电量服务UUID 0x180F
- service_data.service_uuid = BLE_UUID_BATTERY_SERVICE;
- service_data.data.size = sizeof(bat_percent);
- service_data.data.p_data = &bat_percent;
- //广播数据中加入服务数据
- advdata.p_service_data_array=&service_data;
- adv_server_count++;
- #endif
- //服务数据数量设置
- advdata.service_data_count = adv_server_count;
-
- srdata.uuids_complete.uuid_cnt = sizeof(owned_adv_uuids) / sizeof(owned_adv_uuids[0]);
- srdata.uuids_complete.p_uuids = owned_adv_uuids;
- #if NRF_BLE_ADVDATA_WHITELIST_ENABLE==1
- m_advertising.adv_modes_config.ble_adv_whitelist_enabled = true;
- #endif
-
- if(ble_adv_duration==0)
- {
- m_advertising.adv_modes_config.ble_adv_slow_interval = ble_adv_interval;
- m_advertising.adv_modes_config.ble_adv_slow_enabled = true;
- m_advertising.adv_modes_config.ble_adv_slow_timeout = ble_adv_duration;
- m_advertising.adv_modes_config.ble_adv_on_disconnect_disabled = false;
- }
- else{
- m_advertising.adv_modes_config.ble_adv_slow_enabled = true;
- m_advertising.adv_modes_config.ble_adv_slow_interval = ble_adv_interval;
- m_advertising.adv_modes_config.ble_adv_slow_timeout = ble_adv_duration;
- m_advertising.adv_modes_config.ble_adv_fast_enabled = true;
- m_advertising.adv_modes_config.ble_adv_fast_interval = ble_adv_interval;
- m_advertising.adv_modes_config.ble_adv_fast_timeout = ble_adv_duration;
- m_advertising.adv_modes_config.ble_adv_on_disconnect_disabled = true;
- }
-
- m_advertising.adv_mode_current = BLE_ADV_MODE_IDLE;
- m_advertising.conn_cfg_tag = BLE_CONN_CFG_TAG_DEFAULT;
- m_advertising.evt_handler = on_adv_evt;
- m_advertising.error_handler = nrf_qwr_error_handler;
- m_advertising.current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;
- m_advertising.p_adv_data = &m_advertising.adv_data;
- memset(&m_advertising.peer_address, 0, sizeof(m_advertising.peer_address));
- // Copy advertising data.
- if (!m_advertising.initialized)
- {
- m_advertising.adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
- }
- m_advertising.adv_data.adv_data.p_data = m_advertising.enc_advdata;
- if (m_advertising.adv_modes_config.ble_adv_extended_enabled == true)
- {
- #ifdef BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED
- m_advertising.adv_data.adv_data.len = BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED;
- #else
- m_advertising.adv_data.adv_data.len = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
- #endif // BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED
- }
- else
- {
- m_advertising.adv_data.adv_data.len = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
- }
- ret = ble_advdata_encode(&advdata, m_advertising.enc_advdata, &m_advertising.adv_data.adv_data.len);
- VERIFY_SUCCESS(ret);
- m_advertising.adv_data.scan_rsp_data.p_data = m_advertising.enc_scan_rsp_data;
- if (m_advertising.adv_modes_config.ble_adv_extended_enabled == true)
- {
- #ifdef BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED
- m_advertising.adv_data.scan_rsp_data.len = BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED;
- #else
- m_advertising.adv_data.scan_rsp_data.len = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
- #endif // BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED
- }
- else
- {
- m_advertising.adv_data.scan_rsp_data.len = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
- }
- ret = ble_advdata_encode(&srdata,m_advertising.adv_data.scan_rsp_data.p_data,&m_advertising.adv_data.scan_rsp_data.len);
- VERIFY_SUCCESS(ret);
- // Configure a initial advertising configuration. The advertising data and and advertising
- // parameters will be changed later when we call @ref ble_advertising_start, but must be set
- // to legal values here to define an advertising handle.
- m_advertising.adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
- m_advertising.adv_params.duration = ble_adv_duration;
- m_advertising.adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
- m_advertising.adv_params.p_peer_addr = NULL;
- m_advertising.adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
- m_advertising.adv_params.interval = ble_adv_interval;
- ret = sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, NULL, &m_advertising.adv_params);
- VERIFY_SUCCESS(ret);
- m_advertising.initialized = true;
- ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
- return ret;
- }
- /**@brief Function for handling the Connection Parameters Module.
- *
- * @details This function will be called for all events in the Connection Parameters Module that
- * are passed to the application.
- *
- * @note All this function does is to disconnect. This could have been done by simply
- * setting the disconnect_on_fail config parameter, but instead we use the event
- * handler mechanism to demonstrate its use.
- *
- * @param[in] p_evt Event received from the Connection Parameters Module.
- */
- static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
- {
- ret_code_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);
- APP_ERROR_CHECK(err_code);
- }
- }
- /**@brief Function for handling a Connection Parameters error.
- *
- * @param[in] nrf_error Error code containing information about what went wrong.
- */
- static void conn_params_error_handler(uint32_t nrf_error)
- {
- APP_ERROR_HANDLER(nrf_error);
- }
- //连接参数协商模块初始化
- static void conn_params_init(void)
- {
- ret_code_t err_code;
- //定义连接参数协商模块初始化结构体
- ble_conn_params_init_t cp_init;
- memset(&cp_init, 0, sizeof(cp_init));
- //设置为NULL,从主机获取连接参数
- cp_init.p_conn_params = NULL;
- //连接或启动通知到首次发起连接参数更新请求之间的时间设置为5秒
- cp_init.first_conn_params_update_delay = NRF_BLE_FIRST_CONN_PARAMS_UPDATE_DELAY;
- //每次调用sd_ble_gap_conn_param_update()函数发起连接参数更新请求的之间的间隔时间设置为:30秒
- cp_init.next_conn_params_update_delay = NRF_BLE_NEXT_CONN_PARAMS_UPDATE_DELAY;
- //放弃连接参数协商前尝试连接参数协商的最大次数设置为:3次
- cp_init.max_conn_params_update_count = NRF_BLE_MAX_CONN_PARAMS_UPDATE_COUNT;
- //连接参数更新从连接事件开始计时
- cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
- //连接参数更新失败断开连接
- cp_init.disconnect_on_fail = NRF_BLE_CONN_UPDATE_FAIL_DISCONNECT;
- //注册连接参数更新事件句柄
- cp_init.evt_handler = on_conn_params_evt;
- //注册连接参数更新错误事件句柄
- cp_init.error_handler = conn_params_error_handler;
- //调用库函数(以连接参数更新初始化结构体为输入参数)初始化连接参数协商模块
- err_code = ble_conn_params_init(&cp_init);
- APP_ERROR_CHECK(err_code);
- }
- /**@brief Function for starting advertising.
- */
- static void advertising_start(void)
- {
- ret_code_t err_code;
- #if NRF_BLE_ADVDATA_WHITELIST_ENABLE==1
- whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR);
- #endif
- if(ble_adv_duration==NRF_BLE_ADV_DURATION)
- {
- err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_SLOW);
- }
- else{
- err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
- }
- APP_ERROR_CHECK(err_code);
- err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV,m_advertising.adv_handle,tx_power_level);
- APP_ERROR_CHECK(err_code);
- }
- static void advertising_stop(void)
- {
- ret_code_t err_code;
- err_code = sd_ble_gap_adv_stop(m_advertising.adv_handle);
-
- if(err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE)
- {
- APP_ERROR_CHECK(err_code);
- }
- }
- #if NRF_SEC_PARAM_BLE==1
- static void sec_params_init(void)
- {
- memset(&m_sec_params, 0, sizeof(ble_gap_sec_params_t));
- // Security parameters to be used for all security procedures.
- m_sec_params.bond = NRF_SEC_PARAM_BOND;
- m_sec_params.mitm = NRF_SEC_PARAM_MITM;
- m_sec_params.lesc = NRF_SEC_PARAM_LESC;
- m_sec_params.keypress = NRF_SEC_PARAM_KEYPRESS;
- m_sec_params.io_caps = NRF_SEC_PARAM_IO_CAPABILITIES;
- m_sec_params.oob = NRF_SEC_PARAM_OOB;
- m_sec_params.min_key_size = NRF_SEC_PARAM_MIN_KEY_SIZE;
- m_sec_params.max_key_size = NRF_SEC_PARAM_MAX_KEY_SIZE;
- m_sec_params.kdist_own.enc = 1;
- m_sec_params.kdist_own.id = 0;
- m_sec_params.kdist_own.sign = 0;
- m_sec_params.kdist_peer.enc = 1;
- m_sec_params.kdist_peer.id = 0;
- m_sec_params.kdist_peer.sign = 0;
-
- m_sec_keyset.keys_own.p_enc_key = &m_own_enc_key;
- m_sec_keyset.keys_own.p_id_key = NULL;
- m_sec_keyset.keys_own.p_pk = NULL;
- m_sec_keyset.keys_own.p_sign_key = NULL;
-
- m_sec_keyset.keys_peer.p_enc_key = &m_peer_enc_key;
- m_sec_keyset.keys_peer.p_id_key = NULL;
- m_sec_keyset.keys_peer.p_pk = NULL;
- m_sec_keyset.keys_peer.p_sign_key = NULL;
- }
- /**@brief Function for the Peer Manager initialization.
- */
- static void peer_manager_init(void)
- {
- ret_code_t err_code;
- err_code = pm_init();
- APP_ERROR_CHECK(err_code);
- sec_params_init();
- err_code = pm_sec_params_set(&m_sec_params);
- APP_ERROR_CHECK(err_code);
- err_code = pm_register(pm_evt_handler);
- APP_ERROR_CHECK(err_code);
- }
- #endif
- //蓝牙事件处理函数
- void ble_peripheral_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
- {
- ret_code_t err_code;
- ble_owned_t * p_owned = (ble_owned_t *)p_context;
-
- switch (p_ble_evt->header.evt_id)
- {
- case BLE_GAP_EVT_CONNECTED:
- NRF_LOG_INFO("maindev connected!");
- // ble_timers_start(30000);
- m_conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
- // err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, p_ble_evt->evt.gattc_evt.conn_handle);
- // APP_ERROR_CHECK(err_code);
- #if NRF_SEC_PARAM_BLE==1
- m_sec_params_auth.bond = 0;
- m_sec_params_auth.mitm = 1;
- sd_ble_gap_authenticate(m_conn_handle, &m_sec_params_auth);//向中心设备发送配对请求
- #endif
- break;
- case BLE_GAP_EVT_DISCONNECTED:
- NRF_LOG_INFO("maindev disconnected!");
- ble_adv_stat=false;
- if(ble_adv_duration==NRF_BLE_ADV_DURATION)
- {
- Peripheral_Start();
- }
- break;
- case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
- {
- NRF_LOG_INFO("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);
- APP_ERROR_CHECK(err_code);
- } break;
- case BLE_GAP_EVT_ADV_SET_TERMINATED:
- NRF_LOG_INFO("adv timeout!");
- ble_adv_stat=false;
- if(ble_adv_duration == 0)
- {
- Peripheral_Start();
- }
- 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);
- APP_ERROR_CHECK(err_code);
- NRF_LOG_INFO("GATTS_EVT_SYS_ATTR_MISSING.");
- break;
- case BLE_GATTC_EVT_TIMEOUT:
- // Disconnect on GATT Client timeout event.
- NRF_LOG_INFO("GATT Client Timeout.");
- 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);
- break;
- case BLE_GATTS_EVT_TIMEOUT:
- // Disconnect on GATT Server timeout event.
- NRF_LOG_INFO("GATT Server Timeout.");
- err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
- BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
- APP_ERROR_CHECK(err_code);
- break;
- #if NRF_SEC_PARAM_BLE==1
- case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
- sec_params_init();
- err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, &m_sec_keyset);
- APP_ERROR_CHECK(err_code);
- break;
- #endif
- case BLE_GAP_EVT_PASSKEY_DISPLAY:
- NRF_LOG_INFO("passkey: %s\n",p_ble_evt->evt.gap_evt.params.passkey_display.passkey);
- break;
- #if NRF_SEC_PARAM_BLE==1
- case BLE_GAP_EVT_SEC_INFO_REQUEST:
- sd_ble_gap_sec_info_reply(m_conn_handle, &(m_own_enc_key.enc_info), NULL, NULL);
- // sec_params_display();
- NRF_LOG_INFO("BLE_GAP_EVT_SEC_INFO_REQUEST\n");
- break;
- case BLE_GAP_EVT_KEY_PRESSED:
- NRF_LOG_INFO("BLE_GAP_EVT_KEY_PRESSED\n");
- break;
- case BLE_GAP_EVT_AUTH_KEY_REQUEST:
- NRF_LOG_INFO("BLE_GAP_EVT_AUTH_KEY_REQUEST\n");
- break;
- case BLE_GAP_EVT_AUTH_STATUS:
- if(p_ble_evt->evt.gap_evt.params.auth_status.auth_status == BLE_GAP_SEC_STATUS_SUCCESS)
- {
- NRF_LOG_INFO("pair success\n");
- // sec_params_display();
- }
- else
- {
- NRF_LOG_INFO("pair error\n");
- 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);
- }
- break;
- #endif
- default:
- // No implementation needed.
- break;
- }
- }
- void Ble_Peripheral_Init(set_dfu_func func,uint16_t **conn_handle)
- {
- ret_code_t err_code;
-
- ble_per_s.dfu_func=func;
- *conn_handle=&m_conn_handle;
- gap_params_init();
- advertising_init();
- conn_params_init();
- #if NRF_SEC_PARAM_BLE==1
- peer_manager_init();
- #endif
- // Start execution.
- // NRF_LOG_INFO("Blinky example started.");
- advertising_start();
- }
- void set_ble_tx_power_level(int8_t rssi)
- {
- tx_power_level=rssi;
- }
- void set_ble_adv_interval(uint32_t time)
- {
- ble_adv_interval=time;
- }
- void Peripheral_Start(void)
- {
- // if(ble_per_s.dfu_stat==true)
- // {
- // return;
- // }
- advertising_stop();
- advertising_init();
- advertising_start();
- ble_adv_stat=true;
- }
- void Peripheral_Stop(void)
- {
- advertising_stop();
- ble_adv_stat=false;
- }
- void user_ble_advertising_modes_config_set(ble_adv_modes_config_t const * const p_adv_modes_config)
- {
- ble_advertising_modes_config_set(&m_advertising, p_adv_modes_config);
- }
- #if NRF_MODULE_ENABLED(BLE_DFU)
- /**@snippet [Handling the data received over BLE] */
- //检查是否准备好关机
- bool m_ready_for_reset=true;
- //关机准备处理程序。在关闭过程中,将以1秒的间隔调用此函数,直到函数返回true。当函数返回true时,表示应用程序已准备好复位为DFU模式
- static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event)
- {
- switch (event)
- {
- case NRF_PWR_MGMT_EVT_PREPARE_DFU:
- NRF_LOG_INFO("Power management wants to reset to DFU mode.");
- // YOUR_JOB: Get ready to reset into DFU mode
- //
- // If you aren't finished with any ongoing tasks, return "false" to
- // signal to the system that reset is impossible at this stage.
- //
- // Here is an example using a variable to delay resetting the device.
- //
- if (m_ready_for_reset==false)
- {
- return false;
- }
- // uint32_t err_code;
- // err_code = sd_softdevice_disable();
- // APP_ERROR_CHECK(err_code);
- // err_code = app_timer_stop_all();
- // APP_ERROR_CHECK(err_code);
- break;
- default:
- // YOUR_JOB: Implement any of the other events available from the power management module:
- // -NRF_PWR_MGMT_EVT_PREPARE_SYSOFF
- // -NRF_PWR_MGMT_EVT_PREPARE_WAKEUP
- // -NRF_PWR_MGMT_EVT_PREPARE_RESET
- return true;
- }
- NRF_LOG_INFO("Power management allowed to reset to DFU mode.");
- return true;
- }
- //注册优先级为0的应用程序关闭处理程序
- NRF_PWR_MGMT_HANDLER_REGISTER(app_shutdown_handler, 0);
- //SoftDevice状态监视者
- static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void * p_context)
- {
- if (state == NRF_SDH_EVT_STATE_DISABLED)
- {
- //表明Softdevice在复位之前已经禁用,告之bootloader启动时应跳过CRC
- nrf_power_gpregret2_set(BOOTLOADER_DFU_SKIP_CRC);
- //进入system off.
- nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
- }
- }
- //注册SoftDevice状态监视者,用于SoftDevice状态改变或者即将改变时接收SoftDevice事件
- NRF_SDH_STATE_OBSERVER(m_buttonless_dfu_state_obs, 0) =
- {
- .handler = buttonless_dfu_sdh_state_observer,
- };
- //获取广播模式、间隔和超时时间
- static void advertising_config_get(ble_adv_modes_config_t * p_config)
- {
- memset(p_config, 0, sizeof(ble_adv_modes_config_t));
- p_config->ble_adv_slow_enabled = false;
- p_config->ble_adv_slow_interval = NRF_BLE_ADV_INTERVAL;
- p_config->ble_adv_slow_timeout = NRF_BLE_ADV_DURATION;
- }
- //断开当前连接,设备准备进入bootloader之前,需要先断开连接
- static void disconnect(uint16_t conn_handle, void * p_context)
- {
- UNUSED_PARAMETER(p_context);
- //断开当前连接
- ret_code_t err_code = sd_ble_gap_disconnect(conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
- if (err_code != NRF_SUCCESS)
- {
- NRF_LOG_WARNING("Failed to disconnect connection. Connection handle: %d Error: %d", conn_handle, err_code);
- }
- else
- {
- NRF_LOG_DEBUG("Disconnected connection handle %d", conn_handle);
- }
- }
- //DFU事件处理函数。如果需要在DFU事件中执行操作,可以在相应的事件里面加入处理代码
- static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event)
- {
- switch (event)
- {
- //该事件指示设备正在准备进入bootloader
- case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
- {
- if(ble_per_s.dfu_func!=NULL)
- {
- ble_per_s.dfu_func(true);
- }
- // ble_per_s.dfu_stat=true;
- NRF_LOG_INFO("Device is preparing to enter bootloader mode.");
- //防止设备在断开连接时广播
- ble_adv_modes_config_t config;
- advertising_config_get(&config);
- //连接断开后设备不自动进行广播
- config.ble_adv_on_disconnect_disabled = true;
- //修改广播配置
- ble_advertising_modes_config_set(&m_advertising, &config);
- //断开当前已经连接的所有其他绑定设备。在设备固件更新成功(或中止)后,需要在启动时接收服务更改指示
- uint32_t conn_count = ble_conn_state_for_each_connected(disconnect, NULL);
- NRF_LOG_INFO("Disconnected %d links.", conn_count);
- break;
- }
- //该事件指示函数返回后设备即进入bootloader
- case BLE_DFU_EVT_BOOTLOADER_ENTER:
- //如果应用程序有数据需要保存到Flash,通过app_shutdown_handler返回flase以延迟复位,从而保证数据正确写入到Flash
- NRF_LOG_INFO("Device will enter bootloader mode.");
- break;
- //该事件指示进入bootloader失败
- case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:
- //进入bootloader失败,应用程序需要采取纠正措施来处理问题
- NRF_LOG_ERROR("Request to enter bootloader mode failed asynchroneously.");
- if(ble_per_s.dfu_func!=NULL)
- {
- ble_per_s.dfu_func(true);
- }
- else{
- NVIC_SystemReset();
- }
- break;
- //该事件指示发送响应失败
- case BLE_DFU_EVT_RESPONSE_SEND_ERROR:
- NRF_LOG_ERROR("Request to send a response to client failed.");
- //发送响应失败,应用程序需要采取纠正措施来处理问题
- APP_ERROR_CHECK(false);
- break;
- default:
- NRF_LOG_ERROR("Unknown event from ble_dfu_buttonless.");
- break;
- }
- }
- void dfu_service_init(void)
- {
- ret_code_t err_code;
- #if NRF_MODULE_ENABLED(BLE_DFU)
- //初始化DFU服务
- //定义DFU服务初始化结构体
- ble_dfu_buttonless_init_t dfus_init = {0};
- // Initialize the async SVCI interface to bootloader before any interrupts are enabled.
- err_code = ble_dfu_buttonless_async_svci_init();
- APP_ERROR_CHECK(err_code);
-
- dfus_init.evt_handler = ble_dfu_evt_handler;
- err_code = ble_dfu_buttonless_init(&dfus_init);
- APP_ERROR_CHECK(err_code);
- #endif
- }
- #endif
|