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.
Dependents: Hello_BLE F446RE-BLE
Fork of X_NUCLEO_IDB0XA1 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 00018 /** 00019 ****************************************************************************** 00020 * @file btle.cpp 00021 * @author STMicroelectronics 00022 * @brief Implementation BlueNRG Init and helper functions. 00023 ****************************************************************************** 00024 * @copy 00025 * 00026 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 00027 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 00028 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 00029 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 00030 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 00031 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 00032 * 00033 * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> 00034 */ 00035 00036 00037 #include "btle.h" 00038 #include "ble/Gap.h" 00039 #include "ble/GapEvents.h" 00040 #include "BlueNRGGap.h" 00041 #include "BlueNRGGattServer.h" 00042 #include "Utils.h" 00043 00044 #ifdef __cplusplus 00045 extern "C" { 00046 #endif 00047 00048 00049 /* C File Includes ------------------------------------------------------------------*/ 00050 // ANDREA: Updated includes and changed some types (e.g., tHalUint8 --> uint8_t) 00051 #include <stdio.h> 00052 #include <string.h> 00053 #include "hci.h" 00054 #include "hci_const.h" 00055 #include "bluenrg_aci.h" 00056 #include "bluenrg_hal_aci.h" 00057 #include "bluenrg_gap.h" 00058 #include "bluenrg_utils.h" 00059 00060 #include "hal_types.h" 00061 #include "hal.h" 00062 #include "gp_timer.h" 00063 #include "osal.h" 00064 #include "sm.h" 00065 #include "debug_platform.h" 00066 00067 #ifdef __cplusplus 00068 } 00069 #endif 00070 00071 #define IDB04A1 0 00072 #define IDB05A1 1 00073 00074 // static void btle_handler(/*ble_evt_t * p_ble_evt*/); 00075 void HCI_Input(tHciDataPacket * hciReadPacket); 00076 00077 //#define BDADDR_SIZE 6 00078 //tHalUint8 bdaddr[BDADDR_SIZE]= {0xaa, 0x00, 0x00, 0xE1, 0x80, 0x02}; 00079 00080 uint16_t g_gap_service_handle = 0; 00081 uint16_t g_appearance_char_handle = 0; 00082 uint16_t g_device_name_char_handle = 0; 00083 00084 /* Private variables ---------------------------------------------------------*/ 00085 volatile uint8_t set_connectable = 1; 00086 // ANDREA 00087 uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ 00088 00089 Gap::Address_t bleAddr; 00090 Gap::AddressType_t addr_type = Gap::ADDR_TYPE_PUBLIC; 00091 00092 /**************************************************************************/ 00093 /*! 00094 @brief Initialises BTLE and the underlying HW/Device 00095 @param isSetAddress boolean if address has been set 00096 @param mosi MOSI Pin 00097 @param miso MISO Pin 00098 @param sclk clock Pin 00099 @returns void 00100 */ 00101 /**************************************************************************/ 00102 void btle_init(bool isSetAddress) 00103 { 00104 DEBUG("btle_init>>\n\r"); 00105 00106 int ret; 00107 uint8_t hwVersion; 00108 uint16_t fwVersion; 00109 uint16_t service_handle, dev_name_char_handle, appearance_char_handle; 00110 00111 /* Delay needed only to be able to acces the JTAG interface after reset 00112 if it will be disabled later. */ 00113 Clock_Wait(500); 00114 00115 /* Initialize the BlueNRG HCI */ 00116 HCI_Init(); 00117 00118 /* Reset BlueNRG SPI interface */ 00119 BlueNRG_RST(); 00120 00121 /* get the BlueNRG HW and FW versions */ 00122 getBlueNRGVersion(&hwVersion, &fwVersion); 00123 00124 /* 00125 * Reset BlueNRG again otherwise we won't 00126 * be able to change its MAC address. 00127 * aci_hal_write_config_data() must be the first 00128 * command after reset otherwise it will fail. 00129 */ 00130 BlueNRG_RST(); 00131 00132 if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ 00133 bnrg_expansion_board = IDB05A1; 00134 } 00135 00136 /* The Nucleo board must be configured as SERVER */ 00137 //check if isSetAddress is set than set address. 00138 // ANDREA 00139 if(isSetAddress) 00140 { 00141 BlueNRGGap::getInstance().getAddress(&addr_type, bleAddr); 00142 00143 Gap::Address_t bdaddr; 00144 Osal_MemCpy(bdaddr, bleAddr, BDADDR_SIZE); 00145 00146 ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, 00147 CONFIG_DATA_PUBADDR_LEN, 00148 bdaddr); 00149 } else { 00150 00151 const Gap::Address_t BLE_address_BE = {0xFD,0x00,0x25,0xAA,0x02,0x04}; 00152 BlueNRGGap::getInstance().setAddress(Gap::ADDR_TYPE_PUBLIC, BLE_address_BE); 00153 00154 ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, 00155 CONFIG_DATA_PUBADDR_LEN, 00156 BLE_address_BE); 00157 } 00158 00159 ret = aci_gatt_init(); 00160 if(ret){ 00161 PRINTF("GATT_Init failed.\n"); 00162 } 00163 //GAP is always in PERIPHERAL _ROLE as mbed does not support Master role at the moment 00164 if (bnrg_expansion_board == IDB05A1) { 00165 ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); 00166 } else { 00167 ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle); 00168 } 00169 00170 if(ret != BLE_STATUS_SUCCESS){ 00171 PRINTF("GAP_Init failed.\n"); 00172 } 00173 00174 //ANDREA -- FIXME: Security and passkey set by default 00175 ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, 00176 OOB_AUTH_DATA_ABSENT, 00177 NULL, 00178 7, 00179 16, 00180 USE_FIXED_PIN_FOR_PAIRING, 00181 123456, 00182 BONDING); 00183 if (ret == BLE_STATUS_SUCCESS) { 00184 DEBUG("Auth Req set successfully.\n"); 00185 } 00186 00187 aci_hal_set_tx_power_level(1,4); 00188 00189 g_gap_service_handle = service_handle; 00190 g_appearance_char_handle = appearance_char_handle; 00191 g_device_name_char_handle = dev_name_char_handle; 00192 //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API 00193 /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, 00194 strlen(name), (tHalUint8 *)name);*/ 00195 00196 return; 00197 } 00198 00199 void User_Process() 00200 { 00201 if(set_connectable){ 00202 setConnectable(); 00203 set_connectable = FALSE; 00204 } 00205 } 00206 00207 void setConnectable(void) 00208 { 00209 tBleStatus ret; 00210 00211 const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; 00212 00213 /* disable scan response */ 00214 hci_le_set_scan_resp_data(0,NULL); 00215 00216 //int t = BlueNRGGap::getInstance()::ADV_IND;// advType; 00217 00218 ret = aci_gap_set_discoverable(BlueNRGGap::getInstance().ADV_IND, 0, 0, PUBLIC_ADDR, NO_WHITE_LIST_USE, 00219 sizeof(local_name), local_name, 0, NULL, 0, 0); 00220 if (ret != BLE_STATUS_SUCCESS) { 00221 DEBUG("Error while setting discoverable mode (%d)\n", ret); 00222 } 00223 00224 } 00225 00226 /**************************************************************************/ 00227 /*! 00228 @brief Not Used 00229 00230 @param[in] void 00231 00232 @returns 00233 */ 00234 /**************************************************************************/ 00235 /* 00236 static void btle_handler() 00237 { 00238 00239 } 00240 */ 00241 00242 /*! 00243 @brief Not Used 00244 00245 @param[in] void 00246 00247 @returns 00248 */ 00249 void SPI_Poll(void) 00250 { 00251 //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); 00252 return; 00253 } 00254 00255 void Attribute_Modified_CB(uint16_t attr_handle, uint8_t data_length, uint8_t *att_data, uint8_t offset) 00256 { 00257 //Extract the GattCharacteristic from p_characteristics[] and find the properties mask 00258 GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle); 00259 if(p_char!=NULL) { 00260 GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle(); 00261 BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE; 00262 DEBUG("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]); 00263 DEBUG("getProperties 0x%x\n\r",p_char->getProperties()); 00264 if(attr_handle == charHandle+CHAR_VALUE_OFFSET) { 00265 currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; 00266 } 00267 00268 if(attr_handle == charHandle+CHAR_DESC_OFFSET) { 00269 currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; 00270 } 00271 DEBUG("currentHandle %d\n\r", currentHandle); 00272 if((p_char->getProperties() & 00273 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && 00274 currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { 00275 00276 DEBUG("*****NOTIFICATION CASE\n\r"); 00277 //Now Check if data written in Enable or Disable 00278 if((uint16_t)att_data[0]==1) { 00279 //DEBUG("Notify ENABLED\n\r"); 00280 BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, p_char->getValueAttribute().getHandle()); 00281 } else { 00282 //DEBUG("Notify DISABLED\n\r"); 00283 BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, p_char->getValueAttribute().getHandle()); 00284 } 00285 } 00286 00287 //Check is attr handle property is WRITEABLE, if yes, generate GATT_EVENT_DATA_WRITTEN Event 00288 if((p_char->getProperties() & 00289 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) && 00290 currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) { 00291 00292 DEBUG("*****WRITE CASE\n\r"); 00293 00294 GattWriteCallbackParams writeParams; 00295 writeParams.handle = p_char->getValueAttribute().getHandle(); 00296 writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? 00297 writeParams.len = data_length; 00298 writeParams.data = att_data; 00299 if (bnrg_expansion_board == IDB05A1) { 00300 writeParams.offset = offset; 00301 } 00302 BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); 00303 00304 //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, evt->attr_handle); 00305 //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data 00306 if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getInitialLength() > 0)) { 00307 BlueNRGGattServer::getInstance().write(p_char->getValueAttribute().getHandle(), (uint8_t*)att_data, data_length, false); 00308 } 00309 } 00310 } 00311 00312 } 00313 00314 #ifdef __cplusplus 00315 extern "C" { 00316 #endif 00317 00318 /**************************************************************************/ 00319 /*! 00320 @brief Handle HCI Stack Event 00321 00322 @param[in] pckt 00323 Event Packet sent by the stack to be decoded 00324 00325 @returns 00326 */ 00327 /**************************************************************************/ 00328 extern void HCI_Event_CB(void *pckt) { 00329 hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; 00330 hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; 00331 00332 if(hci_pckt->type != HCI_EVENT_PKT) 00333 return; 00334 00335 switch(event_pckt->evt){ 00336 00337 case EVT_DISCONN_COMPLETE: 00338 { 00339 DEBUG("EVT_DISCONN_COMPLETE\n"); 00340 00341 evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt; 00342 00343 BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, BlueNRGGap::REMOTE_USER_TERMINATED_CONNECTION); 00344 } 00345 break; 00346 00347 case EVT_LE_META_EVENT: 00348 { 00349 DEBUG("EVT_LE_META_EVENT\n"); 00350 00351 evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; 00352 00353 switch(evt->subevent){ 00354 // ANDREA 00355 case EVT_LE_CONN_COMPLETE: 00356 { 00357 Gap::AddressType_t peerAddrType = Gap::ADDR_TYPE_PUBLIC; 00358 DEBUG("EVT_LE_CONN_COMPLETE\n"); 00359 00360 evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; 00361 00362 BlueNRGGap::getInstance().setConnectionHandle(cc->handle); 00363 BlueNRGGap::ConnectionParams_t connectionParams; 00364 BlueNRGGap::getInstance().getPreferredConnectionParams(&connectionParams); 00365 switch (cc->peer_bdaddr_type) { 00366 case PUBLIC_ADDR: 00367 peerAddrType = Gap::ADDR_TYPE_PUBLIC; 00368 break; 00369 case STATIC_RANDOM_ADDR: 00370 peerAddrType = Gap::ADDR_TYPE_RANDOM_STATIC; 00371 break; 00372 case RESOLVABLE_PRIVATE_ADDR: 00373 peerAddrType = Gap::ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE; 00374 break; 00375 case NON_RESOLVABLE_PRIVATE_ADDR: 00376 peerAddrType = Gap::ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE; 00377 break; 00378 } 00379 BlueNRGGap::getInstance().processConnectionEvent(cc->handle, Gap::PERIPHERAL, peerAddrType, cc->peer_bdaddr, addr_type, bleAddr, (const BlueNRGGap::ConnectionParams_t *)&connectionParams); 00380 } 00381 break; 00382 } 00383 } 00384 break; 00385 00386 case EVT_VENDOR: 00387 { 00388 evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; 00389 //DEBUG("EVT_VENDOR %d\n", blue_evt->ecode); 00390 00391 switch(blue_evt->ecode){ 00392 00393 case EVT_BLUE_GATT_READ_PERMIT_REQ: 00394 { 00395 DEBUG("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r"); 00396 evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data; 00397 BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle-CHAR_VALUE_OFFSET); 00398 } 00399 break; 00400 00401 case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: 00402 { 00403 DEBUG("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r"); 00404 /* this callback is invoked when a GATT attribute is modified 00405 extract callback data and pass to suitable handler function */ 00406 if (bnrg_expansion_board == IDB05A1) { 00407 evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data; 00408 Attribute_Modified_CB(evt->attr_handle, evt->data_length, evt->att_data, evt->offset); 00409 } else { 00410 evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data; 00411 Attribute_Modified_CB(evt->attr_handle, evt->data_length, evt->att_data, 0); 00412 } 00413 } 00414 break; 00415 00416 //Any cases for Data Sent Notifications? 00417 case EVT_BLUE_GATT_NOTIFICATION: 00418 //This is only relevant for Client Side Event 00419 DEBUG("EVT_BLUE_GATT_NOTIFICATION"); 00420 break; 00421 case EVT_BLUE_GATT_INDICATION: 00422 //This is only relevant for Client Side Event 00423 DEBUG("EVT_BLUE_GATT_INDICATION"); 00424 break; 00425 00426 case EVT_BLUE_GATT_PROCEDURE_COMPLETE: 00427 DEBUG("EVT_BLUE_GATT_PROCEDURE_COMPLETE"); 00428 break; 00429 } 00430 } 00431 break; 00432 } 00433 00434 return ; 00435 } 00436 00437 00438 #ifdef __cplusplus 00439 } 00440 #endif
Generated on Tue Jul 12 2022 17:16:07 by
1.7.2
