主要来自http://www.cnblogs.com/bhlsheji/p/5340092.html
ble_app_proximity 程序,事实上跟防丢有关的程序
打开sdk包路径:D:\myfile\test\examples\ble_peripheral\ble_app_proximity\pca10028\s130\arm5_no_packs
1. TX Power Service 发射功率服务 :
该服务主要条件蓝牙的发射功率,从而影响设备与手机蓝牙通信距离 :
/**@brief Function for initializing the TX Power Service.
#define TX_POWER_LEVEL (0)
static void tps_init(void)
{
uint32_t err_code;
ble_tps_init_t tps_init_obj;
memset(&tps_init_obj, 0, sizeof(tps_init_obj));
tps_init_obj.initial_tx_power_level = TX_POWER_LEVEL;
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&tps_init_obj.tps_attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&tps_init_obj.tps_attr_md.write_perm);
err_code = ble_tps_init(&m_tps, &tps_init_obj);
APP_ERROR_CHECK(err_code);
}
TX_POWER_LEVEL的范围 是4 到-20db 随着数据的减小,通信距离变短
2.Immediate Alert Service 即时报警服务
该服务能够通过手机APP 找到设备 蓝牙建立连接之后,在手机的 APP中有 Find Mebutton有效,按下Find Me ,开发板的灯会亮,这个时候 Find Mebutton 变成Silent Mebutton ,在按下Silent Mebutton 相应灯会灭,相比5介绍的Immediate Alert Service client 是一个相反的寻找方式。
/**@brief Function for initializing the Immediate Alert Service.
*/
static void ias_init(void)
{
uint32_t err_code;
ble_ias_init_t ias_init_obj;
memset(&ias_init_obj, 0, sizeof(ias_init_obj));
ias_init_obj.evt_handler = on_ias_evt;
err_code = ble_ias_init(&m_ias, &ias_init_obj);
APP_ERROR_CHECK(err_code);
}
通过点击手机APP中的 Find Mebutton 或Silent Mebutton切换,会进入函数执行相应的灯ON/OFF,
static void on_ias_evt(ble_ias_t * p_ias, ble_ias_evt_t * p_evt)
{
switch (p_evt->evt_type)
{
case BLE_IAS_EVT_ALERT_LEVEL_UPDATED:
alert_signal(p_evt->params.alert_level);
break;//BLE_IAS_EVT_ALERT_LEVEL_UPDATED
default:
// No implementation needed.
break;
}
}
通过手机直接控制设备或在蓝牙断开时,设备会执行灯闪烁或报警
/**@brief Function for the Signals alert event from Immediate Alert or Link Loss services.
*
* @param[in] alert_level Requested alert level.
*/
static void alert_signal(uint8_t alert_level)
{
uint32_t err_code;
switch (alert_level)
{
case BLE_CHAR_ALERT_LEVEL_NO_ALERT:
err_code = bsp_indication_set(BSP_INDICATE_ALERT_OFF);
APP_ERROR_CHECK(err_code);
NRF_LOG_DEBUG("BLE_CHAR_ALERT_LEVEL_NO_ALERT\r\n");
break;//BLE_CHAR_ALERT_LEVEL_NO_ALERT
case BLE_CHAR_ALERT_LEVEL_MILD_ALERT:
err_code = bsp_indication_set(BSP_INDICATE_ALERT_0);
APP_ERROR_CHECK(err_code);
NRF_LOG_DEBUG("BLE_CHAR_ALERT_LEVEL_MILD_ALERT\r\n");
break;//BLE_CHAR_ALERT_LEVEL_MILD_ALERT
case BLE_CHAR_ALERT_LEVEL_HIGH_ALERT:
NRF_LOG_DEBUG("BLE_CHAR_ALERT_LEVEL_HIGH_ALERT\r\n");
err_code = bsp_indication_set(BSP_INDICATE_ALERT_3);
APP_ERROR_CHECK(err_code);
break;//BLE_CHAR_ALERT_LEVEL_HIGH_ALERT
default:
// No implementation needed.
break;
}
}
3.Link Loss Service 连接丢失服务
当连接丢失之后(有可能是电池没电或者分离APP太远)都会导致连接丢失事件,丢失后会通过通知的方式发送到手机APP,手机依据
该事件做出响应, 程序中使用通知的方式显示出来,
/**@brief Function for initializing the Link Loss Service.
*/
static void lls_init(void)
{
uint32_t err_code;
ble_lls_init_t lls_init_obj;
// Initialize Link Loss Service
memset(&lls_init_obj, 0, sizeof(lls_init_obj));
lls_init_obj.evt_handler = on_lls_evt;
lls_init_obj.error_handler = service_error_handler;
lls_init_obj.initial_alert_level = INITIAL_LLS_ALERT_LEVEL;
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&lls_init_obj.lls_attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&lls_init_obj.lls_attr_md.write_perm);
err_code = ble_lls_init(&m_lls, &lls_init_obj);
APP_ERROR_CHECK(err_code);
}
蓝牙断开或者关机会进入 on_lls_evt 函数中,执行相应的报警或灯的控制
/**@brief Function for handling Link Loss events.
*
* @details This function will be called for all Link Loss events which are passed to the
* application.
*
* @param[in] p_lls Link Loss structure.
* @param[in] p_evt Event received from the Link Loss service.
*/
static void on_lls_evt(ble_lls_t * p_lls, ble_lls_evt_t * p_evt)
{
switch (p_evt->evt_type)
{
case BLE_LLS_EVT_LINK_LOSS_ALERT:
alert_signal(p_evt->params.alert_level);
break;//BLE_LLS_EVT_LINK_LOSS_ALERT
default:
// No implementation needed.
break;
}
}
4. Battery Service 电池服务
通过AD采样电池电压,发送到手机APP
5. Immediate Alert Service client -location role of the Find Me profile 定位器服务
该服务能够使用按键报警服务,按键按下,在按键处理程序中设置好报警的级别之后,通过蓝牙发送到手机APP,APP已经报警级别做不同的动作,
程序通过按键控制手机响铃和停止响铃。
/**@brief Function for initializing the immediate alert service client.
static void ias_client_init(void)
{
uint32_t err_code;
ble_ias_c_init_t ias_c_init_obj;
memset(&ias_c_init_obj, 0, sizeof(ias_c_init_obj));
m_is_high_alert_signalled = false;
ias_c_init_obj.evt_handler = on_ias_c_evt;
ias_c_init_obj.error_handler = service_error_handler;
err_code = ble_ias_c_init(&m_ias_c, &ias_c_init_obj);
APP_ERROR_CHECK(err_code);
}
通过按键来控制手机报警,按一下手机报警响,再次按下手机报警关
/**@brief Function for initializing buttons and leds.
*
* @param[out] p_erase_bonds Will be true if the clear bonding button was pressed to wake the application up.
*/
static void buttons_leds_init(bool * p_erase_bonds)
{
bsp_event_t startup_event;
uint32_t err_code = bsp_init(BSP_INIT_LED|BSP_INIT_BUTTONS,
APP_TIMER_TICKS(100, APP_TIMER_PRESCALER),
bsp_event_handler);//BSP_INIT_LED |BSP_INIT_BUTTONS,
APP_ERROR_CHECK(err_code);
err_code = bsp_btn_ble_init(NULL, &startup_event);
APP_ERROR_CHECK(err_code);
*p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
}
/**@brief Function for handling events from the BSP module.
*
* @param[in] event Event generated when button is pressed.
*/
static void bsp_event_handler(bsp_event_t event)
{
uint32_t err_code;
switch (event)
{
case BSP_EVENT_SLEEP:
// sleep_mode_enter();
break;//BSP_EVENT_SLEEP
case BSP_EVENT_DISCONNECT:
err_code = sd_ble_gap_disconnect(m_ias_c.conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
if (err_code != NRF_ERROR_INVALID_STATE)
{
APP_ERROR_CHECK(err_code);
}
break;//BSP_EVENT_DISCONNECT
case BSP_EVENT_KEY_0:
{
if (m_is_ias_present)
{
if (!m_is_high_alert_signalled)
{
err_code =
ble_ias_c_send_alert_level(&m_ias_c, BLE_CHAR_ALERT_LEVEL_HIGH_ALERT);
NRF_LOG_DEBUG("m_is_high_alert_signalled000\r\n");
}
else
{
err_code = ble_ias_c_send_alert_level(&m_ias_c, BLE_CHAR_ALERT_LEVEL_NO_ALERT);
NRF_LOG_DEBUG("m_is_high_alert_signalled111\r\n");
}
if (err_code == NRF_SUCCESS)
{
m_is_high_alert_signalled = !m_is_high_alert_signalled;
}
else if (
(err_code != BLE_ERROR_NO_TX_PACKETS)
&&
(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
&&
(err_code != NRF_ERROR_NOT_FOUND)
)
{
APP_ERROR_HANDLER(err_code);
}
}
}break;//BSP_EVENT_KEY_0
case BSP_EVENT_KEY_1: // STOP_ALERTING_BUTTON_ID
err_code = bsp_indication_set(BSP_INDICATE_ALERT_OFF);
APP_ERROR_CHECK(err_code);
break;//BSP_EVENT_KEY_1
default:
break;
}
}