BLE temperature profile using digital DS1820 or analog LM35 sensors

Dependencies:   DS1820

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ble_conn_params.cpp Source File

ble_conn_params.cpp

00001 /* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
00002  *
00003  * The information contained herein is property of Nordic Semiconductor ASA.
00004  * Terms and conditions of usage are described in detail in NORDIC
00005  * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
00006  *
00007  * Licensees are granted free, non-transferable use of the information. NO
00008  * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
00009  * the file.
00010  *
00011  */
00012 
00013 #include "ble_conn_params.h "
00014 #include <stdlib.h>
00015 #include "nordic_common.h"
00016 #include "ble_hci.h"
00017 #include "app_timer.h "
00018 #include "ble_srv_common.h "
00019 #include "app_util.h "
00020 
00021 
00022 static ble_conn_params_init_t m_conn_params_config;     /**< Configuration as specified by the application. */
00023 static ble_gap_conn_params_t  m_preferred_conn_params;  /**< Connection parameters preferred by the application. */
00024 static uint8_t                m_update_count;           /**< Number of Connection Parameter Update messages that has currently been sent. */
00025 static uint16_t               m_conn_handle;            /**< Current connection handle. */
00026 static ble_gap_conn_params_t  m_current_conn_params;    /**< Connection parameters received in the most recent Connect event. */
00027 static app_timer_id_t         m_conn_params_timer_id;   /**< Connection parameters timer. */
00028 
00029 static bool m_change_param = false;
00030 
00031 static bool is_conn_params_ok(ble_gap_conn_params_t * p_conn_params)
00032 {
00033     // Check if interval is within the acceptable range.
00034     // NOTE: Using max_conn_interval in the received event data because this contains
00035     //       the client's connection interval.
00036     if (
00037         (p_conn_params->max_conn_interval >= m_preferred_conn_params.min_conn_interval)
00038         && 
00039         (p_conn_params->max_conn_interval <= m_preferred_conn_params.max_conn_interval)
00040     )
00041     {
00042         return true;
00043     }
00044     else
00045     {
00046         return false;
00047     }
00048 }
00049 
00050 
00051 static void update_timeout_handler(void * p_context)
00052 {
00053     UNUSED_PARAMETER(p_context);
00054 
00055     if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
00056     {
00057         // Check if we have reached the maximum number of attempts
00058         m_update_count++;
00059         if (m_update_count <= m_conn_params_config.max_conn_params_update_count)
00060         {
00061             uint32_t err_code;
00062             
00063             // Parameters are not ok, send connection parameters update request.
00064             err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params);
00065             if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
00066             {
00067                 m_conn_params_config.error_handler(err_code);
00068             }
00069         }
00070         else
00071         {
00072             m_update_count = 0;
00073             
00074             // Negotiation failed, disconnect automatically if this has been configured
00075             if (m_conn_params_config.disconnect_on_fail)
00076             {
00077                 uint32_t err_code;
00078                 
00079                 err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
00080                 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
00081                 {
00082                     m_conn_params_config.error_handler(err_code);
00083                 }
00084             }
00085             
00086             // Notify the application that the procedure has failed
00087             if (m_conn_params_config.evt_handler != NULL)
00088             {
00089                 ble_conn_params_evt_t evt;
00090                 
00091                 evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
00092                 m_conn_params_config.evt_handler(&evt);
00093             }
00094         }
00095     }
00096 }
00097 
00098 
00099 uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init)
00100 {
00101     uint32_t err_code;
00102     
00103     m_conn_params_config = *p_init;
00104     m_change_param = false;
00105     if (p_init->p_conn_params != NULL)
00106     {
00107         m_preferred_conn_params = *p_init->p_conn_params;
00108         
00109         // Set the connection params in stack
00110         err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params);
00111         if (err_code != NRF_SUCCESS)
00112         {
00113             return err_code;
00114         }
00115     }
00116     else
00117     {
00118         // Fetch the connection params from stack
00119         err_code = sd_ble_gap_ppcp_get(&m_preferred_conn_params);
00120         if (err_code != NRF_SUCCESS)
00121         {
00122             return err_code;
00123         }
00124     }
00125 
00126     m_conn_handle  = BLE_CONN_HANDLE_INVALID;
00127     m_update_count = 0;
00128     
00129     return app_timer_create(&m_conn_params_timer_id,
00130                             APP_TIMER_MODE_SINGLE_SHOT,
00131                             update_timeout_handler);
00132 }
00133 
00134 
00135 uint32_t ble_conn_params_stop(void)
00136 {
00137     return app_timer_stop(m_conn_params_timer_id);
00138 }
00139 
00140 
00141 static void conn_params_negotiation(void)
00142 {
00143     // Start negotiation if the received connection parameters are not acceptable
00144     if (!is_conn_params_ok(&m_current_conn_params))
00145     {
00146         uint32_t err_code;
00147         uint32_t timeout_ticks;
00148         
00149         if (m_change_param)
00150         {
00151             // Notify the application that the procedure has failed
00152             if (m_conn_params_config.evt_handler != NULL)
00153             {
00154                 ble_conn_params_evt_t evt;
00155                 
00156                 evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
00157                 m_conn_params_config.evt_handler(&evt);
00158             }
00159         }
00160         else
00161         {
00162             if (m_update_count == 0)
00163             {
00164                 // First connection parameter update
00165                 timeout_ticks = m_conn_params_config.first_conn_params_update_delay;
00166             }
00167             else
00168             {
00169                 timeout_ticks = m_conn_params_config.next_conn_params_update_delay;
00170             }
00171 
00172             err_code = app_timer_start(m_conn_params_timer_id, timeout_ticks, NULL);
00173             if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
00174             {
00175                 m_conn_params_config.error_handler(err_code);
00176             }
00177         }
00178     }
00179     else
00180     {
00181         // Notify the application that the procedure has succeded
00182         if (m_conn_params_config.evt_handler != NULL)
00183         {
00184             ble_conn_params_evt_t evt;
00185             
00186             evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
00187             m_conn_params_config.evt_handler(&evt);
00188         }
00189     }
00190     m_change_param = false;
00191 }
00192 
00193 
00194 static void on_connect(ble_evt_t * p_ble_evt)
00195 {
00196     // Save connection parameters
00197     m_conn_handle         = p_ble_evt->evt.gap_evt.conn_handle;
00198     m_current_conn_params = p_ble_evt->evt.gap_evt.params.connected.conn_params;
00199     m_update_count        = 0;  // Connection parameter negotiation should re-start every connection
00200     
00201     // Check if we shall handle negotiation on connect
00202     if (m_conn_params_config.start_on_notify_cccd_handle == BLE_GATT_HANDLE_INVALID)
00203     {
00204         conn_params_negotiation();
00205     }
00206 }
00207 
00208 
00209 static void on_disconnect(ble_evt_t * p_ble_evt)
00210 {
00211     uint32_t err_code;
00212 
00213     m_conn_handle = BLE_CONN_HANDLE_INVALID;
00214 
00215     // Stop timer if running
00216     m_update_count = 0; // Connection parameters updates should happen during every connection
00217     
00218     err_code = app_timer_stop(m_conn_params_timer_id);
00219     if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
00220     {
00221         m_conn_params_config.error_handler(err_code);
00222     }
00223 }
00224 
00225 
00226 static void on_write(ble_evt_t * p_ble_evt)
00227 {
00228     ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
00229 
00230     // Check if this the correct CCCD
00231     if (
00232         (p_evt_write->handle == m_conn_params_config.start_on_notify_cccd_handle)
00233         &&
00234         (p_evt_write->len == 2)
00235     )
00236     {
00237         // Check if this is a 'start notification'
00238         if (ble_srv_is_notification_enabled(p_evt_write->data))
00239         {
00240             // Do connection parameter negotiation if necessary
00241             conn_params_negotiation();
00242         }
00243         else
00244         {
00245             uint32_t err_code;
00246 
00247             // Stop timer if running
00248             err_code = app_timer_stop(m_conn_params_timer_id);
00249             if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
00250             {
00251                 m_conn_params_config.error_handler(err_code);
00252             }
00253         }
00254     }
00255 }
00256 
00257 
00258 static void on_conn_params_update(ble_evt_t * p_ble_evt)
00259 {
00260     // Copy the parameters
00261     m_current_conn_params = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params;
00262 
00263     conn_params_negotiation();
00264 }
00265 
00266 
00267 void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt)
00268 {
00269     switch (p_ble_evt->header.evt_id)
00270     {
00271         case BLE_GAP_EVT_CONNECTED:
00272             on_connect(p_ble_evt);
00273             break;
00274             
00275         case BLE_GAP_EVT_DISCONNECTED:
00276             on_disconnect(p_ble_evt);
00277             break;
00278             
00279         case BLE_GATTS_EVT_WRITE:
00280             on_write(p_ble_evt);
00281             break;
00282             
00283         case BLE_GAP_EVT_CONN_PARAM_UPDATE:
00284             on_conn_params_update(p_ble_evt);
00285             break;
00286             
00287         default:
00288             // No implementation needed.
00289            break;
00290     }
00291 }
00292 
00293 uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t *new_params)
00294 {
00295     uint32_t err_code;
00296 
00297     m_preferred_conn_params = *new_params;
00298     // Set the connection params in stack
00299     err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params);
00300     if (err_code == NRF_SUCCESS)
00301     {
00302         if (!is_conn_params_ok(&m_current_conn_params))
00303         {
00304             m_change_param = true;
00305             err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params);
00306             m_update_count = 1;
00307         }
00308         else
00309         {
00310             // Notify the application that the procedure has succeded
00311             if (m_conn_params_config.evt_handler != NULL)
00312             {
00313                 ble_conn_params_evt_t evt;
00314                 
00315                 evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
00316                 m_conn_params_config.evt_handler(&evt);
00317             }
00318             err_code = NRF_SUCCESS;
00319         }
00320     }
00321     return err_code;
00322 }