-
增加gatt_init初时化函数,并在协议栈初时化之后调用,gatt_init内容如下
NRF_BLE_GATT_DEF(m_gatt);
void gatt_init(void)
{
ret_code_t err_code;
err_code = nrf_ble_gatt_init(&m_gatt, NULL);
APP_ERROR_CHECK(err_code);
}
-
修改advertising_init函数内容如下
#include "ble_advertising.h"
BLE_ADVERTISING_DEF(m_advertising);
/**@brief Function for handling advertising events.
*
* @param[in] ble_adv_evt Advertising event.
*/
static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
switch (ble_adv_evt)
{
case BLE_ADV_EVT_FAST:
{
} break;
case BLE_ADV_EVT_IDLE:
{
ret_code_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code);
} break;
default:
// No implementation needed.
break;
}
}
/**@brief Advertising functionality initialization.
*
* @details Encodes the required advertising data and passes it to the stack.
* Also builds a structure to be passed to the stack when starting advertising.
*/
void advertising_init(void)
{
uint32_t err_code;
ble_advertising_init_t init;
uint8_t flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
memset(&init, 0, sizeof(init));
init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
init.advdata.include_appearance = true;
init.advdata.flags = flags;
NRF_LOG_INFO("ble_advdata_set");
init.config.ble_adv_fast_enabled = true;
init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
init.config.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS;
err_code = ble_advdata_set(&init.advdata, NULL);
APP_ERROR_CHECK(err_code);
NRF_LOG_INFO("init");
init.evt_handler = on_adv_evt;
err_code = ble_advertising_init(&m_advertising, &init);
APP_ERROR_CHECK(err_code);
ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
}
-
修改advertising_start函数内容如下
/**@brief Start advertising.
*/
static void advertising_start(void)
{
ret_code_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code);
}
-
修改ble_evt_handler函数内容如下
/**@brief Function for dispatching a BLE stack event to all modules with a BLE stack event handler.
*
* @param[in] p_ble_evt Bluetooth stack event.
* @param[in] p_context Context.
*/
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
ret_code_t err_code = NRF_SUCCESS;
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;
// Need to close the ANT channel to make it safe to write bonding information to flash
// Note: Bonding information will be stored, advertising will be restarted and the
// ANT channel will be reopened when ANT event CHANNEL_CLOSED is received.
break;
#ifndef S140
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);
APP_ERROR_CHECK(err_code);
} break;
#endif
//Jun add at Dec 28,2018
#ifndef BONDING_ENABLE
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
err_code = sd_ble_gap_sec_params_reply(m_conn_handle,
BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,
NULL,
NULL);
APP_ERROR_CHECK(err_code);
break;
#endif // BONDING_ENABLE
case BLE_GAP_EVT_TIMEOUT:
if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING)
{
}
break;
case BLE_GATTC_EVT_TIMEOUT:
// Disconnect on GATT Client timeout event.
NRF_LOG_DEBUG("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_DEBUG("GATT Server Timeout.");
if (p_ble_evt->evt.gatts_evt.params.timeout.src == BLE_GATT_TIMEOUT_SRC_PROTOCOL)
{
err_code = sd_ble_gap_disconnect(m_conn_handle,BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
}
break;
case BLE_EVT_USER_MEM_REQUEST:
err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gap_evt.conn_handle, NULL);
APP_ERROR_CHECK(err_code);
break;
case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
{
ble_gatts_evt_rw_authorize_request_t req;
ble_gatts_rw_authorize_reply_params_t auth_reply;
req = p_ble_evt->evt.gatts_evt.params.authorize_request;
if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
{
if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) ||
(req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
(req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
{
if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
{
auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
}
else
{
auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
}
auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle,
&auth_reply);
APP_ERROR_CHECK(err_code);
}
}
} break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST
case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
err_code=sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
APP_ERROR_CHECK(err_code);
break; //BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST
//#ifndef BONDING_ENABLE
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
err_code = sd_ble_gatts_sys_attr_set(m_conn_handle,
NULL,
0,
BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);
APP_ERROR_CHECK(err_code);
break;
//#endif // BONDING_ENABLE
case BLE_EVT_TX_COMPLETE:
{
}
break;
default:
// No implementation needed.
break;
}
}
Demo链接
https://download.csdn.net/download/mygod2008ok/19004345
-
在原例程上,另一种解决方案,共3步可解决iphone不能连接问题
-
定义GATT变量
NRF_BLE_GATT_DEF(m_gatt);
-
增加gatt_init函数,并在主函数协议栈初时化后调用
/**@brief Function for initializing the GATT module.
*/
static void gatt_init(void)
{
ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, NULL);
APP_ERROR_CHECK(err_code);
}
-
在ble_evt_handler函数中增加BLE_GAP_EVT_PHY_UPDATE_REQUEST事件处理
/**@brief Function for dispatching a BLE stack event to all modules with a BLE stack event handler.
*
* @param[in] p_ble_evt Bluetooth stack event.
* @param[in] p_context Context.
*/
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
ret_code_t err_code = NRF_SUCCESS;
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;
// Need to close the ANT channel to make it safe to write bonding information to flash
err_code = sd_ant_channel_close(ANT_HRMRX_ANT_CHANNEL);
APP_ERROR_CHECK(err_code);
// Note: Bonding information will be stored, advertising will be restarted and the
// ANT channel will be reopened when ANT event CHANNEL_CLOSED is received.
break;
#ifndef S140
case BLE_GAP_EVT_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;
#endif
#ifndef BONDING_ENABLE
case BLE_GAP_EVT_SEC_INFO_REQUEST:
err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL, NULL);
APP_ERROR_CHECK(err_code);
break;
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
err_code = sd_ble_gap_sec_params_reply(m_conn_handle,
BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,
NULL,
NULL);
APP_ERROR_CHECK(err_code);
break;
#endif // BONDING_ENABLE
case BLE_GAP_EVT_TIMEOUT:
if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING)
{
// Go to system-off mode (this function will not return; wakeup will cause a reset)
}
break;
#ifndef BONDING_ENABLE
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
err_code = sd_ble_gatts_sys_attr_set(m_conn_handle,
NULL,
0,
BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);
APP_ERROR_CHECK(err_code);
break;
#endif // BONDING_ENABLE
default:
// No implementation needed.
break;
}
}