hi, I am updating the sdk from 12.2.0 to 14.2.0, and using softdevice s132. I get a problem by connecting device using ios devices, but it works fine with android device. do you know what should I do?
hi, I am updating the sdk from 12.2.0 to 14.2.0, and using softdevice s132. I get a problem by connecting device using ios devices, but it works fine with android device. do you know what should I do?
Hi,
What are you using to connect to your device? nRF Connect? nRF Toolbox? Any error codes?
Did it work with SDK12.2.0 before you migrated to SDK14.2.0?
Did you follow the migration guides? Guide for migration: from SDK12.2.0 to SDK13.0.0, and from SDK13.0.0 to SDK14.0.0.
Yes, I followed that. I just posted my application code, I am still not sure what's wrong. I just feel that if there is anything wrong happened during I switch sdk, then how it still work on an android system. On ios, I can still get the advertising message, after I click connect in nrf connect it keeping connecting, but nothing shows up.
#include <stdbool.h> #include <stdint.h> #include <string.h> #include "nordic_common.h" #include "nrf.h" #include "nrf_sdm.h" #include "nrf_sdh.h" #include "nrf_sdh_soc.h" #include "nrf_sdh_ble.h" #include "nrf_ble_gatt.h" #include "ble.h" #include "ble_err.h" #include "ble_hci.h" #include "ble_srv_common.h" #include "ble_advdata.h" #include "ble_advertising.h" #include "ble_conn_params.h" #include "ble_conn_state.h" #include "ble_dis.h" #include "app_timer.h" #include "app_error.h" #include "water_fountain_config.h" #include "sinnoz_ble_water_fountain.h" #include "application_timers.h" #include "real_time_clock.h" #include "history_database.h" #include "sinnoz_ble_wfs.h" #include "sinnoz_ble_hists.h" #include "sinnoz_ble_utcs.h" #include "uart.h" #define DEVICE_NAME "Water Fountain" #define MANUFACTURER_NAME "Sinnoz" #define MODEL_NUM "WF-X001" #define SERIAL_NUM "SmartPetDevice" #define MANUFACTURER_ID 0x1122334455 #define ORG_UNIQUE_ID 0x667788 #define SINNOZ_COMPANY_ID 0x054F #define BLE_TX_POWER_LEVEL 4 #define APP_FEATURE_NOT_SUPPORTED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2 /**< Reply when unsupported features are requested. */ #define APP_ADV_INTERVAL 64 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */ #define APP_ADV_TIMEOUT_IN_SECONDS BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED /**< The advertising time-out (in units of seconds). When set to 0, we will never time out. */ #define APP_BLE_OBSERVER_PRIO 3 /**< Application's BLE observer priority. You shouldn't need to modify this value. */ #define APP_BLE_CONN_CFG_TAG 1 /**< A tag identifying the SoftDevice BLE configuration. */ #define LINK_TOTAL NRF_SDH_BLE_PERIPHERAL_LINK_COUNT + \ NRF_SDH_BLE_CENTRAL_LINK_COUNT #define MIN_CONN_INTERVAL MSEC_TO_UNITS(100, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.1 seconds). */ #define MAX_CONN_INTERVAL MSEC_TO_UNITS(200, UNIT_1_25_MS) /**< Maximum acceptable connection interval (0.2 second). */ #define SLAVE_LATENCY 0 /**< Slave latency. */ #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds). */ #define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(20000) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (15 seconds). */ #define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (5 seconds). */ #define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */ #define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */ NRF_BLE_GATT_DEF(m_gatt); /**< GATT module instance. */ BLE_ADVERTISING_DEF(m_advertising); /**< Advertising module instance. */ SINNOZ_BLE_WFS_DEF(sinnoz_wfs); SINNOZ_BLE_HISTS_DEF(sinnoz_hists); SINNOZ_BLE_UTCS_DEF(sinnoz_utcs); static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */ uint8_t _system_mode_ = 1; uint8_t _water_level_low_ = 0; // static sinnoz_ble_wfs_t sinnoz_wfs; // static sinnoz_ble_hists_t sinnoz_hists; // static sinnoz_ble_utcs_t sinnoz_utcs; void on_water_level_update_handler(void) { uint8_t i; sdk_mapped_flags_key_list_t conn_handles = ble_conn_state_periph_handles(); uart_writef(CTRL_DATA_PRINT, "CTRL: WATER WEIGHT - %04x\r\n", water_weight); for (i = 0; i < conn_handles.len; i++) { sinnoz_ble_wfs_water_level_update(conn_handles.flag_keys[i], &sinnoz_wfs, (water_weight < 0) ? 0 : water_weight); } } void on_system_mode_change_handler(void) { uint8_t i; sdk_mapped_flags_key_list_t conn_handles = ble_conn_state_periph_handles(); uart_writef(CTRL_DATA_PRINT, "CTRL: SYSTEM MODE CHANGE - %02x\r\n", system_mode); for (i = 0; i < conn_handles.len; i++) { sinnoz_ble_wfs_on_system_mode_change(conn_handles.flag_keys[i], &sinnoz_wfs, system_mode); } } void on_low_water_warning_handler(void) { uint8_t i; sdk_mapped_flags_key_list_t conn_handles = ble_conn_state_periph_handles(); uart_writef(CTRL_DATA_PRINT, "CTRL: WATER LEVEL STATUS - %02x\r\n", water_level_status); for (i = 0; i < conn_handles.len; i++) { sinnoz_ble_wfs_on_low_water_change(conn_handles.flag_keys[i], &sinnoz_wfs, water_level_status); } } void on_hist_data_flush_handler(void) { uint8_t i; sdk_mapped_flags_key_list_t conn_handles = ble_conn_state_periph_handles(); uint8_t hist_data[DATA_BUF_SIZE]; if (hist_data_count > 0) { hist_data_count = hist_db_pop(hist_data); for (i = 0; i < conn_handles.len; i++) { sinnoz_ble_hists_data_update(conn_handles.flag_keys[i], &sinnoz_hists, hist_data); sinnoz_ble_hists_counts_update(conn_handles.flag_keys[i], &sinnoz_hists, hist_data_count); } } else { history_transmit_timer_stop(); for (i = 0; i < conn_handles.len; i++) { sinnoz_ble_hists_counts_update(conn_handles.flag_keys[i], &sinnoz_hists, hist_data_count); } } } void on_hist_data_count_update_handler(void) { uint8_t i; sdk_mapped_flags_key_list_t conn_handles = ble_conn_state_periph_handles(); for (i = 0; i < conn_handles.len; i++) { sinnoz_ble_hists_counts_update(conn_handles.flag_keys[i], &sinnoz_hists, hist_data_count); } } /**@brief Callback function for asserts in the SoftDevice. * * @details This function will be called in case of an assert in the SoftDevice. * * @warning This handler is an example only and does not fit a final product. You need to analyze * how your product is supposed to react in case of Assert. * @warning On assert from the SoftDevice, the system can only recover on reset. * * @param[in] line_num Line number of the failing ASSERT call. * @param[in] file_name File name of the failing ASSERT call. */ void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name) { app_error_handler(DEAD_BEEF, line_num, p_file_name); } /**@brief Function for the GAP initialization. * * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the * device including the device name, appearance, and the preferred connection parameters. */ static void gap_params_init(void) { uint32_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); // Store the device name and security mode in the SoftDevice. err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *) DEVICE_NAME, strlen(DEVICE_NAME)); uart_writef(ERR_CODE_PRINT, "ERROR CODE: SET DEVICE NAME - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); // Always initialize all fields in structs to zero or you might get unexpected behaviour memset(&gap_conn_params, 0, sizeof(gap_conn_params)); // Populate the GAP connection parameter struct gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; // Set GAP Peripheral Preferred Connection Parameters // The device use these prefered values when negotiating connection terms with another device err_code = sd_ble_gap_ppcp_set(&gap_conn_params); uart_writef(ERR_CODE_PRINT, "ERROR CODE: SET PPCP - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); // Set appearence err_code = sd_ble_gap_appearance_set(0); uart_writef(ERR_CODE_PRINT, "ERROR CODE: SET APPEARENCE - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code);// Check for errors // Set tx power level err_code = sd_ble_gap_tx_power_set(BLE_TX_POWER_LEVEL); uart_writef(ERR_CODE_PRINT, "ERROR CODE: SET TX POWER - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code);// Check for errors } /**@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); } /**@brief Function for handling the Connection Parameters Module. * * @details This function will be called for all events in the Connection Parameters Module which * are passed to the application. * @note All this function does is to disconnect. This could have been done by simply * setting the disconnect_on_fail config parameter, but instead we use the event * handler mechanism to demonstrate its use. * * @param[in] p_evt Event received from the Connection Parameters Module. */ static void on_conn_params_evt(ble_conn_params_evt_t * p_evt) { uint32_t err_code; if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) { err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); uart_writef(ERR_CODE_PRINT, "ERROR CODE: ON CONN PARAMS EVT - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); } } /**@brief Function for handling a Connection Parameters error. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void conn_params_error_handler(uint32_t nrf_error) { uart_writef(ERR_CODE_PRINT, "ERROR CODE: COON PARAMS ERR HANDLER - 0x%04x\r\n", nrf_error); APP_ERROR_HANDLER(nrf_error); } /**@brief Function for initializing the Connection Parameters module. */ static void conn_params_init(void) { uint32_t err_code; ble_conn_params_init_t cp_init; memset(&cp_init, 0, sizeof(cp_init)); cp_init.p_conn_params = NULL; cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; cp_init.disconnect_on_fail = true; cp_init.evt_handler = on_conn_params_evt; cp_init.error_handler = conn_params_error_handler; err_code = ble_conn_params_init(&cp_init); uart_writef(ERR_CODE_PRINT, "ERROR CODE: CONN PARAMS INIT - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); } /**@brief Function for putting the chip into sleep mode. * * @note This function will not return. */ static void sleep_mode_enter(void) { uint32_t err_code; err_code = sd_power_system_off(); uart_writef(ERR_CODE_PRINT, "ERROR CODE: SLEEP MODE - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); } /**@brief Function for handling advertising events. * * @details This function will be called for advertising events which are passed to the application. * * @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: sleep_mode_enter(); break; default: break; } } /**@brief Function for initializing the Advertising functionality. * * @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. */ static void advertising_init(void) { uint32_t err_code; ble_advertising_init_t init; ble_advdata_manuf_data_t manuf_data; // Variable to hold manufacturer specific data uint8_t data[] = MANUFACTURER_NAME; // Our data to adverise manuf_data.company_identifier = SINNOZ_COMPANY_ID; // Sinnoz company ID manuf_data.data.p_data = data; manuf_data.data.size = sizeof(data) - 1; memset(&init, 0, sizeof(init)); init.advdata.name_type = BLE_ADVDATA_FULL_NAME; init.advdata.p_manuf_specific_data = &manuf_data; init.advdata.include_appearance = true; init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; int8_t tx_power = BLE_TX_POWER_LEVEL; init.srdata.p_tx_power_level = &tx_power; 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; init.evt_handler = on_adv_evt; err_code = ble_advertising_init(&m_advertising, &init); uart_writef(ERR_CODE_PRINT, "ERROR CODE: ADAVERTISING INIT - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG); } /**@brief Function for starting advertising. */ static void advertising_start(void) { uint32_t err_code; err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST); uart_writef(ERR_CODE_PRINT, "ERROR CODE: ADAVERTISING START - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); } /**@brief Function for handling the Connected event. * * @param[in] p_gap_evt GAP event received from the BLE stack. */ static void on_connected(const ble_gap_evt_t * const p_gap_evt) { uint32_t periph_link_cnt = ble_conn_state_n_peripherals(); // Number of peripheral links. uart_writef(DEBUG_PRINT, "BLE CONNECT: Connection with link 0x%x established.\r\n", p_gap_evt->conn_handle); if (periph_link_cnt != NRF_SDH_BLE_PERIPHERAL_LINK_COUNT) { // Continue advertising. More connections can be established because the maximum link count has not been reached. advertising_start(); } } /**@brief Function for handling the Disconnected event. * * @param[in] p_gap_evt GAP event received from the BLE stack. */ static void on_disconnected(ble_gap_evt_t const * const p_gap_evt) { uint32_t periph_link_cnt = ble_conn_state_n_peripherals(); // Number of peripheral links. uart_writef(DEBUG_PRINT, "BLE CONNECT: Connection 0x%x has been disconnected. Reason: 0x%x\r\n", p_gap_evt->conn_handle, p_gap_evt->params.disconnected.reason); if (periph_link_cnt == (NRF_SDH_BLE_PERIPHERAL_LINK_COUNT - 1)) { // Advertising is not running when all connections are taken, and must therefore be started. advertising_start(); } } /**@brief Function for handling the Read/Write Authorization request event. * * @param[in] p_ble_evt Event received from the BLE stack. */ static void on_authorize_request(ble_evt_t const * p_ble_evt) { ret_code_t err_code; 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); uart_writef(ERR_CODE_PRINT, "ERROR CODE: BLE GATTS EVT RW AUTHORIZE REQUEST 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); } } } /**@brief Function for handling BLE events. * * @param[in] p_ble_evt Bluetooth stack event. * @param[in] p_context Unused. */ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context) { uint32_t err_code; uart_writef(DEBUG_PRINT, "BLE EVENT: 0x%04x\r\n", p_ble_evt->header.evt_id); switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: on_connected(&p_ble_evt->evt.gap_evt); break; // BLE_GAP_EVT_CONNECTED case BLE_GAP_EVT_DISCONNECTED: on_disconnected(&p_ble_evt->evt.gap_evt); break; // BLE_GAP_EVT_DISCONNECTED case BLE_GAP_EVT_SEC_PARAMS_REQUEST: // Pairing not supported err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); uart_writef(ERR_CODE_PRINT, "ERROR CODE: BLE GAP EVT SEC PARAMS REQUEST 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); break; // BLE_GAP_EVT_SEC_PARAMS_REQUEST case BLE_GATTS_EVT_SYS_ATTR_MISSING: // No system attributes have been stored. err_code = sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gap_evt.conn_handle, NULL, 0, 0); uart_writef(ERR_CODE_PRINT, "ERROR CODE: BLE GATTS EVT SYS ATTR MISSING 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); break; // BLE_GATTS_EVT_SYS_ATTR_MISSING case BLE_GATTS_EVT_TIMEOUT: // Disconnect on GATT Server timeout event. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); uart_writef(ERR_CODE_PRINT, "ERROR CODE: BLE GATTS EVT TIMEOUT 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); break; // BLE_GATTS_EVT_TIMEOUT // case BLE_GATTC_EVT_TIMEOUT: // // Disconnect on GATT Client timeout event. // err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, // BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); // uart_writef(ERR_CODE_PRINT, "ERROR CODE: BLE GATTC EVT TIMEOUT 0x%04x\r\n", err_code); // APP_ERROR_CHECK(err_code); // break; // BLE_GATTC_EVT_TIMEOUT case BLE_EVT_USER_MEM_REQUEST: err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gattc_evt.conn_handle, NULL); uart_writef(ERR_CODE_PRINT, "ERROR CODE: BLE EVT USER MEM REQUEST 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); break; // BLE_EVT_USER_MEM_REQUEST case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: on_authorize_request(p_ble_evt); break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST default: // No implementation needed. break; } // sinnoz_ble_wfs_on_ble_evt(&sinnoz_wfs, p_ble_evt); // sinnoz_ble_hists_on_ble_evt(&sinnoz_hists, p_ble_evt); // sinnoz_ble_utcs_on_ble_evt(&sinnoz_utcs, p_ble_evt); } static void ble_stack_init(void) { uint32_t err_code; err_code = nrf_sdh_enable_request(); uart_writef(ERR_CODE_PRINT, "ERROR CODE: SDH ENABLE REQUEST - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); // Configure the BLE stack using the default settings. // Fetch the start address of the application RAM. uint32_t ram_start = 0; err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start); uart_writef(ERR_CODE_PRINT, "ERROR CODE: SDH BLE DEFAULT CFG SET - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); // Enable BLE stack. err_code = nrf_sdh_ble_enable(&ram_start); uart_writef(ERR_CODE_PRINT, "ERROR CODE: SDH BLE ENABLE - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); // Register a handler for BLE events. NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL); } void ble_wfs_system_mode_write_handler(uint16_t conn_handle, sinnoz_ble_wfs_t * p_sinnoz_ble_wfs, uint8_t new_mode) { uart_writef(DEBUG_PRINT, "TEST PRINT: SYSTEM MODE SET - 0x%02x\r\n", new_mode); system_mode_change(new_mode); } void ble_wfs_custom_light_color_write_handler(uint16_t conn_handle, sinnoz_ble_wfs_t * p_sinnoz_ble_wfs, uint8_t * color) { uart_writef(DEBUG_PRINT, "TEST PRINT: CUSTOM LIGHT COLOR SET - 0x%02x 0x%02x 0x%02x\r\n", color[0], color[1], color[2]); custom_color_set(color); } void ble_hists_ctrl_write_handler(uint16_t conn_handle, sinnoz_ble_hists_t * p_sinnoz_ble_hists, uint8_t ctrl) { uint8_t i; sdk_mapped_flags_key_list_t conn_handles = ble_conn_state_periph_handles(); uint8_t hist_data[DATA_BUF_SIZE]; uart_writef(DEBUG_PRINT, "TEST PRINT: HISTORY CTRL - 0x%02x\r\n", ctrl); switch(ctrl) { case 0: history_transmit_timer_stop(); break; case 1: if (hist_data_count > 0) { hist_data_count = hist_db_pop(hist_data); for (i = 0; i < conn_handles.len; i++) { sinnoz_ble_hists_data_update(conn_handles.flag_keys[i], &sinnoz_hists, hist_data); sinnoz_ble_hists_counts_update(conn_handles.flag_keys[i], &sinnoz_hists, hist_data_count); } } else { for (i = 0; i < conn_handles.len; i++) { sinnoz_ble_hists_counts_update(conn_handles.flag_keys[i], &sinnoz_hists, hist_data_count); } } uart_writef(DEBUG_PRINT, "DATA: UPDATE ONE DATA\r\n"); break; case 2: history_transmit_timer_start(); break; default: break; } } void ble_utcs_time_calibration_write_handler (uint16_t conn_handle, sinnoz_ble_utcs_t * p_sinnoz_ble_utcs, uint32_t current_time) { uart_writef(DEBUG_PRINT, "UTC: TIME CALIBRATION - 0x%08x\r\n", current_time); real_time_clock_set(current_time); } void ble_utcs_day_alarm_settings_write_handler (uint16_t conn_handle, sinnoz_ble_utcs_t * p_sinnoz_ble_utcs, uint16_t alarm_settings) { uart_writef(DEBUG_PRINT, "UTC: DAY ALARM SET - 0x%04x\r\n", alarm_settings); alarm_set(alarm_settings); } void ble_utcs_night_alarm_settings_write_handler (uint16_t conn_handle, sinnoz_ble_utcs_t * p_sinnoz_ble_utcs, uint16_t alarm_settings) { uart_writef(DEBUG_PRINT, "UTC: NIGHT ALARM SET - 0x%04x\r\n", alarm_settings); alarm_set(alarm_settings); } static void services_init(void) { uint32_t err_code; ble_dis_init_t dis_init; ble_dis_sys_id_t sys_id; sinnoz_ble_wfs_init_t sinnoz_wfs_init; sinnoz_ble_hists_init_t sinnoz_hists_init; sinnoz_ble_utcs_init_t sinnoz_utcs_init; // 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.model_num_str, MODEL_NUM); ble_srv_ascii_to_utf8(&dis_init.serial_num_str, SERIAL_NUM); sys_id.manufacturer_id = MANUFACTURER_ID; sys_id.organizationally_unique_id = ORG_UNIQUE_ID; dis_init.p_sys_id = &sys_id; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_init.dis_attr_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&dis_init.dis_attr_md.write_perm); // ble_dis_init(&dis_init); err_code = ble_dis_init(&dis_init); uart_writef(ERR_CODE_PRINT, "ERROR CODE: INIT DEVICE INFORMATION SERVICE - 0x%04x\r\n", err_code); APP_ERROR_CHECK(err_code); // Initialize Sinnoz Water Fountain Service. memset(&sinnoz_wfs_init, 0, sizeof(sinnoz_wfs_init)); sinnoz_wfs_init.system_mode_write_handler = ble_wfs_system_mode_write_handler; sinnoz_wfs_init.custom_light_color_write_handler = ble_wfs_custom_light_color_write_handler; sinnoz_ble_wfs_init(&sinnoz_wfs, &sinnoz_wfs_init); // Initialize Sinnoz History Service. memset(&sinnoz_hists_init, 0, sizeof(sinnoz_hists_init)); sinnoz_hists_init.history_ctrl_write_handler = ble_hists_ctrl_write_handler; sinnoz_ble_hists_init(&sinnoz_hists, &sinnoz_hists_init); // Initialize Sinnoz UTC Service. memset(&sinnoz_utcs_init, 0, sizeof(sinnoz_utcs_init)); sinnoz_utcs_init.time_calibration_write_handler = ble_utcs_time_calibration_write_handler; sinnoz_utcs_init.day_alarm_settings_write_handler = ble_utcs_day_alarm_settings_write_handler; sinnoz_utcs_init.night_alarm_settings_write_handler = ble_utcs_night_alarm_settings_write_handler; sinnoz_ble_utcs_init(&sinnoz_utcs, &sinnoz_utcs_init); } void sinnoz_ble_wf_init(void) { ble_stack_init(); gap_params_init(); gatt_init(); services_init(); advertising_init(); conn_params_init(); } void sinnoz_ble_wf_start(void) { advertising_start(); }
hey Mttrinh, have you got any idea what's wrong with my code?
Have you tried testing with different iOS device? iPhones? iPad? Also tried with different iOS versions?
I can't see anything wrong with your code, have you tried increasing/decreasing the connection interval?
yes, I tried different ios device and tried increasing/decreasing the connection interval, but none of it works
yes, I tried different ios device and tried increasing/decreasing the connection interval, but none of it works