Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nRF51822 by
btle.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "common/common.h " 00018 #include "nordic_common.h" 00019 00020 #include "btle.h" 00021 00022 #include "ble_flash.h" 00023 #include "ble_conn_params.h" 00024 00025 #include "btle_gap.h" 00026 #include "btle_advertising.h" 00027 #include "custom/custom_helper.h" 00028 00029 #include "ble/GapEvents.h" 00030 #include "nRF5xn.h" 00031 00032 extern "C" { 00033 #include "pstorage.h" 00034 #include "device_manager.h" 00035 #include "softdevice_handler.h" 00036 #include "ble_stack_handler_types.h" 00037 } 00038 00039 #include "ble_hci.h" 00040 #include "btle_discovery.h" 00041 00042 #include "nRF5xGattClient.h" 00043 #include "nRF5xServiceDiscovery.h" 00044 #include "nRF5xCharacteristicDescriptorDiscoverer.h" 00045 00046 extern "C" void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name); 00047 void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name); 00048 00049 static void btle_handler(ble_evt_t *p_ble_evt); 00050 static uint32_t gatt_table_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT; 00051 00052 static void sys_evt_dispatch(uint32_t sys_evt) 00053 { 00054 pstorage_sys_event_handler(sys_evt); 00055 } 00056 00057 /** 00058 * This function is called in interrupt context to handle BLE events; i.e. pull 00059 * system and user events out of the pending events-queue of the BLE stack. The 00060 * BLE stack signals the availability of events by the triggering the SWI2 00061 * interrupt, which forwards the handling to this function. 00062 * 00063 * The event processing loop is implemented in intern_softdevice_events_execute(). 00064 * 00065 * In mbed OS, a callback for intern_softdevice_events_execute() is posted 00066 * to the scheduler, which then executes in thread mode. In mbed-classic, 00067 * event processing happens right-away in interrupt context (which is more 00068 * risk-prone). In either case, the logic of event processing is identical. 00069 */ 00070 static uint32_t eventHandler() 00071 { 00072 #ifdef YOTTA_CFG_MBED_OS 00073 minar::Scheduler::postCallback(intern_softdevice_events_execute); 00074 #else 00075 intern_softdevice_events_execute(); 00076 #endif 00077 00078 return NRF_SUCCESS; 00079 } 00080 00081 error_t 00082 btle_set_gatt_table_size(uint32_t size) 00083 { 00084 if (size >= BLE_GATTS_ATTR_TAB_SIZE_MIN) 00085 { 00086 gatt_table_size = size; 00087 return ERROR_NONE; 00088 } 00089 00090 return ERROR_INVALID_PARAM; 00091 } 00092 00093 error_t btle_init(void) 00094 { 00095 nrf_clock_lfclksrc_t clockSource; 00096 if (NRF_CLOCK->LFCLKSRC & (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos)) { 00097 clockSource = NRF_CLOCK_LFCLKSRC_XTAL_20_PPM; 00098 } else { 00099 clockSource = NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION; 00100 } 00101 SOFTDEVICE_HANDLER_INIT(clockSource, eventHandler); 00102 00103 // Enable BLE stack 00104 /** 00105 * Using this call, the application can select whether to include the 00106 * Service Changed characteristic in the GATT Server. The default in all 00107 * previous releases has been to include the Service Changed characteristic, 00108 * but this affects how GATT clients behave. Specifically, it requires 00109 * clients to subscribe to this attribute and not to cache attribute handles 00110 * between connections unless the devices are bonded. If the application 00111 * does not need to change the structure of the GATT server attributes at 00112 * runtime this adds unnecessary complexity to the interaction with peer 00113 * clients. If the SoftDevice is enabled with the Service Changed 00114 * Characteristics turned off, then clients are allowed to cache attribute 00115 * handles making applications simpler on both sides. 00116 */ 00117 static const bool IS_SRVC_CHANGED_CHARACT_PRESENT = true; 00118 ble_enable_params_t enableParams = { 00119 .gatts_enable_params = { 00120 .service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT, 00121 .attr_tab_size = gatt_table_size 00122 } 00123 }; 00124 if (sd_ble_enable(&enableParams) != NRF_SUCCESS) { 00125 return ERROR_INVALID_PARAM; 00126 } 00127 00128 ble_gap_addr_t addr; 00129 if (sd_ble_gap_address_get(&addr) != NRF_SUCCESS) { 00130 return ERROR_INVALID_PARAM; 00131 } 00132 if (sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr) != NRF_SUCCESS) { 00133 return ERROR_INVALID_PARAM; 00134 } 00135 00136 ASSERT_STATUS( softdevice_ble_evt_handler_set(btle_handler)); 00137 ASSERT_STATUS( softdevice_sys_evt_handler_set(sys_evt_dispatch)); 00138 00139 return btle_gap_init(); 00140 } 00141 00142 static void btle_handler(ble_evt_t *p_ble_evt) 00143 { 00144 /* Library service handlers */ 00145 #if SDK_CONN_PARAMS_MODULE_ENABLE 00146 ble_conn_params_on_ble_evt(p_ble_evt); 00147 #endif 00148 00149 dm_ble_evt_handler(p_ble_evt); 00150 00151 #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) 00152 bleGattcEventHandler(p_ble_evt); 00153 #endif 00154 00155 nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE); 00156 nRF5xGap &gap = (nRF5xGap &) ble.getGap(); 00157 nRF5xGattServer &gattServer = (nRF5xGattServer &) ble.getGattServer(); 00158 nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager(); 00159 00160 /* Custom event handler */ 00161 switch (p_ble_evt->header.evt_id) { 00162 case BLE_GAP_EVT_CONNECTED: { 00163 Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle; 00164 #if defined(TARGET_MCU_NRF51_16K_S110) || defined(TARGET_MCU_NRF51_32K_S110) 00165 /* Only peripheral role is supported by S110 */ 00166 Gap::Role_t role = Gap::PERIPHERAL; 00167 #else 00168 Gap::Role_t role = static_cast<Gap::Role_t>(p_ble_evt->evt.gap_evt.params.connected.role); 00169 #endif 00170 gap.setConnectionHandle(handle); 00171 const Gap::ConnectionParams_t *params = reinterpret_cast<Gap::ConnectionParams_t *>(&(p_ble_evt->evt.gap_evt.params.connected.conn_params)); 00172 const ble_gap_addr_t *peer = &p_ble_evt->evt.gap_evt.params.connected.peer_addr; 00173 const ble_gap_addr_t *own = &p_ble_evt->evt.gap_evt.params.connected.own_addr; 00174 gap.processConnectionEvent(handle, 00175 role, 00176 static_cast<BLEProtocol::AddressType_t>(peer->addr_type), peer->addr, 00177 static_cast<BLEProtocol::AddressType_t>(own->addr_type), own->addr, 00178 params); 00179 break; 00180 } 00181 00182 case BLE_GAP_EVT_DISCONNECTED: { 00183 Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle; 00184 // Since we are not in a connection and have not started advertising, 00185 // store bonds 00186 gap.setConnectionHandle (BLE_CONN_HANDLE_INVALID); 00187 00188 Gap::DisconnectionReason_t reason; 00189 switch (p_ble_evt->evt.gap_evt.params.disconnected.reason) { 00190 case BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION: 00191 reason = Gap::LOCAL_HOST_TERMINATED_CONNECTION; 00192 break; 00193 case BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION: 00194 reason = Gap::REMOTE_USER_TERMINATED_CONNECTION; 00195 break; 00196 case BLE_HCI_CONN_INTERVAL_UNACCEPTABLE: 00197 reason = Gap::CONN_INTERVAL_UNACCEPTABLE; 00198 break; 00199 default: 00200 /* Please refer to the underlying transport library for an 00201 * interpretion of this reason's value. */ 00202 reason = static_cast<Gap::DisconnectionReason_t>(p_ble_evt->evt.gap_evt.params.disconnected.reason); 00203 break; 00204 } 00205 00206 // Close all pending discoveries for this connection 00207 #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) 00208 nRF5xGattClient& gattClient = ble.getGattClient(); 00209 gattClient.characteristicDescriptorDiscoverer().terminate(handle, BLE_ERROR_INVALID_STATE); 00210 gattClient.discovery().terminate(handle); 00211 #endif 00212 00213 gap.processDisconnectionEvent(handle, reason); 00214 break; 00215 } 00216 00217 case BLE_GAP_EVT_PASSKEY_DISPLAY: 00218 securityManager.processPasskeyDisplayEvent(p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.passkey_display.passkey); 00219 break; 00220 00221 case BLE_GAP_EVT_TIMEOUT: 00222 gap.processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src)); 00223 break; 00224 00225 case BLE_GATTC_EVT_TIMEOUT: 00226 case BLE_GATTS_EVT_TIMEOUT: 00227 // Disconnect on GATT Server and Client timeout events. 00228 // ASSERT_STATUS_RET_VOID (sd_ble_gap_disconnect(m_conn_handle, 00229 // BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION)); 00230 break; 00231 00232 case BLE_GAP_EVT_ADV_REPORT: { 00233 const ble_gap_evt_adv_report_t *advReport = &p_ble_evt->evt.gap_evt.params.adv_report; 00234 gap.processAdvertisementReport(advReport->peer_addr.addr, 00235 advReport->rssi, 00236 advReport->scan_rsp, 00237 static_cast<GapAdvertisingParams::AdvertisingType_t>(advReport->type), 00238 advReport->dlen, 00239 advReport->data); 00240 break; 00241 } 00242 00243 default: 00244 break; 00245 } 00246 00247 gattServer.hwCallback(p_ble_evt); 00248 } 00249 00250 /*! @brief Callback when an error occurs inside the SoftDevice */ 00251 void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) 00252 { 00253 ASSERT(false, (void) 0); 00254 } 00255 00256 /*! 00257 @brief Handler for general errors above the SoftDevice layer. 00258 Typically we can' recover from this so we do a reset. 00259 */ 00260 void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name) 00261 { 00262 ASSERT_STATUS_RET_VOID( error_code ); 00263 NVIC_SystemReset(); 00264 }
Generated on Fri Jul 15 2022 12:51:28 by
1.7.2
