Nordic stack and drivers for the mbed BLE API Modified for HRM1017 for library 0.1.0

Fork of nRF51822 by Nordic Semiconductor

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 ((p_conn_params->max_conn_interval >= m_preferred_conn_params.min_conn_interval) &&
00037         (p_conn_params->max_conn_interval <= m_preferred_conn_params.max_conn_interval)) {
00038         return true;
00039     } else {
00040         return false;
00041     }
00042 }
00043 
00044 
00045 static void update_timeout_handler(void * p_context)
00046 {
00047     UNUSED_PARAMETER(p_context);
00048 
00049     if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
00050     {
00051         // Check if we have reached the maximum number of attempts
00052         m_update_count++;
00053         if (m_update_count <= m_conn_params_config.max_conn_params_update_count)
00054         {
00055             uint32_t err_code;
00056 
00057             // Parameters are not ok, send connection parameters update request.
00058             err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params);
00059             if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
00060             {
00061                 m_conn_params_config.error_handler(err_code);
00062             }
00063         }
00064         else
00065         {
00066             m_update_count = 0;
00067 
00068             // Negotiation failed, disconnect automatically if this has been configured
00069             if (m_conn_params_config.disconnect_on_fail)
00070             {
00071                 uint32_t err_code;
00072 
00073                 err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
00074                 if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
00075                 {
00076                     m_conn_params_config.error_handler(err_code);
00077                 }
00078             }
00079 
00080             // Notify the application that the procedure has failed
00081             if (m_conn_params_config.evt_handler != NULL)
00082             {
00083                 ble_conn_params_evt_t evt;
00084 
00085                 evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
00086                 m_conn_params_config.evt_handler(&evt);
00087             }
00088         }
00089     }
00090 }
00091 
00092 
00093 uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init)
00094 {
00095     uint32_t err_code;
00096 
00097     m_conn_params_config = *p_init;
00098     m_change_param = false;
00099     if (p_init->p_conn_params != NULL)
00100     {
00101         m_preferred_conn_params = *p_init->p_conn_params;
00102 
00103         // Set the connection params in stack
00104         err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params);
00105         if (err_code != NRF_SUCCESS)
00106         {
00107             return err_code;
00108         }
00109     }
00110     else
00111     {
00112         // Fetch the connection params from stack
00113         err_code = sd_ble_gap_ppcp_get(&m_preferred_conn_params);
00114         if (err_code != NRF_SUCCESS)
00115         {
00116             return err_code;
00117         }
00118     }
00119 
00120     m_conn_handle  = BLE_CONN_HANDLE_INVALID;
00121     m_update_count = 0;
00122 
00123     return app_timer_create(&m_conn_params_timer_id,
00124                             APP_TIMER_MODE_SINGLE_SHOT,
00125                             update_timeout_handler);
00126 }
00127 
00128 
00129 uint32_t ble_conn_params_stop(void)
00130 {
00131     return app_timer_stop(m_conn_params_timer_id);
00132 }
00133 
00134 
00135 static void conn_params_negotiation(void)
00136 {
00137     // Start negotiation if the received connection parameters are not acceptable
00138     if (!is_conn_params_ok(&m_current_conn_params))
00139     {
00140         uint32_t err_code;
00141         uint32_t timeout_ticks;
00142 
00143         if (m_change_param)
00144         {
00145             // Notify the application that the procedure has failed
00146             if (m_conn_params_config.evt_handler != NULL)
00147             {
00148                 ble_conn_params_evt_t evt;
00149 
00150                 evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
00151                 m_conn_params_config.evt_handler(&evt);
00152             }
00153         }
00154         else
00155         {
00156             if (m_update_count == 0)
00157             {
00158                 // First connection parameter update
00159                 timeout_ticks = m_conn_params_config.first_conn_params_update_delay;
00160             }
00161             else
00162             {
00163                 timeout_ticks = m_conn_params_config.next_conn_params_update_delay;
00164             }
00165 
00166             err_code = app_timer_start(m_conn_params_timer_id, timeout_ticks, NULL);
00167             if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
00168             {
00169                 m_conn_params_config.error_handler(err_code);
00170             }
00171         }
00172     }
00173     else
00174     {
00175         // Notify the application that the procedure has succeded
00176         if (m_conn_params_config.evt_handler != NULL)
00177         {
00178             ble_conn_params_evt_t evt;
00179 
00180             evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
00181             m_conn_params_config.evt_handler(&evt);
00182         }
00183     }
00184     m_change_param = false;
00185 }
00186 
00187 
00188 static void on_connect(ble_evt_t * p_ble_evt)
00189 {
00190     // Save connection parameters
00191     m_conn_handle         = p_ble_evt->evt.gap_evt.conn_handle;
00192     m_current_conn_params = p_ble_evt->evt.gap_evt.params.connected.conn_params;
00193     m_update_count        = 0;  // Connection parameter negotiation should re-start every connection
00194 
00195     // Check if we shall handle negotiation on connect
00196     if (m_conn_params_config.start_on_notify_cccd_handle == BLE_GATT_HANDLE_INVALID)
00197     {
00198         conn_params_negotiation();
00199     }
00200 }
00201 
00202 
00203 static void on_disconnect(ble_evt_t * p_ble_evt)
00204 {
00205     uint32_t err_code;
00206 
00207     m_conn_handle = BLE_CONN_HANDLE_INVALID;
00208 
00209     // Stop timer if running
00210     m_update_count = 0; // Connection parameters updates should happen during every connection
00211 
00212     err_code = app_timer_stop(m_conn_params_timer_id);
00213     if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
00214     {
00215         m_conn_params_config.error_handler(err_code);
00216     }
00217 }
00218 
00219 
00220 static void on_write(ble_evt_t * p_ble_evt)
00221 {
00222     ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
00223 
00224     // Check if this the correct CCCD
00225     if (
00226         (p_evt_write->handle == m_conn_params_config.start_on_notify_cccd_handle)
00227         &&
00228         (p_evt_write->len == 2)
00229     )
00230     {
00231         // Check if this is a 'start notification'
00232         if (ble_srv_is_notification_enabled(p_evt_write->data))
00233         {
00234             // Do connection parameter negotiation if necessary
00235             conn_params_negotiation();
00236         }
00237         else
00238         {
00239             uint32_t err_code;
00240 
00241             // Stop timer if running
00242             err_code = app_timer_stop(m_conn_params_timer_id);
00243             if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
00244             {
00245                 m_conn_params_config.error_handler(err_code);
00246             }
00247         }
00248     }
00249 }
00250 
00251 
00252 static void on_conn_params_update(ble_evt_t * p_ble_evt)
00253 {
00254     // Copy the parameters
00255     m_current_conn_params = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params;
00256 
00257     conn_params_negotiation();
00258 }
00259 
00260 
00261 void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt)
00262 {
00263     switch (p_ble_evt->header.evt_id)
00264     {
00265         case BLE_GAP_EVT_CONNECTED:
00266             on_connect(p_ble_evt);
00267             break;
00268 
00269         case BLE_GAP_EVT_DISCONNECTED:
00270             on_disconnect(p_ble_evt);
00271             break;
00272 
00273         case BLE_GATTS_EVT_WRITE:
00274             on_write(p_ble_evt);
00275             break;
00276 
00277         case BLE_GAP_EVT_CONN_PARAM_UPDATE:
00278             on_conn_params_update(p_ble_evt);
00279             break;
00280 
00281         default:
00282             // No implementation needed.
00283            break;
00284     }
00285 }
00286 
00287 uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t *new_params)
00288 {
00289     uint32_t err_code;
00290 
00291     m_preferred_conn_params = *new_params;
00292     // Set the connection params in stack
00293     err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params);
00294     if (err_code == NRF_SUCCESS)
00295     {
00296         if (!is_conn_params_ok(&m_current_conn_params))
00297         {
00298             m_change_param = true;
00299             err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params);
00300             m_update_count = 1;
00301         }
00302         else
00303         {
00304             // Notify the application that the procedure has succeded
00305             if (m_conn_params_config.evt_handler != NULL)
00306             {
00307                 ble_conn_params_evt_t evt;
00308 
00309                 evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
00310                 m_conn_params_config.evt_handler(&evt);
00311             }
00312             err_code = NRF_SUCCESS;
00313         }
00314     }
00315     return err_code;
00316 }