I am using a repeated app timer to count the number of seconds that pass from the start of the NRF system powering on (or the code being flashed into the NRF). The code below also shows the current number of seconds (m_custom_value) that has passed in a custom characteristic value field when notifications are enabled.
However, one issue I noticed is sometimes if I disable notifications I get an error 133(0x85): GATT error and then I get disconnected and get error 22(0x16) GATT CONN TERMINATE LOCAL HOST). I reconnect back to the NRF52 DK, but after I reconnect and turn on notifications I see that the m_custom_value has been reset back to 8 or a lower number than the number before the disconnection. I think the m_custom_value should only reset if the NRF system restarts. The m_custom_value should not be reset due to BLE disconnect. Is there anyway to fix or prevent this?
2. The second issue I am trying to figure out is how to save records of m_custom_value as it is being incremented. For example, if a sensor detects a change I want to save the current value of m_custom_value. I then want to pass the saved value as the custom characteristic's value (attr_char_value.p_value). I have tried doing this by using extern uint8_t global_time in both main.c and ble_cus.c. But when I read the custom characteristic value it is not the value of global_time. Am I using extern variable incorrectly, or is there something else wrong with my code?
Thanks!
// main.c static uint8_t m_custom_value = 0; static uint8_t notif_bool = 0; uint8_t global_time; static void notification_timeout_handler(void * p_context) { UNUSED_PARAMETER(p_context); ret_code_t err_code; // Increment the value of m_custom_value before notifying it. m_custom_value++; if (m_custom_value >= 3){ global_time = 3; } if(notif_bool == 1){ err_code = ble_cus_custom_value_update(&m_cus, m_custom_value); APP_ERROR_CHECK(err_code); } } static void on_cus_evt(ble_cus_t * p_cus_service, ble_cus_evt_t * p_evt) { ret_code_t err_code; switch(p_evt->evt_type) { case BLE_CUS_EVT_NOTIFICATION_ENABLED: //err_code = app_timer_start(m_notification_timer_id, NOTIFICATION_INTERVAL, NULL); //APP_ERROR_CHECK(err_code); notif_bool = 1; break; case BLE_CUS_EVT_NOTIFICATION_DISABLED: //err_code = app_timer_stop(m_notification_timer_id); //APP_ERROR_CHECK(err_code); break; case BLE_CUS_EVT_CONNECTED: break; case BLE_CUS_EVT_DISCONNECTED: break; default: // No implementation needed. break; } } static void application_timers_start(void) { ret_code_t err_code; err_code = app_timer_start(m_notification_timer_id, NOTIFICATION_INTERVAL, NULL); APP_ERROR_CHECK(err_code); } int main(void) { bool erase_bonds; // Initialize. log_init(); timers_init(); application_timers_start(); buttons_leds_init(&erase_bonds); power_management_init(); ble_stack_init(); gap_params_init(); gatt_init(); services_init(); advertising_init(); conn_params_init(); peer_manager_init(); // Start execution. NRF_LOG_INFO("Template example started."); //application_timers_start(); advertising_start(erase_bonds); // Enter main loop. for (;;) { idle_state_handle(); } }
// ble_cus.c extern uint8_t global_time; static uint32_t custom_value_char_add(ble_cus_t * p_cus, const ble_cus_init_t * p_cus_init) { uint32_t err_code; ble_gatts_char_md_t char_md; ble_gatts_attr_md_t cccd_md; ble_gatts_attr_t attr_char_value; ble_uuid_t ble_uuid; ble_gatts_attr_md_t attr_md; // Add Custom Value characteristic memset(&cccd_md, 0, sizeof(cccd_md)); // Read operation on cccd should be possible without authentication. BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); cccd_md.write_perm = p_cus_init->custom_value_char_attr_md.cccd_write_perm; cccd_md.vloc = BLE_GATTS_VLOC_STACK; memset(&char_md, 0, sizeof(char_md)); char_md.char_props.read = 1; char_md.char_props.write = 1; char_md.char_props.notify = 1; char_md.p_char_user_desc = NULL; char_md.p_char_pf = NULL; char_md.p_user_desc_md = NULL; char_md.p_cccd_md = &cccd_md; char_md.p_sccd_md = NULL; ble_uuid.type = p_cus->uuid_type; ble_uuid.uuid = CUSTOM_VALUE_CHAR_UUID; memset(&attr_md, 0, sizeof(attr_md)); attr_md.read_perm = p_cus_init->custom_value_char_attr_md.read_perm; attr_md.write_perm = p_cus_init->custom_value_char_attr_md.write_perm; attr_md.vloc = BLE_GATTS_VLOC_STACK; attr_md.rd_auth = 0; attr_md.wr_auth = 0; attr_md.vlen = 0; memset(&attr_char_value, 0, sizeof(attr_char_value)); attr_char_value.p_uuid = &ble_uuid; attr_char_value.p_attr_md = &attr_md; attr_char_value.init_len = sizeof(uint8_t); attr_char_value.init_offs = 0; attr_char_value.max_len = sizeof(uint8_t); if (global_time == 3){ attr_char_value.p_value = &global_time; } err_code = sd_ble_gatts_characteristic_add(p_cus->service_handle, &char_md, &attr_char_value, &p_cus->custom_value_handles); if (err_code != NRF_SUCCESS) { return err_code; } return NRF_SUCCESS; }