Hi Sir/Miss,
I use SDK 17.0.2 version and softdevice s112 7.2.0 version to develop in nrf52810.
And, I base on this project (NUS with static passkey) which imports CTS_C to my project. (reference ble_app_cts_c example)
Except that services, I add GLS, DIS and BAS.
For this requirement, add cts service in service_init(), current_time_error_handler, db_discovery_init and scheduler_init in project
static void on_cts_c_evt(ble_cts_c_t * p_cts, ble_cts_c_evt_t * p_evt)
{
ret_code_t err_code;
switch (p_evt->evt_type)
{
case BLE_CTS_C_EVT_DISCOVERY_COMPLETE:
NRF_LOG_INFO("Current Time Service discovered on server.");
err_code = ble_cts_c_handles_assign(&m_cts_c,
p_evt->conn_handle,
&p_evt->params.char_handles);
APP_ERROR_CHECK(err_code);
break;
case BLE_CTS_C_EVT_DISCOVERY_FAILED:
NRF_LOG_INFO("Current Time Service not found on server. ");
// CTS not found in this case we just disconnect. There is no reason to stay
// in the connection for this simple app since it all wants is to interact with CT
if (p_evt->conn_handle != BLE_CONN_HANDLE_INVALID)
{
err_code = sd_ble_gap_disconnect(p_evt->conn_handle,
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
APP_ERROR_CHECK(err_code);
}
break;
case BLE_CTS_C_EVT_DISCONN_COMPLETE:
NRF_LOG_INFO("Disconnect Complete.");
break;
case BLE_CTS_C_EVT_CURRENT_TIME:
NRF_LOG_INFO("Current Time received.");
current_time_print(p_evt);
break;
case BLE_CTS_C_EVT_INVALID_TIME:
NRF_LOG_INFO("Invalid Time received.");
break;
default:
break;
}
}
void services_init(void)
{
uint32_t err_code;
ble_nus_init_t nus_init;
ble_gls_init_t gls_init;
ble_dis_sys_id_t sys_id_init;
ble_bas_init_t bas_init;
nrf_ble_qwr_init_t qwr_init = {0};
ble_cts_c_init_t cts_init = {0};
// Initialize Queued Write Module.
qwr_init.error_handler = nrf_qwr_error_handler;
err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
APP_ERROR_CHECK(err_code);
// Initialize CTS.
cts_init.evt_handler = on_cts_c_evt;
cts_init.error_handler = current_time_error_handler;
cts_init.p_gatt_queue = &m_ble_gatt_queue;
err_code = ble_cts_c_init(&m_cts_c, &cts_init);
APP_ERROR_CHECK(err_code);
// Initialize Glucose Service - sample selection of feature bits.
memset(&gls_init, 0, sizeof(gls_init));
gls_init.evt_handler = NULL;
gls_init.p_gatt_queue = &m_ble_gatt_queue;
gls_init.error_handler = service_error_handler;
gls_init.feature = 0;
gls_init.feature |= BLE_GLS_FEATURE_LOW_BATT;
gls_init.feature |= BLE_GLS_FEATURE_TEMP_HIGH_LOW;
gls_init.feature |= BLE_GLS_FEATURE_GENERAL_FAULT;
gls_init.is_context_supported = false;
// Here the sec level for the Glucose Service can be changed/increased.
gls_init.gl_meas_cccd_wr_sec = SEC_MITM;//SEC_JUST_WORKS;
gls_init.gl_feature_rd_sec = SEC_MITM;//SEC_JUST_WORKS;
gls_init.racp_cccd_wr_sec = SEC_MITM;//SEC_JUST_WORKS;
gls_init.racp_wr_sec = SEC_MITM;//SEC_JUST_WORKS;
err_code = ble_gls_init(&m_gls, &gls_init);
APP_ERROR_CHECK(err_code);
// Initialize NUS.
memset(&nus_init, 0, sizeof(nus_init));
nus_init.data_handler = nus_data_handler;
err_code = ble_nus_init(&m_nus, &nus_init);
APP_ERROR_CHECK(err_code);
// Initialize Battery Service.
memset(&bas_init, 0, sizeof(bas_init));
// Here the sec level for the Battery Service can be changed/increased.
bas_init.bl_rd_sec = SEC_OPEN;
bas_init.bl_cccd_wr_sec = SEC_OPEN;
bas_init.bl_report_rd_sec = SEC_OPEN;
bas_init.evt_handler = NULL;
bas_init.support_notification = true;
bas_init.p_report_ref = NULL;
bas_init.initial_batt_level = 100;
err_code = ble_bas_init(&m_bas, &bas_init);
APP_ERROR_CHECK(err_code);
// Initialize Device Information Service.
memset(&dis_init, 0, sizeof(dis_init));
ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, MANUFACTURER_NAME);
ble_srv_ascii_to_utf8(&dis_init.serial_num_str, M_device_serial_num);
ble_srv_ascii_to_utf8(&dis_init.model_num_str, M_device_model_name);
ble_srv_ascii_to_utf8(&dis_init.hw_rev_str, M_device_pcb_ver);
ble_srv_ascii_to_utf8(&dis_init.fw_rev_str, M_device_fw_ver);
ble_srv_ascii_to_utf8(&dis_init.sw_rev_str, SW_VER);
dis_init.hw_rev_str.length = DEVICE_PCB_VER_LEN;
// Get device mac address
ble_gap_addr_t device_addr;
uint8_t temp_sys_manufacturer_id[5];
uint8_t temp_sys_organizationally_unique_id[3];
memset(&sys_id_init, 0, sizeof(sys_id_init));
err_code = sd_ble_gap_addr_get(&device_addr);
APP_ERROR_CHECK(err_code);
//uint8_t *a = device_addr->addr[0];
for(uint8_t i = 0; i < 6; i++)
{
if(i < 3)
temp_sys_organizationally_unique_id[2 - i] = device_addr.addr[i];
else
temp_sys_manufacturer_id[5 - i] = device_addr.addr[i];
}
temp_sys_manufacturer_id[3] = 0xFF;
temp_sys_manufacturer_id[4] = 0xFE;
uint32_t sys_manufacturer_id = 0, sys_organizationally_unique_id = 0;
sys_manufacturer_id |= temp_sys_manufacturer_id[0];
sys_manufacturer_id |= temp_sys_manufacturer_id[1] << 8;
sys_manufacturer_id |= temp_sys_manufacturer_id[2] << 16;
sys_manufacturer_id |= temp_sys_manufacturer_id[3] << 24;
sys_id_init.manufacturer_id = sys_manufacturer_id;
sys_id_init.manufacturer_id |= ((uint64_t)temp_sys_manufacturer_id[4] << 32);
sys_organizationally_unique_id |= temp_sys_organizationally_unique_id[0];
sys_organizationally_unique_id |= temp_sys_organizationally_unique_id[1] << 8;
sys_organizationally_unique_id |= temp_sys_organizationally_unique_id[2] << 16;
sys_id_init.organizationally_unique_id = sys_organizationally_unique_id;
dis_init.p_sys_id = &sys_id_init;
dis_init.dis_char_rd_sec = SEC_OPEN;
err_code = ble_dis_init(&dis_init);
APP_ERROR_CHECK(err_code);
}
void db_discovery_init(void)
{
ble_db_discovery_init_t db_init;
memset(&db_init, 0, sizeof(ble_db_discovery_init_t));
db_init.evt_handler = db_disc_handler;
db_init.p_gatt_queue = &m_ble_gatt_queue;
ret_code_t err_code = ble_db_discovery_init(&db_init);
APP_ERROR_CHECK(err_code);
}
My process is getting device name, FW version and etc from other's MCU. Then, nRF52810 starts advertising.
I use APP nRF connect to test it.
When APP connects with device, it can be discover CTS in advertised service.
But, it can not enter on_cts_evt in BLE_CTS_C_EVT_DISCOVERY_COMPLETE when I set break point in this code.
In cts_c example, it can have the event to enter this function.
Therefore, I can't get current time from phone.
Which part is missing in my project?
Please help.
Thank you.
