Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nrf5 SDK 14.2.0 cannot be connected by ios

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? 

Parents
  • 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?

Reply Children
No Data
Related