BLE UART example

Fork of Nucleo_BLE_BlueNRG by ST Americas mbed Team

Committer:
sjallouli
Date:
Fri Dec 19 18:56:07 2014 +0000
Revision:
0:a948f5f3904c
BLE_BlueNRG for Nucleo board

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sjallouli 0:a948f5f3904c 1 /* mbed Microcontroller Library
sjallouli 0:a948f5f3904c 2 * Copyright (c) 2006-2013 ARM Limited
sjallouli 0:a948f5f3904c 3 *
sjallouli 0:a948f5f3904c 4 * Licensed under the Apache License, Version 2.0 (the "License");
sjallouli 0:a948f5f3904c 5 * you may not use this file except in compliance with the License.
sjallouli 0:a948f5f3904c 6 * You may obtain a copy of the License at
sjallouli 0:a948f5f3904c 7 *
sjallouli 0:a948f5f3904c 8 * http://www.apache.org/licenses/LICENSE-2.0
sjallouli 0:a948f5f3904c 9 *
sjallouli 0:a948f5f3904c 10 * Unless required by applicable law or agreed to in writing, software
sjallouli 0:a948f5f3904c 11 * distributed under the License is distributed on an "AS IS" BASIS,
sjallouli 0:a948f5f3904c 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sjallouli 0:a948f5f3904c 13 * See the License for the specific language governing permissions and
sjallouli 0:a948f5f3904c 14 * limitations under the License.
sjallouli 0:a948f5f3904c 15 */
sjallouli 0:a948f5f3904c 16
sjallouli 0:a948f5f3904c 17
sjallouli 0:a948f5f3904c 18 #include "btle.h"
sjallouli 0:a948f5f3904c 19 #include "public/Gap.h"
sjallouli 0:a948f5f3904c 20 #include "public/GapEvents.h"
sjallouli 0:a948f5f3904c 21 #include "BlueNRGGap.h"
sjallouli 0:a948f5f3904c 22 #include "BlueNRGGattServer.h"
sjallouli 0:a948f5f3904c 23 #include "Utils.h"
sjallouli 0:a948f5f3904c 24
sjallouli 0:a948f5f3904c 25 #ifdef __cplusplus
sjallouli 0:a948f5f3904c 26 extern "C" {
sjallouli 0:a948f5f3904c 27 #endif
sjallouli 0:a948f5f3904c 28
sjallouli 0:a948f5f3904c 29
sjallouli 0:a948f5f3904c 30 /* C File Includes ------------------------------------------------------------------*/
sjallouli 0:a948f5f3904c 31 #include "hal_types.h"
sjallouli 0:a948f5f3904c 32 #include "hci.h"
sjallouli 0:a948f5f3904c 33 #include "bluenrg_hci.h"
sjallouli 0:a948f5f3904c 34 #include "gp_timer.h"
sjallouli 0:a948f5f3904c 35 #include "hal.h"
sjallouli 0:a948f5f3904c 36 #include "osal.h"
sjallouli 0:a948f5f3904c 37 #include "hci_internal.h"
sjallouli 0:a948f5f3904c 38 #include "bluenrg_hci_internal.h"
sjallouli 0:a948f5f3904c 39 #include "bluenrg_gap.h"
sjallouli 0:a948f5f3904c 40 #include "sm.h"
sjallouli 0:a948f5f3904c 41 #include <stdio.h>
sjallouli 0:a948f5f3904c 42 #include <string.h>
sjallouli 0:a948f5f3904c 43 #include "role_type.h"
sjallouli 0:a948f5f3904c 44 #include "debug.h"
sjallouli 0:a948f5f3904c 45
sjallouli 0:a948f5f3904c 46 #ifdef __cplusplus
sjallouli 0:a948f5f3904c 47 }
sjallouli 0:a948f5f3904c 48 #endif
sjallouli 0:a948f5f3904c 49
sjallouli 0:a948f5f3904c 50
sjallouli 0:a948f5f3904c 51 static void btle_handler(/*ble_evt_t * p_ble_evt*/);
sjallouli 0:a948f5f3904c 52 void HCI_Input(tHciDataPacket * hciReadPacket);
sjallouli 0:a948f5f3904c 53
sjallouli 0:a948f5f3904c 54 //#define BDADDR_SIZE 6
sjallouli 0:a948f5f3904c 55 //tHalUint8 bdaddr[BDADDR_SIZE]= {0xaa, 0x00, 0x00, 0xE1, 0x80, 0x02};
sjallouli 0:a948f5f3904c 56
sjallouli 0:a948f5f3904c 57 uint16_t g_gap_service_handle = 0;
sjallouli 0:a948f5f3904c 58 uint16_t g_appearance_char_handle = 0;
sjallouli 0:a948f5f3904c 59 uint16_t g_device_name_char_handle = 0;
sjallouli 0:a948f5f3904c 60
sjallouli 0:a948f5f3904c 61 /* Private variables ---------------------------------------------------------*/
sjallouli 0:a948f5f3904c 62 volatile uint8_t set_connectable = 1;
sjallouli 0:a948f5f3904c 63
sjallouli 0:a948f5f3904c 64 /**************************************************************************/
sjallouli 0:a948f5f3904c 65 /*!
sjallouli 0:a948f5f3904c 66 @brief Initialises BTLE and the underlying HW/Device
sjallouli 0:a948f5f3904c 67
sjallouli 0:a948f5f3904c 68 @returns
sjallouli 0:a948f5f3904c 69 */
sjallouli 0:a948f5f3904c 70 /**************************************************************************/
sjallouli 0:a948f5f3904c 71 void btle_init(bool isSetAddress)
sjallouli 0:a948f5f3904c 72 {
sjallouli 0:a948f5f3904c 73 DEBUG("btle_init>>\n\r");
sjallouli 0:a948f5f3904c 74 tHalUint8 *bleAddr;
sjallouli 0:a948f5f3904c 75 int ret;
sjallouli 0:a948f5f3904c 76 uint16_t service_handle, dev_name_char_handle, appearance_char_handle;
sjallouli 0:a948f5f3904c 77
sjallouli 0:a948f5f3904c 78 //HAL_Init();
sjallouli 0:a948f5f3904c 79
sjallouli 0:a948f5f3904c 80 /* Configure the User Button in GPIO Mode */
sjallouli 0:a948f5f3904c 81 //BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO);
sjallouli 0:a948f5f3904c 82
sjallouli 0:a948f5f3904c 83 /* Configure the system clock */
sjallouli 0:a948f5f3904c 84 //SystemClock_Config();
sjallouli 0:a948f5f3904c 85
sjallouli 0:a948f5f3904c 86 /* Delay needed only to be able to acces the JTAG interface after reset
sjallouli 0:a948f5f3904c 87 if it will be disabled later. */
sjallouli 0:a948f5f3904c 88 Clock_Wait(500);
sjallouli 0:a948f5f3904c 89
sjallouli 0:a948f5f3904c 90 /* Initialize the BlueNRG SPI driver */
sjallouli 0:a948f5f3904c 91 BNRG_SPI_Init();
sjallouli 0:a948f5f3904c 92
sjallouli 0:a948f5f3904c 93 /* Initialize the BlueNRG HCI */
sjallouli 0:a948f5f3904c 94 HCI_Init();
sjallouli 0:a948f5f3904c 95
sjallouli 0:a948f5f3904c 96 /* Reset BlueNRG SPI interface */
sjallouli 0:a948f5f3904c 97 BlueNRG_RST();
sjallouli 0:a948f5f3904c 98
sjallouli 0:a948f5f3904c 99 /* The Nucleo board must be configured as SERVER */
sjallouli 0:a948f5f3904c 100 //check if issetAddress is set than set address.
sjallouli 0:a948f5f3904c 101 if(isSetAddress)
sjallouli 0:a948f5f3904c 102 {
sjallouli 0:a948f5f3904c 103 bleAddr = BlueNRGGap::getInstance().getAddress();
sjallouli 0:a948f5f3904c 104
sjallouli 0:a948f5f3904c 105 tHalUint8 bdaddr[BDADDR_SIZE];
sjallouli 0:a948f5f3904c 106 Osal_MemCpy(bdaddr, bleAddr, BDADDR_SIZE);
sjallouli 0:a948f5f3904c 107
sjallouli 0:a948f5f3904c 108 ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
sjallouli 0:a948f5f3904c 109 CONFIG_DATA_PUBADDR_LEN,
sjallouli 0:a948f5f3904c 110 bdaddr);
sjallouli 0:a948f5f3904c 111 }
sjallouli 0:a948f5f3904c 112
sjallouli 0:a948f5f3904c 113 ret = aci_gatt_init();
sjallouli 0:a948f5f3904c 114 //GAP is always in PERIPHERAL _ROLE as mbed does not support Master role at the moment
sjallouli 0:a948f5f3904c 115 ret = aci_gap_init(GAP_PERIPHERAL_ROLE, &service_handle, &dev_name_char_handle, &appearance_char_handle);
sjallouli 0:a948f5f3904c 116
sjallouli 0:a948f5f3904c 117 g_gap_service_handle = service_handle;
sjallouli 0:a948f5f3904c 118 g_appearance_char_handle = appearance_char_handle;
sjallouli 0:a948f5f3904c 119 g_device_name_char_handle = dev_name_char_handle;
sjallouli 0:a948f5f3904c 120 //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API
sjallouli 0:a948f5f3904c 121 /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0,
sjallouli 0:a948f5f3904c 122 strlen(name), (tHalUint8 *)name);*/
sjallouli 0:a948f5f3904c 123
sjallouli 0:a948f5f3904c 124 return;
sjallouli 0:a948f5f3904c 125 }
sjallouli 0:a948f5f3904c 126
sjallouli 0:a948f5f3904c 127 void User_Process()
sjallouli 0:a948f5f3904c 128 {
sjallouli 0:a948f5f3904c 129 if(set_connectable){
sjallouli 0:a948f5f3904c 130 setConnectable();
sjallouli 0:a948f5f3904c 131 set_connectable = FALSE;
sjallouli 0:a948f5f3904c 132 }
sjallouli 0:a948f5f3904c 133 }
sjallouli 0:a948f5f3904c 134
sjallouli 0:a948f5f3904c 135 void setConnectable(void)
sjallouli 0:a948f5f3904c 136 {
sjallouli 0:a948f5f3904c 137 tBleStatus ret;
sjallouli 0:a948f5f3904c 138
sjallouli 0:a948f5f3904c 139 const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G', '1', '2'};
sjallouli 0:a948f5f3904c 140
sjallouli 0:a948f5f3904c 141 /* disable scan response */
sjallouli 0:a948f5f3904c 142 hci_le_set_scan_resp_data(0,NULL);
sjallouli 0:a948f5f3904c 143
sjallouli 0:a948f5f3904c 144
sjallouli 0:a948f5f3904c 145 ret = aci_gap_set_discoverable(ADV_IND, 0, 0, PUBLIC_ADDR, NO_WHITE_LIST_USE,
sjallouli 0:a948f5f3904c 146 8, local_name, 0, NULL, 0, 0);
sjallouli 0:a948f5f3904c 147
sjallouli 0:a948f5f3904c 148 }
sjallouli 0:a948f5f3904c 149
sjallouli 0:a948f5f3904c 150 /**************************************************************************/
sjallouli 0:a948f5f3904c 151 /*!
sjallouli 0:a948f5f3904c 152 @brief
sjallouli 0:a948f5f3904c 153
sjallouli 0:a948f5f3904c 154 @param[in] p_ble_evt
sjallouli 0:a948f5f3904c 155
sjallouli 0:a948f5f3904c 156 @returns
sjallouli 0:a948f5f3904c 157 */
sjallouli 0:a948f5f3904c 158 /**************************************************************************/
sjallouli 0:a948f5f3904c 159 static void btle_handler()
sjallouli 0:a948f5f3904c 160 {
sjallouli 0:a948f5f3904c 161
sjallouli 0:a948f5f3904c 162 }
sjallouli 0:a948f5f3904c 163
sjallouli 0:a948f5f3904c 164
sjallouli 0:a948f5f3904c 165 void SPI_Poll(void)
sjallouli 0:a948f5f3904c 166 {
sjallouli 0:a948f5f3904c 167 //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN);
sjallouli 0:a948f5f3904c 168 return;
sjallouli 0:a948f5f3904c 169 }
sjallouli 0:a948f5f3904c 170
sjallouli 0:a948f5f3904c 171 #ifdef __cplusplus
sjallouli 0:a948f5f3904c 172 extern "C" {
sjallouli 0:a948f5f3904c 173 #endif
sjallouli 0:a948f5f3904c 174
sjallouli 0:a948f5f3904c 175 /**************************************************************************/
sjallouli 0:a948f5f3904c 176 /*!
sjallouli 0:a948f5f3904c 177 @brief Handle HCI Stack Event
sjallouli 0:a948f5f3904c 178
sjallouli 0:a948f5f3904c 179 @param[in] pckt
sjallouli 0:a948f5f3904c 180 Event Packet sent by the stack to be decoded
sjallouli 0:a948f5f3904c 181
sjallouli 0:a948f5f3904c 182 @returns
sjallouli 0:a948f5f3904c 183 */
sjallouli 0:a948f5f3904c 184 /**************************************************************************/
sjallouli 0:a948f5f3904c 185 extern void HCI_Event_CB(void *pckt) {
sjallouli 0:a948f5f3904c 186
sjallouli 0:a948f5f3904c 187 hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt;
sjallouli 0:a948f5f3904c 188 hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data;
sjallouli 0:a948f5f3904c 189
sjallouli 0:a948f5f3904c 190 if(hci_pckt->type != HCI_EVENT_PKT)
sjallouli 0:a948f5f3904c 191 return;
sjallouli 0:a948f5f3904c 192
sjallouli 0:a948f5f3904c 193 switch(event_pckt->evt){
sjallouli 0:a948f5f3904c 194
sjallouli 0:a948f5f3904c 195 case EVT_DISCONN_COMPLETE:
sjallouli 0:a948f5f3904c 196 {
sjallouli 0:a948f5f3904c 197 evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt;
sjallouli 0:a948f5f3904c 198
sjallouli 0:a948f5f3904c 199 BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, BlueNRGGap::REMOTE_USER_TERMINATED_CONNECTION);
sjallouli 0:a948f5f3904c 200 }
sjallouli 0:a948f5f3904c 201 break;
sjallouli 0:a948f5f3904c 202
sjallouli 0:a948f5f3904c 203 case EVT_LE_META_EVENT:
sjallouli 0:a948f5f3904c 204 {
sjallouli 0:a948f5f3904c 205 evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data;
sjallouli 0:a948f5f3904c 206
sjallouli 0:a948f5f3904c 207 switch(evt->subevent){
sjallouli 0:a948f5f3904c 208 case EVT_LE_CONN_COMPLETE:
sjallouli 0:a948f5f3904c 209 {
sjallouli 0:a948f5f3904c 210 evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data;
sjallouli 0:a948f5f3904c 211
sjallouli 0:a948f5f3904c 212 BlueNRGGap::getInstance().setConnectionHandle(cc->handle);
sjallouli 0:a948f5f3904c 213 BlueNRGGap::ConnectionParams_t connectionParams;
sjallouli 0:a948f5f3904c 214 BlueNRGGap::getInstance().getPreferredConnectionParams(&connectionParams);
sjallouli 0:a948f5f3904c 215 BlueNRGGap::getInstance().processConnectionEvent(cc->handle, (const BlueNRGGap::ConnectionParams_t *)&connectionParams);
sjallouli 0:a948f5f3904c 216 }
sjallouli 0:a948f5f3904c 217 break;
sjallouli 0:a948f5f3904c 218 }
sjallouli 0:a948f5f3904c 219 }
sjallouli 0:a948f5f3904c 220 break;
sjallouli 0:a948f5f3904c 221
sjallouli 0:a948f5f3904c 222 case EVT_VENDOR:
sjallouli 0:a948f5f3904c 223 {
sjallouli 0:a948f5f3904c 224 evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data;
sjallouli 0:a948f5f3904c 225 switch(blue_evt->ecode){
sjallouli 0:a948f5f3904c 226
sjallouli 0:a948f5f3904c 227 case EVT_BLUE_GATT_READ_PERMIT_REQ:
sjallouli 0:a948f5f3904c 228 {
sjallouli 0:a948f5f3904c 229 DEBUG("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r");
sjallouli 0:a948f5f3904c 230 evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data;
sjallouli 0:a948f5f3904c 231 BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle);
sjallouli 0:a948f5f3904c 232 }
sjallouli 0:a948f5f3904c 233 break;
sjallouli 0:a948f5f3904c 234
sjallouli 0:a948f5f3904c 235 case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED:
sjallouli 0:a948f5f3904c 236 {
sjallouli 0:a948f5f3904c 237 /* this callback is invoked when a GATT attribute is modified
sjallouli 0:a948f5f3904c 238 extract callback data and pass to suitable handler function */
sjallouli 0:a948f5f3904c 239 evt_gatt_attr_modified *evt = (evt_gatt_attr_modified*)blue_evt->data;
sjallouli 0:a948f5f3904c 240 DEBUG("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r");
sjallouli 0:a948f5f3904c 241 //DEBUG("CharHandle 0x%x, length: 0x%x, Data: 0x%x\n\r",evt->attr_handle, evt->data_length, (uint16_t)evt->att_data[0]);
sjallouli 0:a948f5f3904c 242 DEBUG("CharHandle %d, length: %d, Data: %d\n\r",evt->attr_handle, evt->data_length, (uint16_t)evt->att_data[0]);
sjallouli 0:a948f5f3904c 243
sjallouli 0:a948f5f3904c 244 //Extract the GattCharacteristic from p_characteristics[] and find the properties mask
sjallouli 0:a948f5f3904c 245 GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(evt->attr_handle);
sjallouli 0:a948f5f3904c 246 if(p_char!=NULL) {
sjallouli 0:a948f5f3904c 247 DEBUG("getProperties 0x%x\n\r",p_char->getProperties());
sjallouli 0:a948f5f3904c 248 if((p_char->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY
sjallouli 0:a948f5f3904c 249 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) {
sjallouli 0:a948f5f3904c 250
sjallouli 0:a948f5f3904c 251 //Now Check if data written in Enable or Disable
sjallouli 0:a948f5f3904c 252 if((uint16_t)evt->att_data[0]==1) {
sjallouli 0:a948f5f3904c 253 //DEBUG("Notify ENABLED\n\r");
sjallouli 0:a948f5f3904c 254 BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, evt->attr_handle);
sjallouli 0:a948f5f3904c 255 }
sjallouli 0:a948f5f3904c 256 else {
sjallouli 0:a948f5f3904c 257 //DEBUG("Notify DISABLED\n\r");
sjallouli 0:a948f5f3904c 258 BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, evt->attr_handle);
sjallouli 0:a948f5f3904c 259 }
sjallouli 0:a948f5f3904c 260 }
sjallouli 0:a948f5f3904c 261
sjallouli 0:a948f5f3904c 262 //Check is attr handle property is WRITEABLE, if yes, generate GATT_EVENT_DATA_WRITTEN Event
sjallouli 0:a948f5f3904c 263 if((p_char->getProperties() &
sjallouli 0:a948f5f3904c 264 (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE|
sjallouli 0:a948f5f3904c 265 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) {
sjallouli 0:a948f5f3904c 266
sjallouli 0:a948f5f3904c 267 BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, evt->attr_handle);
sjallouli 0:a948f5f3904c 268 //Write the actual Data to the Attr Handle? (uint8_1[])evt->att_data contains the data
sjallouli 0:a948f5f3904c 269 if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getInitialLength() > 0)) {
sjallouli 0:a948f5f3904c 270 BlueNRGGattServer::getInstance().updateValue(p_char->getValueAttribute().getHandle(),
sjallouli 0:a948f5f3904c 271 p_char->getValueAttribute().getValuePtr(), p_char->getValueAttribute().getInitialLength(), false /* localOnly */);
sjallouli 0:a948f5f3904c 272 }
sjallouli 0:a948f5f3904c 273 }
sjallouli 0:a948f5f3904c 274 }
sjallouli 0:a948f5f3904c 275 }
sjallouli 0:a948f5f3904c 276 break;
sjallouli 0:a948f5f3904c 277
sjallouli 0:a948f5f3904c 278 //Any cases for Data Sent Notifications?
sjallouli 0:a948f5f3904c 279 case EVT_BLUE_GATT_NOTIFICATION:
sjallouli 0:a948f5f3904c 280 //This is only relevant for Client Side Event
sjallouli 0:a948f5f3904c 281 DEBUG("EVT_BLUE_GATT_NOTIFICATION");
sjallouli 0:a948f5f3904c 282 break;
sjallouli 0:a948f5f3904c 283 case EVT_BLUE_GATT_INDICATION:
sjallouli 0:a948f5f3904c 284 //This is only relevant for Client Side Event
sjallouli 0:a948f5f3904c 285 DEBUG("EVT_BLUE_GATT_INDICATION");
sjallouli 0:a948f5f3904c 286 break;
sjallouli 0:a948f5f3904c 287
sjallouli 0:a948f5f3904c 288 case EVT_BLUE_GATT_PROCEDURE_COMPLETE:
sjallouli 0:a948f5f3904c 289 DEBUG("EVT_BLUE_GATT_PROCEDURE_COMPLETE");
sjallouli 0:a948f5f3904c 290 break;
sjallouli 0:a948f5f3904c 291 }
sjallouli 0:a948f5f3904c 292 }
sjallouli 0:a948f5f3904c 293 break;
sjallouli 0:a948f5f3904c 294 }
sjallouli 0:a948f5f3904c 295
sjallouli 0:a948f5f3904c 296 return ;
sjallouli 0:a948f5f3904c 297 }
sjallouli 0:a948f5f3904c 298
sjallouli 0:a948f5f3904c 299
sjallouli 0:a948f5f3904c 300 #ifdef __cplusplus
sjallouli 0:a948f5f3904c 301 }
sjallouli 0:a948f5f3904c 302 #endif