SG RFID nRF51822 fork

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