|
|
@ -19,8 +19,8 @@ static ble_uuid_t const m_nus_uuid = {.uuid = BLE_UUID_NUS_SERVICE, |
|
|
|
static on_sdk_event_t m_onSdkEvent; |
|
|
|
static uint16_t m_ble_connect_handle; |
|
|
|
static char m_bleScanFilterName[40]; |
|
|
|
static char m_slaveName[40]; |
|
|
|
static bool m_autoConnect = false; |
|
|
|
// static char m_slaveName[40]; |
|
|
|
static bool m_autoConnect = false; |
|
|
|
|
|
|
|
void assert_nrf_callback(uint16_t line_num, const uint8_t* p_file_name) { app_error_handler(0xDEADBEEF, line_num, p_file_name); } |
|
|
|
static void nus_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); } |
|
|
@ -37,12 +37,13 @@ static void scan_start(void) { |
|
|
|
const char* ble_find_name(uint8_t const* p_encoded_data, uint16_t data_len) { |
|
|
|
static char name[40] = {0}; |
|
|
|
memset(name, 0, sizeof(name)); |
|
|
|
uint16_t parsed_name_len; |
|
|
|
uint8_t const* p_parsed_name; |
|
|
|
uint16_t data_offset = 0; |
|
|
|
parsed_name_len = ble_advdata_search(p_encoded_data, data_len, &data_offset, BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME); |
|
|
|
p_parsed_name = &p_encoded_data[data_offset]; |
|
|
|
memcpy(name, p_parsed_name, parsed_name_len); |
|
|
|
uint16_t parsed_name_len; |
|
|
|
uint16_t data_offset = 0; |
|
|
|
parsed_name_len = ble_advdata_search(p_encoded_data, data_len, &data_offset, BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME); |
|
|
|
if (parsed_name_len != 0) { |
|
|
|
memcpy(name, &p_encoded_data[data_offset], parsed_name_len); |
|
|
|
return name; |
|
|
|
} |
|
|
|
return name; |
|
|
|
} |
|
|
|
|
|
|
@ -71,14 +72,28 @@ static ble_gap_conn_params_t m_conn_param = { |
|
|
|
|
|
|
|
static sdk_event_t connectEventCache; |
|
|
|
|
|
|
|
static bool nameIsEqWithHeader(const char* header, const char* name) { |
|
|
|
if (!header) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
if (strlen(name) < strlen(header)) return false; |
|
|
|
for (int i = 0; i < strlen(header); i++) { |
|
|
|
if (header[i] != name[i]) return false; |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static void onScanEvent(scan_evt_t const* p_scan_evt) { |
|
|
|
static sdk_event_t reportEvent; |
|
|
|
memset(&reportEvent, 0, sizeof(reportEvent)); |
|
|
|
|
|
|
|
ret_code_t err_code; |
|
|
|
ble_gap_evt_adv_report_t const* p_adv = p_scan_evt->params.filter_match.p_adv_report; |
|
|
|
ble_gap_scan_params_t const* p_scan_param = p_scan_evt->p_scan_params; |
|
|
|
if (NRF_BLE_SCAN_EVT_NOT_FOUND != p_scan_evt->scan_evt_id) NRF_LOG_INFO("on onScanEvent %d", p_scan_evt->scan_evt_id); |
|
|
|
ble_gap_evt_adv_report_t const* p_adv = p_scan_evt->params.filter_match.p_adv_report; |
|
|
|
ble_gap_scan_params_t const* p_scan_param = p_scan_evt->p_scan_params; |
|
|
|
const char* bleclientName = NULL; |
|
|
|
// if (NRF_BLE_SCAN_EVT_NOT_FOUND != p_scan_evt->scan_evt_id) NRF_LOG_INFO("on onScanEvent %d", p_scan_evt->scan_evt_id); |
|
|
|
|
|
|
|
switch (p_scan_evt->scan_evt_id) { |
|
|
|
case NRF_BLE_SCAN_EVT_CONNECTING_ERROR: { |
|
|
|
APP_ERROR_CHECK(p_scan_evt->params.connecting_err.err_code); |
|
|
@ -101,28 +116,32 @@ static void onScanEvent(scan_evt_t const* p_scan_evt) { |
|
|
|
|
|
|
|
case NRF_BLE_SCAN_EVT_FILTER_MATCH: { |
|
|
|
reportEvent.event = kevent_onScanResult; |
|
|
|
strcpy(reportEvent.data.on_scan_result.blename, ble_find_name(p_adv->data.p_data, p_adv->data.len)); |
|
|
|
reportEvent.data.on_scan_result.rssi = p_adv->rssi; |
|
|
|
reportEvent.data.on_scan_result.tx_power = p_adv->tx_power; |
|
|
|
memcpy(reportEvent.data.on_scan_result.peeradd, p_adv->peer_addr.addr, BLE_GAP_ADDR_LEN); |
|
|
|
m_onSdkEvent(&reportEvent); |
|
|
|
|
|
|
|
if (m_autoConnect) { |
|
|
|
if (strcmp(ble_find_name(p_adv->data.p_data, p_adv->data.len), m_slaveName) == 0) { |
|
|
|
NRF_LOG_INFO("Device \"%s\" found, sending a connection request.", ble_find_name(p_adv->data.p_data, p_adv->data.len)); |
|
|
|
err_code = sd_ble_gap_connect(&p_adv->peer_addr, p_scan_param, &m_conn_param, APP_BLE_CONN_CFG_TAG); |
|
|
|
if (err_code != NRF_SUCCESS) { |
|
|
|
NRF_LOG_ERROR("sd_ble_gap_connect() failed: 0x%x.", err_code); |
|
|
|
bleclientName = ble_find_name(p_adv->data.p_data, p_adv->data.len); |
|
|
|
if (bleclientName && strlen(bleclientName) != 0) { |
|
|
|
// report scan result |
|
|
|
strcpy(reportEvent.data.on_scan_result.blename, bleclientName); |
|
|
|
reportEvent.data.on_scan_result.rssi = p_adv->rssi; |
|
|
|
reportEvent.data.on_scan_result.tx_power = p_adv->tx_power; |
|
|
|
memcpy(reportEvent.data.on_scan_result.peeradd, p_adv->peer_addr.addr, BLE_GAP_ADDR_LEN); |
|
|
|
m_onSdkEvent(&reportEvent); |
|
|
|
|
|
|
|
if (m_autoConnect) { |
|
|
|
if (nameIsEqWithHeader(m_bleScanFilterName, bleclientName)) { |
|
|
|
NRF_LOG_INFO("Device \"%s\" found, sending a connection request.", bleclientName); |
|
|
|
err_code = sd_ble_gap_connect(&p_adv->peer_addr, p_scan_param, &m_conn_param, APP_BLE_CONN_CFG_TAG); |
|
|
|
if (err_code != NRF_SUCCESS) { |
|
|
|
NRF_LOG_ERROR("sd_ble_gap_connect() failed: 0x%x.", err_code); |
|
|
|
} |
|
|
|
|
|
|
|
connectEventCache.event = kevent_connected; |
|
|
|
strcpy(connectEventCache.data.on_connect.blename, bleclientName); |
|
|
|
connectEventCache.data.on_connect.rssi = p_adv->rssi; |
|
|
|
connectEventCache.data.on_connect.tx_power = p_adv->tx_power; |
|
|
|
memcpy(connectEventCache.data.on_connect.peeradd, p_adv->peer_addr.addr, BLE_GAP_ADDR_LEN); |
|
|
|
} |
|
|
|
|
|
|
|
connectEventCache.event = kevent_connected; |
|
|
|
strcpy(connectEventCache.data.on_connect.blename, ble_find_name(p_adv->data.p_data, p_adv->data.len)); |
|
|
|
connectEventCache.data.on_connect.rssi = p_adv->rssi; |
|
|
|
connectEventCache.data.on_connect.tx_power = p_adv->tx_power; |
|
|
|
memcpy(connectEventCache.data.on_connect.peeradd, p_adv->peer_addr.addr, BLE_GAP_ADDR_LEN); |
|
|
|
// ÑÓºóÉϱ¨ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} break; |
|
|
|
default: |
|
|
|
break; |
|
|
@ -152,12 +171,6 @@ static void onBleNusEvent(ble_nus_c_t* p_ble_nus_c, ble_nus_c_evt_t const* p_ble |
|
|
|
event.data.on_ble_data.length = p_ble_nus_evt->data_len; |
|
|
|
m_onSdkEvent(&event); |
|
|
|
break; |
|
|
|
case BLE_NUS_C_EVT_NUS_TX_EVT_2: |
|
|
|
event.event = kevent_onRxData; |
|
|
|
event.data.on_ble_data.data = p_ble_nus_evt->p_data; |
|
|
|
event.data.on_ble_data.length = p_ble_nus_evt->data_len; |
|
|
|
m_onSdkEvent(&event); |
|
|
|
break; |
|
|
|
|
|
|
|
case BLE_NUS_C_EVT_DISCONNECTED: |
|
|
|
NRF_LOG_INFO("Disconnected."); |
|
|
@ -235,6 +248,7 @@ static void ondbDiscoveryEvent(ble_db_discovery_evt_t* p_evt) { ble_nus_c_on_db_ |
|
|
|
/*********************************************************************************************************************** |
|
|
|
* BLE_INIT * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
|
|
|
|
static void scan_init(void) { |
|
|
|
ret_code_t err_code; |
|
|
|
nrf_ble_scan_init_t init_scan; |
|
|
@ -247,9 +261,14 @@ static void scan_init(void) { |
|
|
|
err_code = nrf_ble_scan_init(&m_scan, &init_scan, onScanEvent); |
|
|
|
APP_ERROR_CHECK(err_code); |
|
|
|
|
|
|
|
APP_ERROR_CHECK(nrf_ble_scan_filter_set(&m_scan, SCAN_NAME_FILTER, m_bleScanFilterName)); |
|
|
|
err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_NAME_FILTER, false); |
|
|
|
APP_ERROR_CHECK(err_code); |
|
|
|
// err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_UUID_FILTER, &m_nus_uuid); |
|
|
|
// APP_ERROR_CHECK(err_code); |
|
|
|
// nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_UUID_FILTER, false); |
|
|
|
|
|
|
|
// APP_ERROR_CHECK(err_code); |
|
|
|
// strcpy(m_bleScanFilterName, "AciDisp"); |
|
|
|
// APP_ERROR_CHECK(nrf_ble_scan_filter_set(&m_scan, SCAN_NAME_FILTER, m_bleScanFilterName)); |
|
|
|
// err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_NAME_FILTER, false); |
|
|
|
} |
|
|
|
static void ble_stack_init(void) { |
|
|
|
ret_code_t err_code; |
|
|
@ -286,12 +305,11 @@ static void nus_c_init(void) { |
|
|
|
APP_ERROR_CHECK(err_code); |
|
|
|
} |
|
|
|
|
|
|
|
void zble_master_sdk_init(const char* bleScanFilterName, const char* slaveName, bool autoConnect, on_sdk_event_t onSdkEvent) { |
|
|
|
void zble_master_sdk_init(const char* bleScanFilterName, bool autoConnect, on_sdk_event_t onSdkEvent) { |
|
|
|
// APP_ERROR_HANDLER(onSdkEvent != NULL); |
|
|
|
// APP_ERROR_HANDLER(bleScanFilterName != NULL); |
|
|
|
|
|
|
|
if (!bleScanFilterName) bleScanFilterName = ""; |
|
|
|
memcpy(m_bleScanFilterName, bleScanFilterName, strlen(bleScanFilterName)); |
|
|
|
if (slaveName) memcpy(m_slaveName, slaveName, strlen(slaveName)); |
|
|
|
m_onSdkEvent = onSdkEvent; |
|
|
|
m_autoConnect = autoConnect; |
|
|
|
|
|
|
@ -318,30 +336,21 @@ void zble_master_sdk_init(const char* bleScanFilterName, const char* slaveName, |
|
|
|
} |
|
|
|
|
|
|
|
void zble_master_sdk_ble_tx(uint8_t* data, int32_t len) { ble_nus_c_string_send(&m_ble_nus_c, data, len); } |
|
|
|
|
|
|
|
void zble_master_sdk_rescan(const char* slaveName, bool autoConnected) { |
|
|
|
// |
|
|
|
uint16_t connect_handle = 0; |
|
|
|
CRITICAL_REGION_ENTER(); |
|
|
|
if (slaveName == NULL) { |
|
|
|
memset(m_slaveName, 0, sizeof(m_slaveName)); |
|
|
|
} else { |
|
|
|
memcpy(m_slaveName, slaveName, strlen(slaveName)); |
|
|
|
memset(m_bleScanFilterName, 0, sizeof(m_bleScanFilterName)); |
|
|
|
if (!slaveName) { |
|
|
|
memcpy(m_bleScanFilterName, slaveName, strlen(slaveName)); |
|
|
|
} |
|
|
|
m_autoConnect = autoConnected; |
|
|
|
connect_handle = m_ble_connect_handle; |
|
|
|
CRITICAL_REGION_EXIT(); |
|
|
|
|
|
|
|
if (connect_handle != 0) { |
|
|
|
sd_ble_gap_disconnect(connect_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void zble_master_sdk_set_slave_name(const char* slaveName) { |
|
|
|
CRITICAL_REGION_ENTER(); |
|
|
|
if (slaveName == NULL) { |
|
|
|
memset(m_slaveName, 0, sizeof(m_slaveName)); |
|
|
|
} else { |
|
|
|
memcpy(m_slaveName, slaveName, strlen(slaveName)); |
|
|
|
uint32_t ecode = sd_ble_gap_disconnect(connect_handle, BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION); |
|
|
|
NRF_LOG_DEBUG("sd_ble_gap_disconnect ecode:%d", ecode); |
|
|
|
} |
|
|
|
CRITICAL_REGION_EXIT(); |
|
|
|
} |