Taeil Kim / Mbed OS color-firmware

Files at this revision

API Documentation at this revision

Comitter:
LAINO
Date:
Sat Apr 21 08:25:59 2018 +0000
Child:
1:6f55e05bb7a0
Commit message:
mbed os firmware of color

Changed in this revision

.mbed Show annotated file Show diff for this revision Revisions of this file
img/connection.png Show annotated file Show diff for this revision Revisions of this file
img/discovery.png Show annotated file Show diff for this revision Revisions of this file
img/notifications.png Show annotated file Show diff for this revision Revisions of this file
img/register_to_notifications.png Show annotated file Show diff for this revision Revisions of this file
img/scan_result.png Show annotated file Show diff for this revision Revisions of this file
img/start_scan.png Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
mbed_app.json Show annotated file Show diff for this revision Revisions of this file
module.json Show annotated file Show diff for this revision Revisions of this file
readme.md Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG.lib Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/.gitignore Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/README.md Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/mbed_lib.json Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/module.json Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Show annotated file Show diff for this revision Revisions of this file
shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Show annotated file Show diff for this revision Revisions of this file
source/main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.mbed	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,1 @@
+ROOT=.
Binary file img/connection.png has changed
Binary file img/discovery.png has changed
Binary file img/notifications.png has changed
Binary file img/register_to_notifications.png has changed
Binary file img/scan_result.png has changed
Binary file img/start_scan.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#addec7ba10054be03849eff58a1d17f157391e7d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_app.json	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,16 @@
+{
+    "target_overrides": {
+        "K64F": {
+            "target.features_add": ["BLE"],
+            "target.extra_labels_add": ["ST_BLUENRG"]
+        },
+        "NUCLEO_F401RE": {
+            "target.features_add": ["BLE"],
+            "target.extra_labels_add": ["ST_BLUENRG"]
+        },
+        "DISCO_L475VG_IOT01A": {
+            "target.features_add": ["BLE"],
+            "target.extra_labels_add": ["ST_BLUENRG"]
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/module.json	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,16 @@
+{
+  "name": "ble-batterylevel",
+  "version": "0.0.1",
+  "description": "An example of creating and updating a simple GATT Service using the BLE_API",
+  "licenses": [
+    {
+      "url": "https://spdx.org/licenses/Apache-2.0",
+      "type": "Apache-2.0"
+    }
+  ],
+  "dependencies": {
+    "ble": "^2.0.0"
+  },
+  "targetDependencies": {},
+  "bin": "./source"
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/readme.md	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,68 @@
+This example creates and updates a standard Battery Level service containing a single
+GATT characteristic.
+
+The [battery service transmits](https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml) a device's battery level in percentage, with 100% being a fully charged battery and 0% being a fully drained battery.
+
+Although the sample application runs on a BLE device, it doesn't show the device's real battery level (because that changes very slowly and will make for a dull example). Instead, it transmits a fake battery level that starts at 50% (half charged). Every half second, it increments the battery level, going in single increments until reaching 100% (as if the battery is charging). It then drops down to 20% to start incrementing again.
+
+# Running the application
+
+## Requirements
+
+The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install :
+
+- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android.
+
+- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone.
+
+Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md).
+
+## Building instructions
+
+Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md).
+
+## Checking for success
+
+**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals.
+
+1. Build the application and install it on your board as explained in the building instructions.
+1. Open the BLE scanner on your phone.
+1. Start a scan.
+
+    ![](img/start_scan.png)
+
+    **figure 1** How to start scan using nRF Master Control Panel 4.0.5
+
+1. Find your device; it should be named `BATTERY`.
+
+    ![](img/scan_result.png)
+
+    **figure 2** Scan results using nRF Master Control Panel 4.0.5
+
+1. Establish a connection with your device.
+
+    ![](img/connection.png)
+
+    **figure 3**  How to establish a connection using Master Control Panel 4.0.5
+
+1. Discover the services and the characteristics on the device. The *Battery service* has the UUID 0x180F and includes the *Battery level* characteristic which has the UUID 0x2A19.
+
+    ![](img/discovery.png)
+
+    **figure 4** Representation of the Battery service using Master Control Panel 4.0.5
+
+1. Register for the notifications sent by the *Battery level* characteristic.
+
+    ![](img/register_to_notifications.png)
+
+    **figure 5** How to register to notifications using Master Control Panel 4.0.5
+
+
+1. You should see the battery level value change every half second. It begins at 50, goes up to 100 (in steps of 1), resets to 20 and so on.
+
+    ![](img/notifications.png)
+
+    **figure 6** Notifications view using Master Control Panel 4.0.5
+
+If you can see the characteristic, and if its value is incrementing correctly, the application is working properly.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG.lib	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/#bcef7fa68b2deaa8ae7b2dbbe2648fdc8bae290b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/.gitignore	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,9 @@
+# vim temporary files
+*.sw*
+
+# yotta files
+build
+yotta_modules
+yotta_targets
+.yotta.json
+upload.tar.gz
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/README.md	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,34 @@
+# BLE-X-NUCLEO-IDB0XA1
+
+BLE_API wrapper Library for X-NUCLEO-IDB05A1 BlueNRG (Bluetooth Low Energy) Expansion Board
+
+## Introduction
+
+This firmware package implements the port of BLE_API to STMicroelectronics' [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) Bluetooth Low Energy Nucleo Expansion Board.
+
+### Arduino Connector Compatibility Warning
+
+X-NUCLEO-IDB05A1 is Arduino compatible with an exception: instead of using pin **D13** for the SPI clock, pin **D3** is used.
+The default configuration for this library is having the SPI clock on pin **D3**.
+
+To be fully Arduino compatible, X-NUCLEO-IDB05A1 needs a small HW patch.
+
+For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor **R4** and instead soldering zero resistor **R6**.
+
+In case you patch your board, then you also have to configure this library to use pin **D13** to drive the SPI clock. To this aim you need to compile this driver with macro `BLUENRG_PIN_SPI_SCK=D13` defined.
+
+If you use pin **D13** for the SPI clock, please be aware that on STM32 Nucleo boards you may **not** drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin **D13**.
+
+Referring to the current list of tested platforms (see [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) page), the patch is required by [ST-Nucleo-F103RB](https://developer.mbed.org/platforms/ST-Nucleo-F103RB/); [ST-Nucleo-F302R8](https://developer.mbed.org/platforms/ST-Nucleo-F302R8/); [ST-Nucleo-F411RE](https://developer.mbed.org/platforms/ST-Nucleo-F411RE/); [ST-Nucleo-F446RE](https://developer.mbed.org/platforms/ST-Nucleo-F446RE/); and [FRDM-K64F](https://developer.mbed.org/platforms/FRDM-K64F/).
+
+### Firmware update
+
+For better performance and compatibility with latest mbed API, you should update firmware of X-NUCLEO-IDB05A1 component by using this simple [application](https://developer.mbed.org/teams/ST/code/BlueNRG-MS-Stack-Updater).
+
+### Driver configuration
+
+In order to use the BlueNRG-MS module together with other targets, you need to set the macros defined in file [bluenrg_targets.h](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/bluenrg/bluenrg_targets.h). Please, update the [mbed_lib.json](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/mbed_lib.json) to include the list of extra macros that configure the driver for your target.
+
+## Example Applications
+
+To run BLE example applications using X-NUCLEO-IDB05A1 Expansion Board based on mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli), please refer to section [Using ST shield on other targets](https://github.com/ARMmbed/mbed-os-example-ble#using-st-nucleo-shield-on-other-targets) in the official [mbed-os-example-ble](https://github.com/ARMmbed/mbed-os-example-ble) page.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,111 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/**
+  ******************************************************************************
+  * @file    BlueNRGDevice.h 
+  * @author  STMicroelectronics
+  * @brief   Header file for BLEDeviceInstanceBase based BlueNRGDevice
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */ 
+  
+#ifndef __BLUENRG_DEVICE_H__
+#define __BLUENRG_DEVICE_H__
+
+#define BLUENRG
+#define DEBUG_BLUENRG_USER
+
+#include "btle.h"
+
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif 
+#include "ble/blecommon.h"
+#include "ble/BLEInstanceBase.h"
+#include "ble/BLE.h"
+#include "BlueNRGGap.h"
+#include "BlueNRGGattServer.h"
+#include "BlueNRGGattClient.h"
+
+
+class BlueNRGDevice : public BLEInstanceBase
+{
+
+public:
+    BlueNRGDevice(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, PinName irq);
+    virtual ~BlueNRGDevice(void);
+
+    virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback);
+    virtual ble_error_t shutdown(void);   
+    virtual const char *getVersion(void);
+    virtual Gap&        getGap();
+    virtual const Gap&  getGap() const;
+    virtual GattServer& getGattServer();
+    virtual const GattServer& getGattServer() const;
+    virtual void        waitForEvent(void);
+    
+    virtual GattClient& getGattClient() {
+        return BlueNRGGattClient::getInstance();
+    }
+
+    virtual SecurityManager& getSecurityManager() {
+        return *sm;
+    }
+
+    virtual const SecurityManager& getSecurityManager() const {
+        return *sm;
+    }
+    void reset(void);
+    virtual bool hasInitialized(void) const {
+        return isInitialized;
+    }
+
+    uint8_t getUpdaterHardwareVersion(uint8_t *hw_version);
+    int updateFirmware(const uint8_t *fw_image, uint32_t fw_size);
+    bool dataPresent();
+    int32_t spiRead(uint8_t *buffer, uint8_t buff_size);
+    int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2);
+    void disable_irq();
+    void enable_irq();
+
+    virtual void processEvents();
+    
+private:
+    bool isInitialized;
+
+    SPI         spi_;
+    DigitalOut  nCS_;
+    DigitalOut  rst_;
+    InterruptIn irq_;
+
+    //FIXME: TBI (by now just placeholders to let build
+    /*** betzw: placeholders ***/
+    SecurityManager *sm;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,46 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__
+#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__
+
+#include "ble/DiscoveredCharacteristic.h"
+
+class BlueNRGGattClient; /* forward declaration */
+
+class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic {
+public:
+
+  void setup(BlueNRGGattClient         *gattcIn,
+             Gap::Handle_t            connectionHandleIn,
+             DiscoveredCharacteristic::Properties_t    propsIn,
+             GattAttribute::Handle_t  declHandleIn,
+             GattAttribute::Handle_t  valueHandleIn,
+             GattAttribute::Handle_t  lastHandleIn);
+
+  void setup(BlueNRGGattClient         *gattcIn,
+             Gap::Handle_t            connectionHandleIn,
+             UUID   uuidIn,
+             DiscoveredCharacteristic::Properties_t    propsIn,
+             GattAttribute::Handle_t  declHandleIn,
+             GattAttribute::Handle_t  valueHandleIn,
+             GattAttribute::Handle_t  lastHandleIn);
+
+
+  void setLastHandle(GattAttribute::Handle_t  lastHandleIn);
+};
+
+#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,230 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/**
+  ******************************************************************************
+  * @file    BlueNRGGap.h
+  * @author  STMicroelectronics
+  * @brief   Header file for BlueNRG BLE_API Gap Class
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */
+
+#ifndef __BLUENRG_GAP_H__
+#define __BLUENRG_GAP_H__
+
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif 
+#include "ble/blecommon.h"
+#include "btle.h"
+#include "ble/GapAdvertisingParams.h"
+#include "ble/GapAdvertisingData.h"
+#include "ble/Gap.h"
+
+#define BLE_CONN_HANDLE_INVALID 0x0
+#define BDADDR_SIZE 6
+
+#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020)
+#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000)
+#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0)
+
+// Scanning and Connection Params used by Central for creating connection
+#define GAP_OBSERVATION_PROC (0x80)
+
+#define SCAN_P         (0x0010)
+#define SCAN_L         (0x0010)
+#define SUPERV_TIMEOUT (0xC80)
+#define CONN_P(x)      ((int)((x)/1.25f))
+#define CONN_L(x)      ((int)((x)/0.625f))
+#define CONN_P1        ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C)
+#define CONN_P2        ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C)
+#define CONN_L1        (0x0008)
+#define CONN_L2        (0x0008)
+#define GUARD_INT      5 //msec
+#define MIN_INT_CONN   0x0006 //=>7.5msec
+#define MAX_INT_CONN   0x0C80 //=>4000msec
+#define DEF_INT_CONN   0x0140 //=>400msec (default value for connection interval)
+
+/**************************************************************************/
+/*!
+    \brief
+
+*/
+/**************************************************************************/
+class BlueNRGGap : public Gap
+{
+public:
+    static BlueNRGGap &getInstance() {
+        static BlueNRGGap m_instance;
+        return m_instance;
+    }
+
+    enum Reason_t {
+        DEVICE_FOUND,
+        DISCOVERY_COMPLETE
+    };
+
+    /* Functions that must be implemented from Gap */
+    virtual ble_error_t setAddress(addr_type_t type, const BLEProtocol::AddressBytes_t address);
+    virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address);
+    virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &);
+    virtual ble_error_t startAdvertising(const GapAdvertisingParams &);
+    virtual ble_error_t stopAdvertising(void);
+    virtual ble_error_t stopScan();
+    virtual uint16_t    getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);}
+    virtual uint16_t    getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);}
+    virtual uint16_t    getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);}
+    virtual ble_error_t disconnect(DisconnectionReason_t reason);
+    virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason);
+    virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params);
+    virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params);
+    virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params);
+
+    virtual ble_error_t setDeviceName(const uint8_t *deviceName);
+    virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP);
+    virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance);
+    virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP);
+
+    virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode);
+    virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode);
+    virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const;
+    virtual ScanningPolicyMode_t getScanningPolicyMode(void) const;
+
+    virtual ble_error_t setTxPower(int8_t txPower);
+    virtual void        getPermittedTxPowerValues(const int8_t **, size_t *);
+
+    virtual ble_error_t connect(const Address_t peerAddr,
+                                Gap::AddressType_t peerAddrType,
+                                const ConnectionParams_t *connectionParams,
+                                const GapScanningParams *scanParams);
+
+    virtual ble_error_t reset(void);
+
+    void                Discovery_CB(Reason_t reason,
+                                     uint8_t adv_type,
+                                     uint8_t addr_type,
+                                     uint8_t *addr,
+                                     uint8_t *data_length,
+                                     uint8_t *data,
+                                     uint8_t *RSSI);
+    ble_error_t         createConnection(void);
+
+    void     setConnectionHandle(uint16_t con_handle);
+    uint16_t getConnectionHandle(void);
+
+    bool getIsSetAddress();
+
+    // ADV timeout handling
+    Timeout& getAdvTimeout(void) {
+        return advTimeout;
+    }
+    uint8_t getAdvToFlag(void) {
+        return AdvToFlag;
+    }
+    void setAdvToFlag(void);
+
+    // SCAN timeout handling
+    Timeout& getScanTimeout(void) {
+        return scanTimeout;
+    }
+    uint8_t getScanToFlag(void) {
+        return ScanToFlag;
+    }
+    void setScanToFlag(void);
+
+    void Process(void);
+
+    GapScanningParams* getScanningParams(void);
+
+    virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams);
+
+    void setConnectionInterval(uint16_t interval);
+    Gap::Role_t getGapRole(void);
+    void setGapRole(Gap::Role_t role);
+
+private:
+    uint16_t m_connectionHandle;
+    Role_t gapRole;
+    AddressType_t addr_type;
+    Address_t _peerAddr;
+    AddressType_t _peerAddrType;
+    uint8_t bdaddr[BDADDR_SIZE];
+    bool _scanning;
+    bool _connecting;
+    bool isSetAddress;
+    uint8_t deviceAppearance[2];
+
+    // ADV timeout handling
+    Timeout advTimeout;
+    bool AdvToFlag;
+
+    // SCAN timeout handling
+    Timeout scanTimeout;
+    bool ScanToFlag;
+
+    static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) {
+        return (duration * 625) / 1000;
+    }
+
+    uint16_t scanInterval;
+    uint16_t scanWindow;
+    uint16_t advInterval;
+    uint16_t slaveConnIntervMin;
+    uint16_t slaveConnIntervMax;
+    uint16_t conn_min_interval;
+    uint16_t conn_max_interval;
+    void setAdvParameters(void);
+    void setConnectionParameters(void);
+
+    Gap::AdvertisingPolicyMode_t advertisingPolicyMode;
+    Gap::ScanningPolicyMode_t scanningPolicyMode;
+
+    Whitelist_t whitelistAddresses;
+
+    ble_error_t updateAdvertisingData(void);
+
+    BlueNRGGap() : AdvToFlag(false), ScanToFlag(false) {
+        m_connectionHandle = BLE_CONN_HANDLE_INVALID;
+        addr_type = BLEProtocol::AddressType::RANDOM_STATIC;
+
+        /* Set the whitelist policy filter modes to IGNORE_WHITELIST */
+        advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST;
+        scanningPolicyMode    = Gap::SCAN_POLICY_IGNORE_WHITELIST;
+
+        isSetAddress = false;
+        memset(deviceAppearance, 0, sizeof(deviceAppearance));
+    }
+
+    BlueNRGGap(BlueNRGGap const &);
+    void operator=(BlueNRGGap const &);
+
+    GapAdvertisingData _advData;
+    GapAdvertisingData _scanResponse;
+};
+
+#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,157 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/**
+  ******************************************************************************
+  * @file    BlueNRGGattClient.cpp 
+  * @author  STMicroelectronics
+  * @brief   Header file for BLE_API GattClient Class
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
+  */
+ 
+#ifndef __BLUENRG_GATT_CLIENT_H__
+#define __BLUENRG_GATT_CLIENT_H__
+
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif 
+#include "ble/blecommon.h"
+#include "btle.h"
+#include "ble/GattClient.h"
+#include "ble/DiscoveredService.h"
+#include "ble/CharacteristicDescriptorDiscovery.h"
+#include "BlueNRGDiscoveredCharacteristic.h"
+#include "BlueNRGGattConnectionClient.h"
+
+using namespace std;
+
+#define MAX_ACTIVE_CONNECTIONS 7
+
+class BlueNRGGattClient : public GattClient
+{
+public:
+    static BlueNRGGattClient &getInstance() {
+        static BlueNRGGattClient m_instance;
+        return m_instance;
+    }
+
+    ble_error_t createGattConnectionClient(Gap::Handle_t connectionHandle);
+    ble_error_t removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason);
+    
+    /* Functions that must be implemented from GattClient */
+    virtual ble_error_t launchServiceDiscovery(Gap::Handle_t                               connectionHandle,
+                                               ServiceDiscovery::ServiceCallback_t         sc                           = NULL,
+                                               ServiceDiscovery::CharacteristicCallback_t  cc                           = NULL,
+                                               const UUID                                 &matchingServiceUUID          = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
+                                               const UUID                                 &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN));
+
+    virtual ble_error_t discoverServices(Gap::Handle_t                        connectionHandle,
+                                         ServiceDiscovery::ServiceCallback_t  callback,
+                                         const UUID                          &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN));
+
+    virtual ble_error_t discoverServices(Gap::Handle_t                        connectionHandle,
+                                         ServiceDiscovery::ServiceCallback_t  callback,
+                                         GattAttribute::Handle_t              startHandle,
+                                         GattAttribute::Handle_t              endHandle);
+
+    virtual bool isServiceDiscoveryActive(void) const;
+    virtual void terminateServiceDiscovery(void);
+    virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback);
+    virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const;
+    virtual ble_error_t write(GattClient::WriteOp_t    cmd,
+                              Gap::Handle_t            connHandle,
+                              GattAttribute::Handle_t  attributeHandle,
+                              size_t                   length,
+                              const uint8_t           *value) const;
+    virtual ble_error_t discoverCharacteristicDescriptors(
+        const DiscoveredCharacteristic& characteristic,
+        const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
+        const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback);
+
+    virtual ble_error_t reset(void);
+
+    void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code);
+
+    void primaryServicesCB(Gap::Handle_t connectionHandle,
+                           uint8_t event_data_length,
+                           uint8_t attribute_data_length,
+                           uint8_t *attribute_data_list);
+    
+    void primaryServiceCB(Gap::Handle_t connectionHandle,
+                          uint8_t event_data_length,
+                          uint8_t *handles_info_list);
+    
+    ble_error_t findServiceChars(Gap::Handle_t connectionHandle);
+    
+    void serviceCharsCB(Gap::Handle_t connectionHandle,
+                        uint8_t event_data_length,
+                        uint8_t handle_value_pair_length,
+                        uint8_t *handle_value_pair);
+    
+    void serviceCharByUUIDCB(Gap::Handle_t connectionHandle,
+                             uint8_t event_data_length,
+                             uint16_t attr_handle,
+                             uint8_t *attr_value);
+
+    void discAllCharacDescCB(Gap::Handle_t connHandle,
+                             uint8_t event_data_length,
+                             uint8_t format,
+                             uint8_t *handle_uuid_pair);
+
+    void charReadCB(Gap::Handle_t connHandle,
+                    uint8_t event_data_length,
+                    uint8_t* attribute_value);
+
+    void charWritePrepareCB(Gap::Handle_t connHandle,
+                            uint8_t event_data_length,
+                            uint16_t attribute_handle,
+                            uint16_t offset,
+                            uint8_t *part_attr_value);
+    
+    void charWriteExecCB(Gap::Handle_t connHandle,
+                         uint8_t event_data_length);
+
+
+protected:
+
+    BlueNRGGattClient(): _connectionPool() {};
+
+    ServiceDiscovery::TerminationCallback_t terminationCallback;
+
+private:
+
+  BlueNRGGattClient(BlueNRGGattClient const &);
+  void operator=(BlueNRGGattClient const &);
+
+  BlueNRGGattConnectionClient *_connectionPool[MAX_ACTIVE_CONNECTIONS];
+  uint8_t _numConnections;
+
+  BlueNRGGattConnectionClient * getGattConnectionClient(Gap::Handle_t connectionHandle);
+
+};
+
+#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,185 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/**
+  ******************************************************************************
+  * @file    BlueNRGGattConnectionClient.cpp 
+  * @author  STMicroelectronics
+  * @brief   Header file for BlueNRGGattConnectionClient Class
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
+  */
+ 
+#ifndef __BLUENRG_GATT_CONNECTION_CLIENT_H__
+#define __BLUENRG_GATT_CONNECTION_CLIENT_H__
+
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif 
+#include "ble/blecommon.h"
+#include "btle.h"
+#include "ble/GattClient.h"
+#include "ble/DiscoveredService.h"
+#include "ble/CharacteristicDescriptorDiscovery.h"
+#include "BlueNRGDiscoveredCharacteristic.h"
+
+using namespace std;
+
+#define BLE_TOTAL_DISCOVERED_SERVICES 10
+#define BLE_TOTAL_DISCOVERED_CHARS 10
+
+class BlueNRGGattConnectionClient
+{
+public:
+    
+    enum {
+      GATT_IDLE,
+      GATT_SERVICE_DISCOVERY,
+      GATT_CHAR_DESC_DISCOVERY,
+      //GATT_CHARS_DISCOVERY_COMPLETE,
+      //GATT_DISCOVERY_TERMINATED,
+      GATT_READ_CHAR,
+      GATT_WRITE_CHAR
+    };
+    
+    /* Functions that must be implemented from GattClient */
+    ble_error_t launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t         sc                           = NULL,
+                                       ServiceDiscovery::CharacteristicCallback_t  cc                           = NULL,
+                                       const UUID                                 &matchingServiceUUID          = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
+                                       const UUID                                 &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN));
+
+    ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t  callback,
+                                         const UUID                          &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN));
+
+    ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t  callback,
+                                         GattAttribute::Handle_t              startHandle,
+                                         GattAttribute::Handle_t              endHandle);
+
+    bool isServiceDiscoveryActive(void) const;
+    void terminateServiceDiscovery(void);
+    void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) {
+      terminationCallback = callback;
+    }
+    ble_error_t read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const;
+    ble_error_t write(GattClient::WriteOp_t    cmd,
+                              GattAttribute::Handle_t  attributeHandle,
+                              size_t                   length,
+                              const uint8_t           *value) const;
+    ble_error_t discoverCharacteristicDescriptors(
+        const DiscoveredCharacteristic& characteristic,
+        const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
+        const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback);
+
+    ble_error_t reset(void);
+
+    void gattProcedureCompleteCB(uint8_t error_code);
+
+    void primaryServicesCB(uint8_t event_data_length,
+                           uint8_t attribute_data_length,
+                           uint8_t *attribute_data_list);
+    
+    void primaryServiceCB(uint8_t event_data_length,
+                          uint8_t *handles_info_list);
+    
+    ble_error_t findServiceChars(void);
+    
+    void serviceCharsCB(uint8_t event_data_length,
+                        uint8_t handle_value_pair_length,
+                        uint8_t *handle_value_pair);
+    
+    void serviceCharByUUIDCB(uint8_t event_data_length,
+                             uint16_t attr_handle,
+                             uint8_t *attr_value);
+
+    void discAllCharacDescCB(uint8_t event_data_length,
+                             uint8_t format,
+                             uint8_t *handle_uuid_pair);
+
+    void charReadCB(uint8_t event_data_length,
+                    uint8_t* attribute_value);
+
+    void charWritePrepareCB(uint8_t event_data_length,
+                            uint16_t attribute_handle,
+                            uint16_t offset,
+                            uint8_t *part_attr_value);
+    
+    void charWriteExecCB(uint8_t event_data_length);
+
+protected:
+
+    BlueNRGGattConnectionClient(BlueNRGGattClient *gattClient, Gap::Handle_t connectionHandle):
+                                discoveredService(),
+                                discoveredChar(),
+                                readCBParams(),
+                                writeCBParams(),
+                                _characteristic()  {
+
+     //PRINTF("BlueNRGGattConnectionClient construtor: connHandle=%d\n\r", connectionHandle);
+
+     _gattClient = gattClient;
+     _connectionHandle = connectionHandle;
+
+     _currentState = GATT_IDLE;
+     _matchingServiceUUID = BLE_UUID_UNKNOWN;
+     _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN;
+
+    }
+
+    ServiceDiscovery::ServiceCallback_t  serviceDiscoveryCallback;
+    ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback;
+    ServiceDiscovery::TerminationCallback_t terminationCallback;
+    CharacteristicDescriptorDiscovery::DiscoveryCallback_t charDescDiscoveryCallback;
+    CharacteristicDescriptorDiscovery::TerminationCallback_t charDescTerminationCallback;
+
+private:
+
+  BlueNRGGattConnectionClient(BlueNRGGattConnectionClient const &);
+  void operator=(BlueNRGGattConnectionClient const &);
+  ~BlueNRGGattConnectionClient() {};
+
+  BlueNRGGattClient *_gattClient;
+
+  Gap::Handle_t _connectionHandle;
+  DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES];
+  BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS];
+  
+  GattReadCallbackParams readCBParams;
+  GattWriteCallbackParams writeCBParams;
+
+  // The char for which the descriptor discovery has been launched  
+  DiscoveredCharacteristic _characteristic;
+
+  UUID _matchingServiceUUID;
+  UUID _matchingCharacteristicUUIDIn;
+  uint8_t _currentState;
+  uint8_t _numServices, _servIndex;
+  uint8_t _numChars;
+  uint8_t _numCharDesc;
+  
+  friend class BlueNRGGattClient;
+};
+
+#endif /* __BLUENRG_GATT_CONNECTION_CLIENT_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,125 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/**
+  ******************************************************************************
+  * @file    BlueNRGGattServer.cpp
+  * @author  STMicroelectronics
+  * @brief   Header file for BLE_API GattServer Class
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */
+
+#ifndef __BLUENRG_GATT_SERVER_H__
+#define __BLUENRG_GATT_SERVER_H__
+
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif 
+#include "ble/blecommon.h"
+#include "btle.h"
+#include "ble/GattService.h"
+#include "ble/GattServer.h"
+#include <vector>
+#include <map>
+
+#define BLE_TOTAL_CHARACTERISTICS 10
+
+using namespace std;
+
+class BlueNRGGattServer : public GattServer
+{
+public:
+    static BlueNRGGattServer &getInstance() {
+        static BlueNRGGattServer m_instance;
+        return m_instance;
+    }
+
+    enum HandleEnum_t {
+        CHAR_HANDLE = 0,
+        CHAR_VALUE_HANDLE,
+        CHAR_DESC_HANDLE
+    };
+
+    /* Functions that must be implemented from GattServer */
+    virtual ble_error_t addService(GattService &);
+    virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
+    virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
+    virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false);
+    virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false);
+    virtual ble_error_t initializeGATTDatabase(void);
+
+    virtual bool isOnDataReadAvailable() const {
+        return true;
+    }
+
+    virtual ble_error_t reset(void);
+
+    /* BlueNRG Functions */
+    void eventCallback(void);
+    //void hwCallback(void *pckt);
+    ble_error_t Read_Request_CB(uint16_t attributeHandle);
+    uint8_t Write_Request_CB(
+        uint16_t connection_handle, uint16_t attr_handle,
+        uint8_t data_length, const uint8_t* data
+    );
+    GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle);
+    void HCIDataWrittenEvent(const GattWriteCallbackParams *params);
+    void HCIDataReadEvent(const GattReadCallbackParams *params);
+    void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle);
+    void HCIDataSentEvent(unsigned count);
+
+private:
+
+    // compute the number of attribute record needed by a service
+    static uint16_t computeAttributesRecord(GattService& service);
+
+
+    static const int MAX_SERVICE_COUNT = 10;
+    uint8_t serviceCount;
+    uint8_t characteristicCount;
+    uint16_t servHandle, charHandle;
+
+    std::map<uint16_t, uint16_t> bleCharHandleMap;  // 1st argument is characteristic, 2nd argument is service
+    GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS];
+    uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS];
+
+    BlueNRGGattServer() {
+        serviceCount = 0;
+        characteristicCount = 0;
+    };
+
+    BlueNRGGattServer(BlueNRGGattServer const &);
+    void operator=(BlueNRGGattServer const &);
+
+    static const int CHAR_DESC_TYPE_16_BIT=0x01;
+    static const int CHAR_DESC_TYPE_128_BIT=0x02;
+    static const int CHAR_DESC_SECURITY_PERMISSION=0x00;
+    static const int CHAR_DESC_ACCESS_PERMISSION=0x03;
+    static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,59 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : ble_clock.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.1
+* Date               : 19-July-2012
+* Description        : Header file for clock library, that gives a simple time
+*                       reference to the BLE Stack.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLE_CLOCK_H__
+#define __BLE_CLOCK_H__
+
+#include <ble_hal_types.h>
+
+/**
+ * Number of clocks in one seconds.
+ * This value must be set by each platorm implementation, basing on its needs.
+ */
+extern const uint32_t CLOCK_SECOND;
+
+typedef uint32_t tClockTime;
+
+/**
+ * This function initializes the clock library and should be called before
+ * any other Stack functions.
+ *
+ */
+void Clock_Init(void);
+
+/**
+ * This function returns the current system clock time. it is used by
+ * the host stack and has to be implemented.
+ *
+ * @return The current clock time, measured in system ticks.
+ */
+tClockTime Clock_Time(void);
+
+/**
+ * This function waits for a given number of milliseconds.
+ *
+ */
+void Clock_Wait(uint32_t i);
+
+/**
+ * It suspends system clock.
+ *
+ */
+void Clock_Suspend(void);
+
+
+#endif /* __BLE_CLOCK_H__ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,36 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : ble_compiler.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : Compiler-dependent macros.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+#ifdef __ICCARM__
+#define PACKED
+#else
+#ifdef __GNUC__
+#undef __packed
+#define __packed
+#ifndef PACKED
+#define PACKED __attribute__((packed))
+#endif
+#else
+#define PACKED
+#define __packed
+#endif
+#endif
+
+/* Change this define to 1 if zero-length arrays are not supported by your compiler. */
+#define VARIABLE_SIZE 1
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,73 @@
+/**
+  ******************************************************************************
+  * @file    ble_debug.h
+  * @author  CL
+  * @version V1.0.0
+  * @date    04-July-2014
+  * @brief   This file defines print functions for debug purposes.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __BLE_DEBUG_H
+#define __BLE_DEBUG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+
+/* Exported macro ------------------------------------------------------------*/
+//#define DEBUG
+#ifdef DEBUG
+#include <stdio.h>
+#define PRINTF(...) printf(__VA_ARGS__)
+#else
+#define PRINTF(...)
+#endif
+
+/* Print the data travelling over the SPI in the .csv format for the GUI*/
+//#define PRINT_CSV_FORMAT
+#ifdef PRINT_CSV_FORMAT
+#include <stdio.h>
+#define PRINT_CSV(...) printf(__VA_ARGS__)
+#else
+#define PRINT_CSV(...)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BLE_DEBUG_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,105 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : ble_gp_timer.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : General purpose timer library.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLE_GP_TIMER_H__
+#define __BLE_GP_TIMER_H__
+
+#include "ble_clock.h"
+#include "ble_status.h"
+#ifdef __DMA_LP__
+#include "stm32xx_timerserver.h"
+#endif /* __DMA_LP__ */
+
+/**
+ * timer
+ *
+ * A structure that represents a timer. Use Timer_Set() to set the timer.
+ *
+ */
+struct timer {
+    
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+    
+  tClockTime start;
+  tClockTime interval;
+  
+#endif
+};
+
+typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void);
+
+/**
+ * Timer_Set
+ *
+ * @param[in] t             Pointer to a timer structure
+ * @param[in] interval      timeout value
+ *
+ * This function sets the timeout value of a timer.
+ *
+ */
+void Timer_Set(struct timer *t, tClockTime interval);
+
+/**
+ * Timer_Reset
+ * 
+ * @param[in] t     Pointer to a timer structure
+ * 
+ * This function resets the timer with the same interval given
+ * with Timer_Set, starting from the time it previously expired.
+ * 
+ */ 
+void Timer_Reset(struct timer *t);
+
+/**
+ * Timer_Restart
+ * 
+ * @param[in]  t   Pointer to a timer structure
+ * 
+ * This function resets the timer with the same interval given
+ * with Timer_Set, starting from the current time.
+ * 
+ */ 
+void Timer_Restart(struct timer *t);
+
+/**
+ * Timer_Expired
+ *
+ * @param[in] t    Pointer to a timer structure
+ *
+ * This function returns TRUE if timer is expired, FALSE otherwise.
+ *
+ */
+int Timer_Expired(struct timer *t);
+
+/**
+ * Timer_Expired
+ *
+ * @param[in] t    Pointer to a timer structure
+ *
+ * This function returns the time needed for expiration.
+ *
+ * @return  Time before timer's expiration.
+ */
+tClockTime Timer_Remaining(struct timer *t);
+
+#ifdef __DMA_LP__
+tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime,
+		TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb,
+					   uint8_t *timerID);
+
+tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID);
+#endif /* __DMA_LP__ */
+
+#endif /* __BLE_GP_TIMER_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,108 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : ble_hal.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : Header file which defines Hardware abstraction layer APIs
+*                       used by the BLE stack. It defines the set of functions
+*                       which needs to be ported to the target platform.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef __BLE_HAL_H__
+#define __BLE_HAL_H__
+
+/******************************************************************************
+ * Includes
+ *****************************************************************************/
+#include <ble_hal_types.h>
+#include <ble_status.h>
+
+
+/******************************************************************************
+ * Macros
+ *****************************************************************************/
+/* Little Endian buffer to host endianess conversion */
+#define LE_TO_HOST_16(ptr)  (uint16_t) ( ((uint16_t) \
+                                           *((uint8_t *)ptr)) | \
+                                          ((uint16_t) \
+                                           *((uint8_t *)ptr + 1) << 8 ) )
+
+#define LE_TO_HOST_32(ptr)   (uint32_t) ( ((uint32_t) \
+                                           *((uint8_t *)ptr)) | \
+                                           ((uint32_t) \
+                                            *((uint8_t *)ptr + 1) << 8)  | \
+                                           ((uint32_t) \
+                                            *((uint8_t *)ptr + 2) << 16) | \
+                                           ((uint32_t) \
+                                            *((uint8_t *)ptr + 3) << 24) )
+
+/* Big Endian buffer to host endianess conversion */
+#define BE_TO_HOST_16(ptr)  (uint16_t) ( ((uint16_t) \
+                                           *((uint8_t *)ptr)) << 8 | \
+                                          ((uint16_t) \
+                                           *((uint8_t *)ptr + 1) ) )
+											
+/* Store Value into a buffer in Little Endian Format */
+#define HOST_TO_LE_16(buf, val)    ( ((buf)[0] =  (uint8_t) (val)    ) , \
+                                   ((buf)[1] =  (uint8_t) (val>>8) ) )
+
+#define HOST_TO_LE_32(buf, val)    ( ((buf)[0] =  (uint8_t) (val)     ) , \
+                                   ((buf)[1] =  (uint8_t) (val>>8)  ) , \
+                                   ((buf)[2] =  (uint8_t) (val>>16) ) , \
+                                   ((buf)[3] =  (uint8_t) (val>>24) ) ) 
+
+
+/* Store Value into a buffer in Big Endian Format */
+#define HOST_TO_BE_16(buf, val)    ( ((buf)[1] =  (uint8_t) (val)    ) , \
+                                   ((buf)[0] =  (uint8_t) (val>>8) ) )
+
+#define DISABLE_INTERRUPTS() __disable_interrupt()
+#define ENABLE_INTERRUPTS() __enable_interrupt()
+#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK()
+#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \
+                                __disable_interrupt(); \
+/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */
+#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit)
+ 
+/******************************************************************************
+ * Types
+ *****************************************************************************/
+
+/******************************************************************************
+ * Function Prototypes
+ *****************************************************************************/
+
+/**
+ * Writes data to a serial interface.
+ *
+ * @param[in]  data1    1st buffer
+ * @param[in]  data2    2nd buffer
+ * @param[in]  n_bytes1 number of bytes in 1st buffer
+ * @param[in]  n_bytes2 number of bytes in 2nd buffer
+ */
+void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2);
+
+/**
+ * Enable interrupts from HCI controller.
+ */
+void Enable_SPI_IRQ(void);
+
+/**
+ * Disable interrupts from BLE controller.
+ */
+void Disable_SPI_IRQ(void);
+
+void signalEventsToProcess(void);
+
+void Hal_Init_Timer(void);
+uint32_t Hal_Get_Timer_Value(void);
+void Hal_Start_Timer(uint32_t timeout);
+void Hal_Stop_Timer(void);
+
+#endif /* __BLE_HAL_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,58 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : ble_hal_types.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : This header file defines the basic data types used by the
+*                       BLE stack.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef __BLE_HAL_TYPES_H__
+#define __BLE_HAL_TYPES_H__
+
+#include <stdint.h>
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#ifndef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN 0
+#define __BIG_ENDIAN    1
+#endif
+
+/* Byte order conversions */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define htobs(d)  (d)
+#define htobl(d)  (d)
+#define btohs(d)  (d)
+#define btohl(d)  (d)
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define htobs(d)  (d<<8|d>>8)
+#define htobl(d)  (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff))
+#define btohs(d)  (d<<8|d>>8)
+#define btohl(d)  (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff))
+#else
+#error "Unknown byte order"
+#endif
+
+typedef uint8_t BOOL;
+
+#ifndef TRUE 
+#define TRUE (1)
+#endif
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+
+
+#endif /* __BLE_HAL_TYPES_H__ */ 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,126 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : ble_hci.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : Constants and functions for HCI layer. See Bluetooth Core
+*                      v 4.0, Vol. 2, Part E.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLE_HCI_H_
+#define __BLE_HCI_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ble_hal_types.h"
+#include "ble_link_layer.h"
+#include <ble_list.h>
+
+#define HCI_READ_PACKET_SIZE                    128 //71
+
+/**
+ * Maximum payload of HCI commands that can be sent. Change this value if needed.
+ * This value can be up to 255.
+ */
+#define HCI_MAX_PAYLOAD_SIZE 128
+
+/*** Data types ***/
+
+/* structure used to read received data */
+typedef struct _tHciDataPacket
+{
+  tListNode currentNode;
+  uint8_t dataBuff[HCI_READ_PACKET_SIZE];
+  uint8_t data_len;
+} tHciDataPacket;
+
+struct hci_request {
+  uint16_t ogf;
+  uint16_t ocf;
+  int      event;
+  void     *cparam;
+  int      clen;
+  void     *rparam;
+  int      rlen;
+};
+
+typedef enum
+{
+  BUSY,
+  AVAILABLE
+} HCI_CMD_STATUS_t;
+
+
+/**
+ * This function must be used to pass the packet received from the HCI
+ * interface to the BLE Stack HCI state machine.
+ *
+ * @param[in] hciReadPacket    The packet that is received from HCI interface.
+ *
+ */
+void HCI_Input(tHciDataPacket *hciReadPacket);
+
+/**
+ * Initialization function. Must be done before any data can be received from
+ * BLE controller.
+ */
+void HCI_Init(void);
+
+/**
+ * Callback used to pass events to application.
+ *
+ * @param[in] pckt    The event.
+ *
+ */
+extern void HCI_Event_CB(void *pckt);
+
+/**
+ * Processing function that must be called after an event is received from
+ * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if
+ * necessary.
+*/
+void HCI_Process(void);
+
+/**
+ * @brief Check if queue of HCI event is empty or not.
+ * @note This funtion can be used to check if the event queue from BlueNRG is empty. This
+ *        is useful when checking if it is safe to go to sleep. 
+ * @return TRUE if event queue is empty. FALSE otherwhise.
+ */
+BOOL HCI_Queue_Empty(void);
+/**
+ * Iterrupt service routine that must be called when the BlueNRG 
+ * reports a packet received or an event to the host through the 
+ * BlueNRG interrupt line.
+ */
+#ifdef __DMA_LP__
+void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len);
+void HCI_Process_Notification_Request(void);
+void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status);
+void HCI_Wait_For_Response(void);
+#else
+void HCI_Isr(void);
+void HCI_HandleSPI(void);
+
+int hci_send_req(struct hci_request *r, BOOL async);
+#endif /* __DMA_LP__ */
+
+extern tListNode hciReadPktPool;
+extern tListNode hciReadPktRxQueue;
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __BLE_HCI_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,548 @@
+/******************************************************************************
+*
+*  File Description 
+*  ---------------------
+* This file defines constants and functions for HCI layer.
+* See Bluetooth Core v 4.0, Vol. 2, Part E.
+* 
+*******************************************************************************/
+
+#ifndef __HCI_INTERNAL_H_
+#define __HCI_INTERNAL_H_
+
+#include "ble_compiler.h"
+#include "ble_hal_types.h"
+#include "ble_clock.h"
+#include "ble_link_layer.h"
+#include "ble_hci.h"
+
+#define DEFAULT_TIMEOUT (CLOCK_SECOND/10)
+
+
+/* HCI Packet types */
+#define HCI_COMMAND_PKT		0x01
+#define HCI_ACLDATA_PKT		0x02
+#define HCI_SCODATA_PKT		0x03
+#define HCI_EVENT_PKT		0x04
+#define HCI_VENDOR_PKT		0xff
+
+typedef __packed struct _hci_uart_pckt{
+  uint8_t type;
+  uint8_t data[VARIABLE_SIZE];
+} PACKED hci_uart_pckt;
+#define HCI_HDR_SIZE 1
+
+typedef __packed struct _hci_command_hdr{
+  uint16_t opcode;		/* OCF & OGF */
+  uint8_t  plen;
+} PACKED hci_command_hdr;
+#define HCI_COMMAND_HDR_SIZE 	3
+
+typedef __packed struct _hci_event_pckt{
+  uint8_t evt;
+  uint8_t plen;
+  uint8_t data[VARIABLE_SIZE];
+} PACKED hci_event_pckt;
+#define HCI_EVENT_HDR_SIZE 	2
+
+typedef __packed struct _hci_acl_hdr{
+  uint16_t handle;		/* Handle & Flags(PB, BC) */
+  uint16_t dlen;
+} PACKED hci_acl_hdr;
+#define HCI_ACL_HDR_SIZE 	4
+
+/* Link Control */
+#define OGF_LINK_CTL	        0x01
+
+#define OCF_DISCONNECT          0x0006
+typedef __packed struct _disconnect_cp{
+  uint16_t handle;
+  uint8_t  reason;
+} PACKED disconnect_cp;
+#define DISCONNECT_CP_SIZE      3
+
+/* Host Controller and Baseband */
+#define OGF_HOST_CTL            0x03
+
+#define OCF_SET_EVENT_MASK      0x0001
+#define OCF_RESET               0x0003
+
+#define OCF_READ_TRANSMIT_POWER_LEVEL	0x002D
+typedef __packed struct _read_transmit_power_level_cp{
+  uint16_t handle;
+  uint8_t  type;
+} PACKED read_transmit_power_level_cp;
+#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3
+typedef __packed struct _read_transmit_power_level_rp{
+  uint8_t  status;
+  uint16_t handle;
+  int8_t   level;
+} PACKED read_transmit_power_level_rp;
+#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4
+
+#define OCF_SET_CONTROLLER_TO_HOST_FC   0x0031
+#define OCF_HOST_BUFFER_SIZE            0x0033
+#define OCF_HOST_NUM_COMP_PKTS          0x0035
+
+/* Informational Parameters */
+#define OGF_INFO_PARAM                  0x04
+
+#define OCF_READ_LOCAL_VERSION          0x0001
+typedef __packed struct _read_local_version_rp{
+  uint8_t  status;
+  uint8_t  hci_version;
+  uint16_t hci_revision;
+  uint8_t  lmp_pal_version;
+  uint16_t manufacturer_name;
+  uint16_t lmp_pal_subversion;
+} PACKED read_local_version_rp;
+#define READ_LOCAL_VERSION_RP_SIZE      9
+
+#define OCF_READ_LOCAL_COMMANDS         0x0002
+#define OCF_READ_LOCAL_FEATURES         0x0003
+
+#define OCF_READ_BD_ADDR                0x0009
+typedef __packed struct _read_bd_addr_rp{
+  uint8_t status;
+  tBDAddr bdaddr;
+} PACKED read_bd_addr_rp;
+#define READ_BD_ADDR_RP_SIZE            7
+
+/* Status params */
+#define OGF_STATUS_PARAM                0x05
+
+#define OCF_READ_RSSI                   0x0005
+typedef __packed struct _read_rssi_cp{
+  uint16_t handle;
+} PACKED read_rssi_cp;
+#define READ_RSSI_CP_SIZE               2
+typedef __packed struct _read_rssi_rp{
+  uint8_t  status;
+  uint16_t handle;
+  int8_t   rssi;
+} PACKED read_rssi_rp;
+#define READ_RSSI_RP_SIZE               4
+
+
+/* LE commands */
+#define OGF_LE_CTL                      0x08
+
+#define OCF_LE_SET_EVENT_MASK           0x0001
+typedef __packed struct _le_set_event_mask_cp{
+  uint8_t mask[8];
+} PACKED le_set_event_mask_cp;
+#define LE_SET_EVENT_MASK_CP_SIZE       8
+
+#define OCF_LE_READ_BUFFER_SIZE         0x0002
+typedef __packed struct _le_read_buffer_size_rp{
+  uint8_t  status;
+  uint16_t pkt_len;
+  uint8_t  max_pkt;
+} PACKED le_read_buffer_size_rp;
+#define LE_READ_BUFFER_SIZE_RP_SIZE     4
+
+#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES	0x0003
+typedef __packed struct _le_read_local_supported_features_rp{
+  uint8_t status;
+  uint8_t features[8];
+} PACKED le_read_local_supported_features_rp;
+#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9
+
+#define OCF_LE_SET_RANDOM_ADDRESS		0x0005
+typedef __packed struct _le_set_random_address_cp{
+  tBDAddr bdaddr;
+} PACKED le_set_random_address_cp;
+#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6
+
+#define OCF_LE_SET_ADV_PARAMETERS	0x0006
+typedef __packed struct _le_set_adv_parameters_cp{
+  uint16_t min_interval;
+  uint16_t max_interval;
+  uint8_t  advtype;
+  uint8_t  own_bdaddr_type;
+  uint8_t  direct_bdaddr_type;
+  tBDAddr  direct_bdaddr;
+  uint8_t  chan_map;
+  uint8_t  filter;
+} PACKED le_set_adv_parameters_cp;
+#define LE_SET_ADV_PARAMETERS_CP_SIZE 15
+
+#define OCF_LE_READ_ADV_CHANNEL_TX_POWER	0x0007
+typedef __packed struct _le_read_adv_channel_tx_power_rp{
+  uint8_t status;
+  int8_t  level;
+} PACKED le_read_adv_channel_tx_power_rp;
+#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2
+
+#define OCF_LE_SET_ADV_DATA		0x0008
+typedef __packed struct _le_set_adv_data_cp{
+  uint8_t length;
+  uint8_t data[31];
+} PACKED le_set_adv_data_cp;
+#define LE_SET_ADV_DATA_CP_SIZE 32
+
+#define OCF_LE_SET_SCAN_RESPONSE_DATA		0x0009
+typedef __packed struct _le_set_scan_response_data_cp{
+  uint8_t length;
+  uint8_t data[31];
+} PACKED le_set_scan_response_data_cp;
+#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32
+
+#define OCF_LE_SET_ADVERTISE_ENABLE		0x000A
+typedef __packed struct _le_set_advertise_enable_cp{
+  uint8_t enable;
+} PACKED le_set_advertise_enable_cp;
+#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1
+
+#define OCF_LE_SET_SCAN_PARAMETERS		0x000B
+typedef __packed struct _le_set_scan_parameters_cp{
+  uint8_t  type;
+  uint16_t interval;
+  uint16_t window;
+  uint8_t  own_bdaddr_type;
+  uint8_t  filter;
+} PACKED le_set_scan_parameters_cp;
+#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7
+
+#define OCF_LE_SET_SCAN_ENABLE			0x000C
+typedef __packed struct _le_set_scan_enable_cp{
+  uint8_t enable;
+  uint8_t filter_dup;
+} PACKED le_set_scan_enable_cp;
+#define LE_SET_SCAN_ENABLE_CP_SIZE 2
+
+#define OCF_LE_CREATE_CONN			0x000D
+typedef __packed struct _le_create_connection_cp{
+  uint16_t interval;
+  uint16_t window;
+  uint8_t  initiator_filter;
+  uint8_t  peer_bdaddr_type;
+  tBDAddr  peer_bdaddr;
+  uint8_t  own_bdaddr_type;
+  uint16_t min_interval;
+  uint16_t max_interval;
+  uint16_t latency;
+  uint16_t supervision_timeout;
+  uint16_t min_ce_length;
+  uint16_t max_ce_length;
+} PACKED le_create_connection_cp;
+#define LE_CREATE_CONN_CP_SIZE 25
+
+#define OCF_LE_CREATE_CONN_CANCEL		0x000E
+
+#define OCF_LE_READ_WHITE_LIST_SIZE		0x000F
+typedef __packed struct _le_read_white_list_size_rp{
+  uint8_t status;
+  uint8_t size;
+} PACKED le_read_white_list_size_rp;
+#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2
+
+#define OCF_LE_CLEAR_WHITE_LIST			0x0010
+
+#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST		0x0011
+typedef __packed struct _le_add_device_to_white_list_cp{
+  uint8_t bdaddr_type;
+  tBDAddr bdaddr;
+} PACKED le_add_device_to_white_list_cp;
+#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7
+
+#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST	0x0012
+typedef __packed struct _le_remove_device_from_white_list_cp{
+  uint8_t bdaddr_type;
+  tBDAddr bdaddr;
+} PACKED le_remove_device_from_white_list_cp;
+#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7
+
+#define OCF_LE_CONN_UPDATE			0x0013
+typedef __packed struct _le_connection_update_cp{
+  uint16_t handle;
+  uint16_t min_interval;
+  uint16_t max_interval;
+  uint16_t latency;
+  uint16_t supervision_timeout;
+  uint16_t min_ce_length;
+  uint16_t max_ce_length;
+} PACKED le_connection_update_cp;
+#define LE_CONN_UPDATE_CP_SIZE 14
+
+#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION	0x0014
+typedef __packed struct _le_set_host_channel_classification_cp{
+  uint8_t map[5];
+} PACKED le_set_host_channel_classification_cp;
+#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5
+
+#define OCF_LE_READ_CHANNEL_MAP			0x0015
+typedef __packed struct _le_read_channel_map_cp{
+  uint16_t handle;
+} PACKED le_read_channel_map_cp;
+#define LE_READ_CHANNEL_MAP_CP_SIZE 2
+
+typedef __packed struct _le_read_channel_map_rp{
+  uint8_t  status;
+  uint16_t handle;
+  uint8_t  map[5];
+} PACKED le_read_channel_map_rp;
+#define LE_READ_CHANNEL_MAP_RP_SIZE 8
+
+#define OCF_LE_READ_REMOTE_USED_FEATURES	0x0016
+typedef __packed struct _le_read_remote_used_features_cp{
+  uint16_t handle;
+} PACKED le_read_remote_used_features_cp;
+#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2
+
+#define OCF_LE_ENCRYPT				0x0017
+typedef __packed struct _le_encrypt_cp{
+  uint8_t key[16];
+  uint8_t plaintext[16];
+} PACKED le_encrypt_cp;
+#define LE_ENCRYPT_CP_SIZE 32
+
+typedef __packed struct _le_encrypt_rp{
+  uint8_t status;
+  uint8_t encdata[16];
+} PACKED le_encrypt_rp;
+#define LE_ENCRYPT_RP_SIZE 17
+
+#define OCF_LE_RAND				0x0018
+typedef __packed struct _le_rand_rp{
+  uint8_t status;
+  uint8_t random[8];
+} PACKED le_rand_rp;
+#define LE_RAND_RP_SIZE 9
+
+#define OCF_LE_START_ENCRYPTION			0x0019
+typedef __packed struct _le_start_encryption_cp{
+  uint16_t handle;
+  uint8_t  random[8];
+  uint16_t diversifier;
+  uint8_t  key[16];
+} PACKED le_start_encryption_cp;
+#define LE_START_ENCRYPTION_CP_SIZE 28
+
+#define OCF_LE_LTK_REPLY			0x001A
+typedef __packed struct _le_ltk_reply_cp{
+  uint16_t handle;
+  uint8_t  key[16];
+} PACKED le_ltk_reply_cp;
+#define LE_LTK_REPLY_CP_SIZE 18
+
+typedef __packed struct _le_ltk_reply_rp{
+  uint8_t  status;
+  uint16_t handle;
+} PACKED le_ltk_reply_rp;
+#define LE_LTK_REPLY_RP_SIZE 3
+
+#define OCF_LE_LTK_NEG_REPLY			0x001B
+typedef __packed struct _le_ltk_neg_reply_cp{
+  uint16_t handle;
+} PACKED le_ltk_neg_reply_cp;
+#define LE_LTK_NEG_REPLY_CP_SIZE 2
+
+typedef __packed struct _le_ltk_neg_reply_rp{
+  uint8_t  status;
+  uint16_t handle;
+} PACKED le_ltk_neg_reply_rp;
+#define LE_LTK_NEG_REPLY_RP_SIZE 3
+
+#define OCF_LE_READ_SUPPORTED_STATES		0x001C
+typedef __packed struct _le_read_supported_states_rp{
+  uint8_t status;
+  uint8_t states[8];
+} PACKED le_read_supported_states_rp;
+#define LE_READ_SUPPORTED_STATES_RP_SIZE 9
+
+#define OCF_LE_RECEIVER_TEST			0x001D
+typedef __packed struct _le_receiver_test_cp{
+  uint8_t frequency;
+} PACKED le_receiver_test_cp;
+#define LE_RECEIVER_TEST_CP_SIZE 1
+
+#define OCF_LE_TRANSMITTER_TEST			0x001E
+typedef __packed struct _le_transmitter_test_cp{
+  uint8_t frequency;
+  uint8_t length;
+  uint8_t payload;
+} PACKED le_transmitter_test_cp;
+#define LE_TRANSMITTER_TEST_CP_SIZE 3
+
+#define OCF_LE_TEST_END				0x001F
+typedef __packed struct _le_test_end_rp{
+  uint8_t  status;
+  uint16_t num_pkts;
+} PACKED le_test_end_rp;
+#define LE_TEST_END_RP_SIZE 3
+
+/* Vendor specific commands */
+#define OGF_VENDOR_CMD		0x3f
+
+
+/*------------- Events -------------*/
+#define EVT_CONN_COMPLETE		0x03
+typedef __packed struct _evt_conn_complete{
+  uint8_t  status;
+  uint16_t handle;
+  tBDAddr  bdaddr;
+  uint8_t  link_type;
+  uint8_t  encr_mode;
+} PACKED evt_conn_complete;
+#define EVT_CONN_COMPLETE_SIZE 13
+
+#define EVT_DISCONN_COMPLETE		0x05
+typedef __packed struct _evt_disconn_complete{
+  uint8_t  status;
+  uint16_t handle;
+  uint8_t  reason;
+} PACKED evt_disconn_complete;
+#define EVT_DISCONN_COMPLETE_SIZE 4
+
+#define EVT_ENCRYPT_CHANGE		0x08
+typedef __packed struct _evt_encrypt_change{
+  uint8_t  status;
+  uint16_t handle;
+  uint8_t  encrypt;
+} PACKED evt_encrypt_change;
+#define EVT_ENCRYPT_CHANGE_SIZE 5
+
+#define EVT_READ_REMOTE_VERSION_COMPLETE	0x0C
+
+#define EVT_CMD_COMPLETE 		0x0E
+typedef __packed struct _evt_cmd_complete{
+  uint8_t  ncmd;
+  uint16_t opcode;
+} PACKED evt_cmd_complete;
+#define EVT_CMD_COMPLETE_SIZE 3
+
+#define EVT_CMD_STATUS 			0x0F
+typedef __packed struct _evt_cmd_status{
+  uint8_t  status;
+  uint8_t  ncmd;
+  uint16_t opcode;
+} PACKED evt_cmd_status;
+#define EVT_CMD_STATUS_SIZE 4
+
+#define EVT_HARDWARE_ERROR		0x10
+typedef __packed struct _evt_hardware_error{
+  uint8_t code;
+} PACKED evt_hardware_error;
+#define EVT_HARDWARE_ERROR_SIZE 1
+
+#define EVT_NUM_COMP_PKTS		0x13
+typedef __packed struct _evt_num_comp_pkts{
+  uint8_t num_hndl;
+  /* variable length part */
+} PACKED evt_num_comp_pkts;
+#define EVT_NUM_COMP_PKTS_SIZE 1
+
+/* variable length part of evt_num_comp_pkts. */
+typedef __packed struct _evt_num_comp_pkts_param{
+  uint16_t hndl;
+  uint16_t num_comp_pkts;
+} PACKED evt_num_comp_pkts_param;
+#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1
+
+#define EVT_DATA_BUFFER_OVERFLOW		0x1A
+typedef __packed struct _evt_data_buffer_overflow{
+  uint8_t link_type;
+} PACKED evt_data_buffer_overflow;
+#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1
+
+#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE	0x30
+typedef __packed struct _evt_encryption_key_refresh_complete{
+  uint8_t  status;
+  uint16_t handle;
+} PACKED evt_encryption_key_refresh_complete;
+#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3
+
+#define EVT_LE_META_EVENT	0x3E
+typedef __packed struct _evt_le_meta_event{
+  uint8_t subevent;
+  uint8_t data[VARIABLE_SIZE];
+} PACKED evt_le_meta_event;
+#define EVT_LE_META_EVENT_SIZE 1
+
+#define EVT_LE_CONN_COMPLETE	0x01
+typedef __packed struct _evt_le_connection_complete{
+  uint8_t  status;
+  uint16_t handle;
+  uint8_t  role;
+  uint8_t  peer_bdaddr_type;
+  tBDAddr  peer_bdaddr;
+  uint16_t interval;
+  uint16_t latency;
+  uint16_t supervision_timeout;
+  uint8_t  master_clock_accuracy;
+} PACKED evt_le_connection_complete;
+#define EVT_LE_CONN_COMPLETE_SIZE 18
+
+#define EVT_LE_ADVERTISING_REPORT	0x02
+typedef __packed struct _le_advertising_info{
+  uint8_t evt_type;
+  uint8_t bdaddr_type;
+  tBDAddr bdaddr;
+  uint8_t data_length;
+  uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer).
+} PACKED le_advertising_info;
+#define LE_ADVERTISING_INFO_SIZE 9
+
+#define EVT_LE_CONN_UPDATE_COMPLETE	0x03
+typedef __packed struct _evt_le_connection_update_complete{
+  uint8_t  status;
+  uint16_t handle;
+  uint16_t interval;
+  uint16_t latency;
+  uint16_t supervision_timeout;
+} PACKED evt_le_connection_update_complete;
+#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9
+
+#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE	0x04
+typedef __packed struct _evt_le_read_remote_used_features_complete{
+  uint8_t  status;
+  uint16_t handle;
+  uint8_t  features[8];
+} PACKED evt_le_read_remote_used_features_complete;
+#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11
+
+#define EVT_LE_LTK_REQUEST	0x05
+typedef __packed struct _evt_le_long_term_key_request{
+  uint16_t handle;
+  uint8_t  random[8];
+  uint16_t ediv;
+} PACKED evt_le_long_term_key_request;
+#define EVT_LE_LTK_REQUEST_SIZE 12
+
+/**
+* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR,
+* application can use @ref evt_blue_aci structure to parse the packet.
+*/
+#define EVT_VENDOR	0xFF
+
+
+/* Command opcode pack/unpack */
+#define cmd_opcode_pack(ogf, ocf)	(uint16_t)((ocf & 0x03ff)|(ogf << 10))
+#define cmd_opcode_ogf(op)		(op >> 10)
+#define cmd_opcode_ocf(op)		(op & 0x03ff)
+
+
+
+void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param);
+
+typedef enum {
+  WAITING_TYPE,
+  WAITING_OPCODE1,
+  WAITING_OPCODE2,
+  WAITING_EVENT_CODE,
+  WAITING_HANDLE,
+  WAITING_HANDLE_FLAG,
+  WAITING_PARAM_LEN,
+  WAITING_DATA_LEN1,
+  WAITING_DATA_LEN2,
+  WAITING_PAYLOAD
+}hci_state;
+
+typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len);
+
+/* HCI library functions. */
+
+int hci_send_req(struct hci_request *r, BOOL async);
+
+#endif /* __HCI_INTERNAL_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,170 @@
+/******************** (C) COPYRIGHT 2016 STMicroelectronics ********************
+* File Name          : ble_hci_le.h
+* Author             : AMG RF FW team
+* Version            : V1.1.0
+* Date               : 18-July-2016
+* Description        : Constants and functions for HCI layer. See Bluetooth Core
+*                       v 4.1, Vol. 2, Part E.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLE_HCI_LE_H_
+#define __BLE_HCI_LE_H_
+
+#include "ble_hal_types.h"
+#include "ble_link_layer.h"
+
+/**
+ * @defgroup HCI_Error_codes HCI Error codes
+ * @{
+ */
+#define HCI_UNKNOWN_COMMAND					0x01
+#define HCI_NO_CONNECTION					0x02
+#define HCI_HARDWARE_FAILURE				0x03
+#define HCI_PAGE_TIMEOUT					0x04
+#define HCI_AUTHENTICATION_FAILURE			0x05
+#define HCI_PIN_OR_KEY_MISSING				0x06
+#define HCI_MEMORY_FULL						0x07
+#define HCI_CONNECTION_TIMEOUT				0x08
+#define HCI_MAX_NUMBER_OF_CONNECTIONS		0x09
+#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS	0x0a
+#define HCI_ACL_CONNECTION_EXISTS			0x0b
+#define HCI_COMMAND_DISALLOWED				0x0c
+#define HCI_REJECTED_LIMITED_RESOURCES		0x0d
+#define HCI_REJECTED_SECURITY				0x0e
+#define HCI_REJECTED_PERSONAL				0x0f
+#define HCI_HOST_TIMEOUT					0x10
+#define HCI_UNSUPPORTED_FEATURE				0x11
+#define HCI_INVALID_PARAMETERS				0x12
+#define HCI_OE_USER_ENDED_CONNECTION		0x13
+#define HCI_OE_LOW_RESOURCES				0x14
+#define HCI_OE_POWER_OFF					0x15
+#define HCI_CONNECTION_TERMINATED			0x16
+#define HCI_REPEATED_ATTEMPTS				0x17
+#define HCI_PAIRING_NOT_ALLOWED				0x18
+#define HCI_UNKNOWN_LMP_PDU					0x19
+#define HCI_UNSUPPORTED_REMOTE_FEATURE		0x1a
+#define HCI_SCO_OFFSET_REJECTED				0x1b
+#define HCI_SCO_INTERVAL_REJECTED			0x1c
+#define HCI_AIR_MODE_REJECTED				0x1d
+#define HCI_INVALID_LMP_PARAMETERS			0x1e
+#define HCI_UNSPECIFIED_ERROR				0x1f
+#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE	0x20
+#define HCI_ROLE_CHANGE_NOT_ALLOWED			0x21
+#define HCI_LMP_RESPONSE_TIMEOUT			0x22
+#define HCI_LMP_ERROR_TRANSACTION_COLLISION	0x23
+#define HCI_LMP_PDU_NOT_ALLOWED				0x24
+#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED	0x25
+#define HCI_UNIT_LINK_KEY_USED				0x26
+#define HCI_QOS_NOT_SUPPORTED				0x27
+#define HCI_INSTANT_PASSED					0x28
+#define HCI_PAIRING_NOT_SUPPORTED			0x29
+#define HCI_TRANSACTION_COLLISION			0x2a
+#define HCI_QOS_UNACCEPTABLE_PARAMETER		0x2c
+#define HCI_QOS_REJECTED					0x2d
+#define HCI_CLASSIFICATION_NOT_SUPPORTED	0x2e
+#define HCI_INSUFFICIENT_SECURITY			0x2f
+#define HCI_PARAMETER_OUT_OF_RANGE			0x30
+#define HCI_ROLE_SWITCH_PENDING				0x32
+#define HCI_SLOT_VIOLATION					0x34
+#define HCI_ROLE_SWITCH_FAILED				0x35
+#define HCI_EIR_TOO_LARGE					0x36
+#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED	0x37
+#define HCI_HOST_BUSY_PAIRING				0x38
+#define HCI_CONN_REJ_NO_CH_FOUND			0x39
+#define HCI_CONTROLLER_BUSY					0x3A
+#define HCI_UNACCEPTABLE_CONN_INTERV		0x3B
+#define HCI_DIRECTED_ADV_TIMEOUT			0x3C
+#define HCI_CONN_TERM_MIC_FAIL				0x3D
+#define HCI_CONN_FAIL_TO_BE_ESTABL			0x3E
+#define HCI_MAC_CONN_FAILED					0x3F
+/**
+ * @}
+ */
+
+
+/*
+ * HCI library functions.
+ * Each function returns 0 in case of success, otherwise one of the error codes.
+ */
+
+int hci_reset(void);
+
+int hci_disconnect(uint16_t	handle, uint8_t reason);
+
+int hci_le_set_advertise_enable(uint8_t enable);
+
+int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype,
+		uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map,
+		uint8_t filter);
+
+int hci_le_set_scan_parameters(uint8_t	type, uint16_t interval,
+                               uint16_t window, uint8_t own_bdaddr_type,
+                               uint8_t	filter);
+
+int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup);
+
+int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]);
+
+int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]);
+
+int hci_le_rand(uint8_t random_number[8]);
+
+int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level);
+
+int hci_acl_data(const uint8_t * data, uint16_t len);
+
+int hci_le_set_random_address(tBDAddr bdaddr);
+
+int hci_read_bd_addr(tBDAddr bdaddr);
+
+int hci_le_read_white_list_size(uint8_t *size);
+
+int hci_le_clear_white_list();
+
+int hci_le_add_device_to_white_list(uint8_t	bdaddr_type, tBDAddr bdaddr);
+
+int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr);
+
+int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]);
+
+int hci_le_ltk_request_reply(uint8_t key[16]);
+
+int hci_le_ltk_request_neg_reply();
+
+int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt);
+
+int hci_le_create_connection(uint16_t interval,	uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type,
+                             const tBDAddr peer_bdaddr,	uint8_t	own_bdaddr_type, uint16_t min_interval,	uint16_t max_interval,
+                             uint16_t latency,	uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length);
+
+int hci_le_create_connection_cancel(void);
+
+int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level);
+
+int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi);
+
+int hci_le_read_local_supported_features(uint8_t *features);
+
+int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]);
+
+int hci_le_read_supported_states(uint8_t states[8]);
+
+int hci_le_receiver_test(uint8_t frequency);
+
+int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload);
+
+int hci_le_test_end(uint16_t *num_pkts);
+
+int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, 
+			      uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion);
+
+
+
+#endif /* __BLE_HCI_LE_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,161 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : ble_link_layer.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : Header file for BlueNRG's link layer. It contains
+*                      definition of functions for link layer, most of which are
+*                      mapped to HCI commands.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef _BLE_LINK_LAYER_H
+#define _BLE_LINK_LAYER_H
+
+#include <ble_status.h>
+
+/**
+ *@addtogroup GAP GAP
+ *@brief API for GAP layer.
+ *@{
+ */
+
+/**
+ *@name Advertising filter 
+ *Advertising policy for filtering (white list related) 
+ *@{
+ */
+#define NO_WHITE_LIST_USE           (0x00)  /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */
+#define WHITE_LIST_FOR_ONLY_SCAN    (0x01)  /**< Process connection requests from all devices and only scan requests from devices that are in the White List */
+#define WHITE_LIST_FOR_ONLY_CONN    (0x02)  /**< Process scan requests from all devices and only connection requests from devices that are in the White List */
+#define WHITE_LIST_FOR_ALL          (0x03)  /**< Process scan and connection requests only from devices in the White List. */
+/**
+ * @}
+ */
+
+
+/**
+ * Bluetooth 48 bit address (in little-endian order).
+ */
+typedef	uint8_t	tBDAddr[6];
+
+
+/**
+ *@name Bluetooth address types
+ * Bluetooth address types
+ *@{
+ */
+#define PUBLIC_ADDR                 (0)
+#define RANDOM_ADDR                 (1)
+#define STATIC_RANDOM_ADDR          (1)
+#define RESOLVABLE_PRIVATE_ADDR     (2)
+#define NON_RESOLVABLE_PRIVATE_ADDR (3)
+/**
+ * @}
+ */
+   
+/**
+ *@name Directed advertising types
+ * Type of advertising during directed advertising
+ *@{
+ */
+#define HIGH_DUTY_CYCLE_DIRECTED_ADV   (1)
+#define LOW_DUTY_CYCLE_DIRECTED_ADV    (4)
+/**
+ * @}
+ */
+
+/** 
+ * @name Advertising type
+ * @{
+ */
+
+/**
+ * undirected scannable and connectable 
+ */ 
+#define ADV_IND         (0x00)
+
+/** 
+ * directed non scannable
+ */
+#define ADV_DIRECT_IND  (0x01)
+
+/**
+ * scannable non connectable
+ */
+#define ADV_SCAN_IND    (0x02)
+
+/**
+ * non-connectable and no scan response
+ */
+#define ADV_NONCONN_IND (0x03)
+
+/**
+ * scan response 
+ */
+#define SCAN_RSP        (0x04)
+
+/**
+ * @}
+ */
+
+/* 0X05-0XFF RESERVED */
+
+/**
+ * @name Advertising ranges
+ * @{
+ */
+
+/** 
+ * lowest allowed interval value for connectable types(20ms)..multiple of 625us
+ */
+#define ADV_INTERVAL_LOWEST_CONN    (0X0020)
+
+/** 
+ * highest allowed interval value (10.24s)..multiple of 625us.
+ */
+#define ADV_INTERVAL_HIGHEST        (0X4000)
+
+/** 
+ * lowest allowed interval value for non connectable types
+ * (100ms)..multiple of 625us.
+ */
+#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0)
+
+/**
+ * @}
+ */
+
+/**
+ * @name Advertising channels
+ * @{
+ */
+#define ADV_CH_37 0x01
+#define ADV_CH_38 0x02
+#define ADV_CH_39 0x04
+/**
+ * @}
+ */
+
+/**
+ * @name Scan_types Scan types
+ * @{
+ */
+#define PASSIVE_SCAN    0
+#define ACTIVE_SCAN     1
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#endif /* _BLE_LINK_LAYER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,47 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : ble_list.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : Header file for linked list library.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef _BLE_LIST_H_
+#define _BLE_LIST_H_
+
+typedef struct _tListNode {
+	struct _tListNode * next;
+	struct _tListNode * prev;
+}tListNode, *pListNode;
+
+void list_init_head (tListNode * listHead);
+
+uint8_t list_is_empty (tListNode * listHead);
+
+void list_insert_head (tListNode * listHead, tListNode * node);
+
+void list_insert_tail (tListNode * listHead, tListNode * node);
+
+void list_remove_node (tListNode * node);
+
+void list_remove_head (tListNode * listHead, tListNode ** node );
+
+void list_remove_tail (tListNode * listHead, tListNode ** node );
+
+void list_insert_node_after (tListNode * node, tListNode * ref_node);
+
+void list_insert_node_before (tListNode * node, tListNode * ref_node);
+
+int list_get_size (tListNode * listHead);
+
+void list_get_next_node (tListNode * ref_node, tListNode ** node);
+
+void list_get_prev_node (tListNode * ref_node, tListNode ** node);
+
+#endif /* _BLE_LIST_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,81 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : ble_osal.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : This header file defines the OS abstraction layer used by
+*                      the BLE stack. OSAL defines the set of functions
+*                      which needs to be ported to target operating system and
+*                      target platform.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLE_OSAL_H__
+#define __BLE_OSAL_H__
+
+/******************************************************************************
+ * Includes
+ *****************************************************************************/
+#include <ble_hal_types.h>
+#ifdef __ICCARM__
+#include <intrinsics.h>
+#endif
+
+/******************************************************************************
+ * Macros
+ *****************************************************************************/
+
+
+/******************************************************************************
+ * Function Prototypes
+ *****************************************************************************/
+
+/**
+ * This function copies size number of bytes from a 
+ * memory location pointed by src to a destination 
+ * memory location pointed by dest
+ * 
+ * @param[in] dest Destination address
+ * @param[in] src  Source address
+ * @param[in] size size in the bytes  
+ * 
+ * @return  Address of the destination
+ */
+ 
+extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size);
+
+
+/**
+ * This function sets first number of bytes, specified
+ * by size, to the destination memory pointed by ptr 
+ * to the specified value
+ * 
+ * @param[in] ptr    Destination address
+ * @param[in] value  Value to be set
+ * @param[in] size   Size in the bytes  
+ * 
+ * @return  Address of the destination
+ */
+ 
+extern void* Osal_MemSet(void *ptr, int value, unsigned int size);
+
+/**
+ * Osal_Get_Cur_Time
+ * 
+ * returns the current time in milliseconds
+ */
+/**
+ * Returns the number of ticks (1 tick = 1 millisecond)
+ * 
+ * @return  Time in milliseconds
+ */
+uint32_t Osal_Get_Cur_Time(void);
+
+
+#endif /* __BLE_OSAL_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,158 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : ble_sm.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : Header file for BlueNRG's security manager.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLE_SM_H__
+#define __BLE_SM_H__
+
+/******************************************************************************
+* Macros
+*****************************************************************************/
+
+/**
+ *@addtogroup GAP GAP
+ *@brief API for GAP layer.
+ *@{
+ */
+
+/* IO capabilities */
+/**
+ * @anchor IO_capabilities
+ * @name IO capabilities
+ * @{
+ */
+#define IO_CAP_DISPLAY_ONLY				(0x00)
+#define IO_CAP_DISPLAY_YES_NO			(0x01)
+#define IO_CAP_KEYBOARD_ONLY			(0x02)
+#define IO_CAP_NO_INPUT_NO_OUTPUT		(0x03)
+#define IO_CAP_KEYBOARD_DISPLAY			(0x04)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Auth_req
+ * @name Authentication requirements
+ * @{
+ */
+#define BONDING				            (0x01)
+#define NO_BONDING				        (0x00)
+/**
+ * @}
+ */
+
+/**
+ * @anchor MITM_req
+ * @name MITM protection requirements
+ * @{
+ */
+#define MITM_PROTECTION_NOT_REQUIRED	(0x00)
+#define MITM_PROTECTION_REQUIRED        (0x01)
+/**
+ * @}
+ */
+
+/**
+ * @anchor OOB_Data
+ * @name Out-Of-Band data
+ * @{
+ */
+#define OOB_AUTH_DATA_ABSENT		    (0x00)
+#define OOB_AUTH_DATA_PRESENT      		(0x01)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Author_req
+ * @name Authorization requirements
+ * @{
+ */
+#define AUTHORIZATION_NOT_REQUIRED	     (0x00)
+#define AUTHORIZATION_REQUIRED			 (0x01)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Conn_authorization
+ * @name Connection authorization
+ * @{
+ */
+#define CONNECTION_AUTHORIZED			(0x01)
+#define CONNECTION_REJECTED				(0x02)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Use_fixed_pin
+ * @name Use fixed pin
+ * @{
+ */
+#define USE_FIXED_PIN_FOR_PAIRING		(0x0)
+#define DONOT_USE_FIXED_PIN_FOR_PAIRING	(0x01)
+/**
+ * @}
+ */
+
+/**
+ * @anchor link_security_status
+ * @name Link security status
+ * @{
+ */
+#define SM_LINK_AUTHENTICATED               (0x01)
+#define SM_LINK_AUTHORIZED                  (0x02)
+#define SM_LINK_ENCRYPTED                   (0x04)
+/**
+ * @}
+ */
+
+/**
+ * @anchor SMP_pairing_failed_codes
+ * @name SMP pairing failed reason codes
+ * @{
+ */
+#define PASSKEY_ENTRY_FAILED			(0x01)
+#define OOB_NOT_AVAILABLE				(0x02)
+#define AUTH_REQ_CANNOT_BE_MET			(0x03)
+#define CONFIRM_VALUE_FAILED			(0x04)
+#define PAIRING_NOT_SUPPORTED			(0x05)
+#define INSUFF_ENCRYPTION_KEY_SIZE		(0x06)
+#define CMD_NOT_SUPPORTED				(0x07)
+#define UNSPECIFIED_REASON				(0x08)
+#define VERY_EARLY_NEXT_ATTEMPT			(0x09)
+#define SM_INVALID_PARAMS				(0x0A)
+/**
+ * @}
+ */
+
+/**
+ * @anchor pairing_failed_codes
+ * @name Pairing failed error codes
+ * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event
+ * @{
+ */
+#define SM_PAIRING_SUCCESS              (0x00)
+#define SM_PAIRING_TIMEOUT              (0x01)
+#define SM_PAIRING_FAILED               (0x02)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* __BLE_SM_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,188 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : ble_status.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : Header file with BLE Stack status codes.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef __BLE_STATUS_H__
+#define __BLE_STATUS_H__
+
+#include <ble_hal_types.h>
+
+/** @addtogroup Middlewares
+ *  @{
+ */
+
+/** @defgroup ST
+ *  @{
+ */
+ 
+/** @defgroup SimpleBlueNRG_HCI
+ *  @{
+ */
+
+/** @defgroup ble_status Bluetooth Status/Error Codes
+ * @{
+ */
+ 
+typedef uint8_t tBleStatus; 
+
+/* Error Codes as specified by the specification 
+ * according to the spec the error codes range
+ * from 0x00 to 0x3F 
+ */
+/**
+ * @name Standard error codes
+ * @brief Standard error codes. See Core v 4.1, Vol. 2, part D.
+ * @{
+ */
+#define ERR_CMD_SUCCESS         	                (0x00)
+#define BLE_STATUS_SUCCESS            		        (0x00)
+#define ERR_UNKNOWN_HCI_COMMAND	                    (0x01)
+#define ERR_UNKNOWN_CONN_IDENTIFIER	                (0x02)
+
+#define ERR_AUTH_FAILURE                            (0x05)
+#define ERR_PIN_OR_KEY_MISSING                      (0x06)
+#define ERR_MEM_CAPACITY_EXCEEDED                   (0x07)
+#define ERR_CONNECTION_TIMEOUT                      (0x08)
+
+#define ERR_COMMAND_DISALLOWED				        (0x0C)
+
+#define ERR_UNSUPPORTED_FEATURE				        (0x11)
+#define ERR_INVALID_HCI_CMD_PARAMS                  (0x12)
+#define ERR_RMT_USR_TERM_CONN                       (0x13)
+#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES           (0x14)
+#define ERR_RMT_DEV_TERM_CONN_POWER_OFF             (0x15)
+#define ERR_LOCAL_HOST_TERM_CONN                    (0x16)
+
+#define ERR_UNSUPP_RMT_FEATURE                      (0x1A)
+
+#define ERR_INVALID_LMP_PARAM                       (0x1E)
+#define ERR_UNSPECIFIED_ERROR                       (0x1F)
+
+#define ERR_LL_RESP_TIMEOUT                         (0x22)
+#define ERR_LMP_PDU_NOT_ALLOWED                     (0x24)
+
+#define ERR_INSTANT_PASSED                          (0x28)
+
+#define ERR_PAIR_UNIT_KEY_NOT_SUPP                  (0x29)
+#define ERR_CONTROLLER_BUSY                         (0x3A)
+
+#define ERR_DIRECTED_ADV_TIMEOUT                    (0x3C)
+
+#define ERR_CONN_END_WITH_MIC_FAILURE               (0x3D)
+
+#define ERR_CONN_FAILED_TO_ESTABLISH                (0x3E)
+
+
+/**
+ * @}
+ */
+/**
+ * @name Vendor-specific error codes
+ * @brief Error codes defined by ST related to BlueNRG stack
+ * @{
+ */
+/**
+ * The command cannot be executed due to the current state of the device.
+ */
+#define BLE_STATUS_FAILED             		(0x41)
+/**
+ * Some parameters are invalid.
+ */
+#define BLE_STATUS_INVALID_PARAMS     		(0x42)
+/**
+ * It is not allowed to start the procedure (e.g. another the procedure is ongoing
+ * or cannot be started on the given handle).
+ */
+#define BLE_STATUS_NOT_ALLOWED        		(0x46)
+/**
+ * Unexpected error.
+ */
+#define BLE_STATUS_ERROR              		(0x47)
+#define BLE_STATUS_ADDR_NOT_RESOLVED        (0x48)
+
+#define FLASH_READ_FAILED 					(0x49)
+#define FLASH_WRITE_FAILED 					(0x4A)
+#define FLASH_ERASE_FAILED 					(0x4B)
+
+#define BLE_STATUS_INVALID_CID         		(0x50)
+
+#define TIMER_NOT_VALID_LAYER				(0x54)
+#define TIMER_INSUFFICIENT_RESOURCES		(0x55)
+ 
+#define BLE_STATUS_CSRK_NOT_FOUND			(0x5A)
+#define BLE_STATUS_IRK_NOT_FOUND			(0x5B)
+#define BLE_STATUS_DEV_NOT_FOUND_IN_DB		(0x5C)
+#define BLE_STATUS_SEC_DB_FULL				(0x5D)
+#define BLE_STATUS_DEV_NOT_BONDED           (0x5E)
+#define BLE_STATUS_DEV_IN_BLACKLIST         (0x5F)
+ 
+#define BLE_STATUS_INVALID_HANDLE           (0x60)
+#define BLE_STATUS_INVALID_PARAMETER        (0x61)
+#define BLE_STATUS_OUT_OF_HANDLE            (0x62)
+#define BLE_STATUS_INVALID_OPERATION        (0x63)
+#define BLE_STATUS_INSUFFICIENT_RESOURCES   (0x64)
+#define BLE_INSUFFICIENT_ENC_KEYSIZE		(0x65)
+#define BLE_STATUS_CHARAC_ALREADY_EXISTS    (0x66)
+
+/**
+ * Returned when no valid slots are available (e.g. when there are no available state machines).
+  */
+#define BLE_STATUS_NO_VALID_SLOT                (0x82)
+
+/**
+ * Returned when a scan window shorter than minimum allowed value has been requested (i.e. 2ms)
+ */
+ 
+#define BLE_STATUS_SCAN_WINDOW_SHORT            (0x83)
+/**
+ * Returned when the maximum requested interval to be allocated is shorter then the current
+ * anchor period and a there is no submultiple for the current anchor period that is between
+ * the minimum and the maximum requested intervals.
+ */
+
+#define BLE_STATUS_NEW_INTERVAL_FAILED          (0x84)
+/**
+ * Returned when the maximum requested interval to be allocated is greater than the current anchor
+ * period and there is no multiple of the anchor period that is between the minimum and the maximum
+ * requested intervals.
+ */
+
+#define BLE_STATUS_INTERVAL_TOO_LARGE           (0x85)
+/**
+ * Returned when the current anchor period or a new one can be found that is compatible to the
+ * interval range requested by the new slot but the maximum available length that can be allocated is
+ * less than the minimum requested slot length.
+ */
+ 
+#define BLE_STATUS_LENGTH_FAILED                (0x86)
+/**
+ * @}
+ */
+
+/**
+ * @name Library Error Codes
+ * @brief Error codes defined by ST related to MCU library.
+ * @{
+ */
+#define BLE_STATUS_TIMEOUT                      (0xFF)
+#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED  (0xF0)
+#define BLE_STATUS_NULL_PARAM                   (0xF1) 
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+ 
+#endif /* __BLE_STATUS_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,27 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name          : bluenrg_aci.h
+* Author             : AMS - AAS
+* Version            : V1.0.0
+* Date               : 26-Jun-2014
+* Description        : Header file that includes commands and events for BlueNRG
+*                      FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_ACI_H__
+#define __BLUENRG_ACI_H__
+
+#include "bluenrg_aci_const.h"
+#include "bluenrg_gap_aci.h"
+#include "bluenrg_gatt_aci.h"
+#include "bluenrg_l2cap_aci.h"
+#include "bluenrg_hal_aci.h"
+#include "bluenrg_updater_aci.h"
+
+#endif /* __BLUENRG_ACI_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,813 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name          : bluenrg_aci_const.h
+* Author             : AMS - AAS
+* Version            : V1.0.0
+* Date               : 26-Jun-2014
+* Description        : Header file with ACI definitions for BlueNRG
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_ACI_CONST_H_
+#define __BLUENRG_ACI_CONST_H_
+
+#include "ble_compiler.h"
+#include "ble_link_layer.h"
+#include "ble_hci_const.h"
+#include "bluenrg_gatt_server.h"
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+#define OCF_HAL_GET_FW_BUILD_NUMBER         0x0000
+typedef __packed struct _hal_get_fw_build_number_rp{
+  uint8_t       status;
+  uint16_t      build_number;
+} PACKED hal_get_fw_build_number_rp;
+#define HAL_GET_FW_BUILD_NUMBER_RP_SIZE 3
+#define OCF_HAL_WRITE_CONFIG_DATA   0x000C
+
+#define OCF_HAL_READ_CONFIG_DATA   0x000D
+typedef __packed struct _hal_read_config_data_cp{
+    uint8_t offset;
+} PACKED hal_read_config_data_cp;
+#define HAL_READ_CONFIG_DATA_RP_SIZE 1
+typedef __packed struct _hal_read_config_data_rp{
+    uint8_t status;
+    uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE];
+} PACKED hal_read_config_data_rp;
+
+#define OCF_HAL_SET_TX_POWER_LEVEL          0x000F
+typedef __packed struct _hal_set_tx_power_level_cp{
+	uint8_t	en_high_power;
+    uint8_t pa_level;
+} PACKED hal_set_tx_power_level_cp;
+#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2
+
+#define OCF_HAL_DEVICE_STANDBY          0x0013
+
+#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER    0x0014
+typedef __packed struct _hal_le_tx_test_packet_number_rp{
+  uint8_t status;
+  uint32_t number_of_packets;
+} PACKED hal_le_tx_test_packet_number_rp;
+
+#define OCF_HAL_TONE_START                  0x0015
+typedef __packed struct _hal_tone_start_cp{
+	uint8_t	rf_channel;
+} PACKED hal_tone_start_cp;
+#define HAL_TONE_START_CP_SIZE 1
+
+#define OCF_HAL_TONE_STOP                   0x0016
+#define OCF_HAL_GET_LINK_STATUS             0x0017
+typedef __packed struct _hal_get_link_status_rp{
+  uint8_t       status;
+  uint8_t       link_status[8];
+  uint16_t      conn_handle[8];
+} PACKED hal_get_link_status_rp;
+
+#define OCF_HAL_GET_ANCHOR_PERIOD           0x0019
+typedef __packed struct _hal_get_anchor_period_rp{
+  uint8_t  status;
+  uint32_t anchor_period;
+  uint32_t max_free_slot;
+} PACKED hal_get_anchor_period_rp;
+
+#define OCF_UPDATER_START                   0x0020
+#define OCF_UPDATER_REBOOT                  0x0021
+
+#define OCF_GET_UPDATER_VERSION                 0x0022
+typedef __packed struct _get_updater_version_rp{
+    uint8_t		    status;
+	uint8_t		    version;
+} PACKED get_updater_version_rp;
+#define GET_UPDATER_VERSION_RP_SIZE 2
+
+#define OCF_GET_UPDATER_BUFSIZE             0x0023
+typedef __packed struct _get_updater_bufsize_rp{
+    uint8_t		    status;
+	uint8_t		    buffer_size;
+} PACKED get_updater_bufsize_rp;
+#define GET_UPDATER_BUFSIZE_RP_SIZE 2
+
+#define OCF_UPDATER_ERASE_BLUE_FLAG         0x0024
+
+#define OCF_UPDATER_RESET_BLUE_FLAG         0x0025
+
+#define OCF_UPDATER_ERASE_SECTOR            0x0026
+typedef __packed struct _updater_erase_sector_cp{
+	uint32_t	address;
+} PACKED updater_erase_sector_cp;
+#define UPDATER_ERASE_SECTOR_CP_SIZE 4
+
+#define OCF_UPDATER_PROG_DATA_BLOCK         0x0027
+#define UPDATER_PROG_DATA_BLOCK_CP_SIZE     6
+typedef __packed struct _updater_prog_data_block_cp{
+	uint32_t	address;
+    uint16_t    data_len;
+    uint8_t		data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE];
+} PACKED updater_prog_data_block_cp;
+
+#define OCF_UPDATER_READ_DATA_BLOCK         0x0028
+typedef __packed struct _updater_read_data_block_cp{
+	uint32_t	address;
+    uint16_t    data_len;
+} PACKED updater_read_data_block_cp;
+#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6
+typedef __packed struct _updater_read_data_block_rp{
+    uint8_t		    status;
+	uint8_t		    data[VARIABLE_SIZE];
+} PACKED updater_read_data_block_rp;
+#define GET_UPDATER_BUFSIZE_RP_SIZE 2
+
+#define OCF_UPDATER_CALC_CRC                0x0029
+typedef __packed struct _updater_calc_crc_cp{
+	uint32_t	address;
+    uint8_t    num_sectors;
+} PACKED updater_calc_crc_cp;
+#define UPDATER_CALC_CRC_CP_SIZE 5
+typedef __packed struct _updater_calc_crc_rp{
+    uint8_t		    status;
+	uint32_t		crc;
+} PACKED updater_calc_crc_rp;
+#define UPDATER_CALC_CRC_RP_SIZE 5
+
+#define OCF_UPDATER_HW_VERSION              0x002A
+typedef __packed struct _updater_hw_version_rp{
+    uint8_t		    status;
+	uint8_t		    version;
+} PACKED updater_hw_version_rp;
+#define UPDATER_HW_VERSION_RP_SIZE 2
+
+#define OCF_GAP_SET_NON_DISCOVERABLE	    0x0081
+
+#define OCF_GAP_SET_LIMITED_DISCOVERABLE	0x0082
+
+#define OCF_GAP_SET_DISCOVERABLE	        0x0083
+
+#define OCF_GAP_SET_DIRECT_CONNECTABLE      0x0084
+typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{
+    uint8_t		own_bdaddr_type;
+    uint8_t		directed_adv_type;
+    uint8_t		direct_bdaddr_type;
+    tBDAddr		direct_bdaddr;
+    uint16_t            adv_interv_min;
+    uint16_t            adv_interv_max;
+} PACKED gap_set_direct_conectable_cp_IDB05A1;
+
+typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{
+    uint8_t		own_bdaddr_type;
+    uint8_t		direct_bdaddr_type;
+    tBDAddr		direct_bdaddr;
+} PACKED gap_set_direct_conectable_cp_IDB04A1;
+#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8
+
+#define OCF_GAP_SET_IO_CAPABILITY      0x0085
+typedef __packed struct _gap_set_io_capability_cp{
+    uint8_t		io_capability;
+} PACKED gap_set_io_capability_cp;
+#define GAP_SET_IO_CAPABILITY_CP_SIZE 1
+
+#define OCF_GAP_SET_AUTH_REQUIREMENT      0x0086
+typedef __packed struct _gap_set_auth_requirement_cp{
+    uint8_t	mitm_mode;
+    uint8_t     oob_enable;
+    uint8_t     oob_data[16];
+    uint8_t     min_encryption_key_size;
+    uint8_t     max_encryption_key_size;
+    uint8_t     use_fixed_pin;
+    uint32_t    fixed_pin;
+    uint8_t     bonding_mode;
+} PACKED gap_set_auth_requirement_cp;
+#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26
+
+#define OCF_GAP_SET_AUTHOR_REQUIREMENT      0x0087
+typedef __packed struct _gap_set_author_requirement_cp{
+  uint16_t      conn_handle;
+  uint8_t       authorization_enable;
+} PACKED gap_set_author_requirement_cp;
+#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3
+
+#define OCF_GAP_PASSKEY_RESPONSE      0x0088
+typedef __packed struct _gap_passkey_response_cp{
+  uint16_t conn_handle;
+  uint32_t passkey;
+} PACKED gap_passkey_response_cp;
+#define GAP_PASSKEY_RESPONSE_CP_SIZE 6
+
+#define OCF_GAP_AUTHORIZATION_RESPONSE      0x0089
+typedef __packed struct _gap_authorization_response_cp{
+  uint16_t conn_handle;
+  uint8_t  authorize;
+} PACKED gap_authorization_response_cp;
+#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3
+
+#define OCF_GAP_INIT		        0x008A
+typedef __packed struct _gap_init_cp_IDB05A1{
+    uint8_t	role;
+    uint8_t	privacy_enabled;
+    uint8_t device_name_char_len; 
+} PACKED gap_init_cp_IDB05A1;
+#define GAP_INIT_CP_SIZE_IDB05A1 3
+
+typedef __packed struct _gap_init_cp_IDB04A1{
+	uint8_t	role;
+} PACKED gap_init_cp_IDB04A1;
+#define GAP_INIT_CP_SIZE_IDB04A1 1
+typedef __packed struct _gap_init_rp{
+    uint8_t		    status;
+	uint16_t		service_handle;
+    uint16_t		dev_name_char_handle;
+    uint16_t		appearance_char_handle;
+} PACKED gap_init_rp;
+#define GAP_INIT_RP_SIZE 7
+
+#define OCF_GAP_SET_NON_CONNECTABLE      0x008B
+typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{
+    uint8_t	advertising_event_type;
+    uint8_t	own_address_type;
+#endif
+} PACKED gap_set_non_connectable_cp_IDB05A1;
+
+typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{
+    uint8_t	advertising_event_type;
+} PACKED gap_set_non_connectable_cp_IDB04A1;
+
+#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE      0x008C
+typedef __packed struct _gap_set_undirected_connectable_cp{
+    uint8_t	adv_filter_policy;
+    uint8_t	own_addr_type;
+} PACKED gap_set_undirected_connectable_cp;
+#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2
+
+#define OCF_GAP_SLAVE_SECURITY_REQUEST      0x008D
+typedef __packed struct _gap_slave_security_request_cp{
+  uint16_t conn_handle;
+  uint8_t  bonding;
+  uint8_t  mitm_protection;
+} PACKED gap_slave_security_request_cp;
+#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4
+
+#define OCF_GAP_UPDATE_ADV_DATA      0x008E
+
+#define OCF_GAP_DELETE_AD_TYPE      0x008F
+typedef __packed struct _gap_delete_ad_type_cp{
+    uint8_t	ad_type;
+} PACKED gap_delete_ad_type_cp;
+#define GAP_DELETE_AD_TYPE_CP_SIZE 1
+
+#define OCF_GAP_GET_SECURITY_LEVEL      0x0090
+typedef __packed struct _gap_get_security_level_rp{
+    uint8_t		    status;
+	uint8_t		    mitm_protection;
+    uint8_t		    bonding;
+    uint8_t		    oob_data;
+    uint8_t         passkey_required;
+} PACKED gap_get_security_level_rp;
+#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5
+
+#define OCF_GAP_SET_EVT_MASK      0x0091
+typedef __packed struct _gap_set_evt_mask_cp{
+    uint16_t	evt_mask;
+} PACKED gap_set_evt_mask_cp;
+#define GAP_SET_EVT_MASK_CP_SIZE 2
+
+#define OCF_GAP_CONFIGURE_WHITELIST   0x0092
+
+#define OCF_GAP_TERMINATE      0x0093
+typedef __packed struct _gap_terminate_cp{
+  uint16_t handle;
+  uint8_t  reason;
+} PACKED gap_terminate_cp;
+#define GAP_TERMINATE_CP_SIZE 3
+
+#define OCF_GAP_CLEAR_SECURITY_DB   0x0094
+
+#define OCF_GAP_ALLOW_REBOND_DB     0x0095
+
+typedef __packed struct _gap_allow_rebond_cp_IDB05A1{
+  uint16_t conn_handle;
+} PACKED gap_allow_rebond_cp_IDB05A1;
+
+#define OCF_GAP_START_LIMITED_DISCOVERY_PROC   0x0096
+typedef __packed struct _gap_start_limited_discovery_proc_cp{
+  uint16_t scanInterval;
+  uint16_t scanWindow;
+  uint8_t  own_address_type;
+  uint8_t  filterDuplicates;
+} PACKED gap_start_limited_discovery_proc_cp;
+#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6
+
+#define OCF_GAP_START_GENERAL_DISCOVERY_PROC   0x0097
+typedef __packed struct _gap_start_general_discovery_proc_cp{
+  uint16_t scanInterval;
+  uint16_t scanWindow;
+  uint8_t  own_address_type;
+  uint8_t  filterDuplicates;
+} PACKED gap_start_general_discovery_proc_cp;
+#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6
+
+#define OCF_GAP_START_NAME_DISCOVERY_PROC   0x0098
+typedef __packed struct _gap_start_name_discovery_proc_cp{
+  uint16_t scanInterval;
+  uint16_t scanWindow;
+  uint8_t peer_bdaddr_type;
+  tBDAddr peer_bdaddr;
+  uint8_t own_bdaddr_type;
+  uint16_t conn_min_interval;
+  uint16_t conn_max_interval;
+  uint16_t conn_latency;
+  uint16_t supervision_timeout;
+  uint16_t min_conn_length;
+  uint16_t max_conn_length;
+} PACKED gap_start_name_discovery_proc_cp;
+#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24
+
+#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC  0x0099
+
+#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC  0x009A
+typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{
+  uint8_t  scan_type;
+  uint16_t scan_interval;
+  uint16_t scan_window;
+  uint8_t  own_address_type;
+  uint8_t  filter_duplicates;
+} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1;
+
+typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{
+  uint8_t  scan_type;
+  uint16_t scan_interval;
+  uint16_t scan_window;
+  uint8_t  own_address_type;
+  uint8_t  filter_duplicates;
+  uint8_t  use_reconn_addr;
+  tBDAddr  reconn_addr;
+} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1;
+
+#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC  0x009B
+#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8
+typedef __packed struct _gap_start_selective_conn_establish_proc_cp{
+  uint8_t scan_type;
+  uint16_t scan_interval;
+  uint16_t scan_window;
+  uint8_t own_address_type;
+  uint8_t filter_duplicates;
+  uint8_t num_whitelist_entries;
+  uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE];
+} PACKED gap_start_selective_conn_establish_proc_cp;
+
+#define OCF_GAP_CREATE_CONNECTION      0x009C
+typedef __packed struct _gap_create_connection_cp{
+  uint16_t scanInterval;
+  uint16_t scanWindow;
+  uint8_t peer_bdaddr_type;
+  tBDAddr peer_bdaddr;
+  uint8_t own_bdaddr_type;
+  uint16_t conn_min_interval;
+  uint16_t conn_max_interval;
+  uint16_t conn_latency;
+  uint16_t supervision_timeout;
+  uint16_t min_conn_length;
+  uint16_t max_conn_length;
+} PACKED gap_create_connection_cp;
+#define GAP_CREATE_CONNECTION_CP_SIZE 24
+
+#define OCF_GAP_TERMINATE_GAP_PROCEDURE      0x009D
+
+#define OCF_GAP_START_CONNECTION_UPDATE      0x009E
+typedef __packed struct _gap_start_connection_update_cp{
+  uint16_t conn_handle;
+  uint16_t conn_min_interval;
+  uint16_t conn_max_interval;
+  uint16_t conn_latency;
+  uint16_t supervision_timeout;
+  uint16_t min_conn_length;
+  uint16_t max_conn_length;
+} PACKED gap_start_connection_update_cp;
+#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14
+
+#define OCF_GAP_SEND_PAIRING_REQUEST      0x009F
+typedef __packed struct _gap_send_pairing_request_cp{
+  uint16_t conn_handle;
+  uint8_t  force_rebond;
+} PACKED gap_send_pairing_request_cp;
+#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3
+
+#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS   0x00A0
+typedef __packed struct _gap_resolve_private_address_cp{
+  tBDAddr address;
+} PACKED gap_resolve_private_address_cp;
+#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6
+typedef __packed struct _gap_resolve_private_address_rp{
+  uint8_t status;
+  tBDAddr address;
+} PACKED gap_resolve_private_address_rp;
+  
+#define OCF_GAP_SET_BROADCAST_MODE   0x00A1
+#define GAP_SET_BROADCAST_MODE_CP_SIZE 6
+typedef __packed struct _gap_set_broadcast_mode_cp{
+  uint16_t adv_interv_min;
+  uint16_t adv_interv_max;
+  uint8_t adv_type;
+  uint8_t own_addr_type;
+  uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE];
+} PACKED gap_set_broadcast_mode_cp;
+
+#define OCF_GAP_START_OBSERVATION_PROC   0x00A2
+typedef __packed struct _gap_start_observation_proc_cp{
+  uint16_t scan_interval;
+  uint16_t scan_window;
+  uint8_t  scan_type;
+  uint8_t  own_address_type;
+  uint8_t  filter_duplicates;
+} PACKED gap_start_observation_proc_cp;
+
+#define OCF_GAP_GET_BONDED_DEVICES   0x00A3
+typedef __packed struct _gap_get_bonded_devices_rp{
+    uint8_t		status;
+    uint8_t		num_addr;
+	uint8_t		dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1];
+} PACKED gap_get_bonded_devices_rp;
+
+#define OCF_GAP_IS_DEVICE_BONDED   0x00A4
+typedef __packed struct _gap_is_device_bonded_cp{
+  uint8_t peer_address_type;
+  tBDAddr peer_address;
+} PACKED gap_is_device_bonded_cp;
+
+
+#define OCF_GATT_INIT		        0x0101
+
+#define OCF_GATT_ADD_SERV		    0x0102
+typedef __packed struct _gatt_add_serv_rp{
+    uint8_t		    status;
+	uint16_t		handle;
+} PACKED gatt_add_serv_rp;
+#define GATT_ADD_SERV_RP_SIZE 3
+
+#define OCF_GATT_INCLUDE_SERV		0x0103
+typedef __packed struct _gatt_include_serv_rp{
+	uint8_t		    status;
+    uint16_t		handle;    
+} PACKED gatt_include_serv_rp;
+#define GATT_INCLUDE_SERV_RP_SIZE 3
+
+#define OCF_GATT_ADD_CHAR		    0x0104
+typedef __packed struct _gatt_add_char_rp{
+    uint8_t		    status;
+	uint16_t		handle;
+} PACKED gatt_add_char_rp;
+#define GATT_ADD_CHAR_RP_SIZE 3
+
+#define OCF_GATT_ADD_CHAR_DESC	    0x0105
+typedef __packed struct _gatt_add_char_desc_rp{
+    uint8_t		    status;
+	uint16_t		handle;
+} PACKED gatt_add_char_desc_rp;
+#define GATT_ADD_CHAR_DESC_RP_SIZE 3
+
+#define OCF_GATT_UPD_CHAR_VAL		0x0106
+
+#define OCF_GATT_DEL_CHAR   		0x0107
+typedef __packed struct _gatt_del_char_cp{
+	uint16_t	service_handle;
+	uint16_t	char_handle;
+} PACKED gatt_del_char_cp;
+#define GATT_DEL_CHAR_CP_SIZE 4
+
+#define OCF_GATT_DEL_SERV   		0x0108
+typedef __packed struct _gatt_del_serv_cp{
+	uint16_t	service_handle;
+} PACKED gatt_del_serv_cp;
+#define GATT_DEL_SERV_CP_SIZE 2
+
+#define OCF_GATT_DEL_INC_SERV   	0x0109
+typedef __packed struct _gatt_del_inc_serv_cp{
+	uint16_t	service_handle;
+    uint16_t	inc_serv_handle;
+} PACKED gatt_del_inc_serv_cp;
+#define GATT_DEL_INC_SERV_CP_SIZE 4
+
+#define OCF_GATT_SET_EVT_MASK      0x010A
+typedef __packed struct _gatt_set_evt_mask_cp{
+    uint32_t	evt_mask;
+} PACKED gatt_set_evt_mask_cp;
+#define GATT_SET_EVT_MASK_CP_SIZE 4
+
+#define OCF_GATT_EXCHANGE_CONFIG      0x010B
+typedef __packed struct _gatt_exchange_config_cp{
+    uint16_t	conn_handle;
+} PACKED gatt_exchange_config_cp;
+#define GATT_EXCHANGE_CONFIG_CP_SIZE 2
+
+#define OCF_ATT_FIND_INFO_REQ      0x010C
+typedef __packed struct _att_find_info_req_cp{
+    uint16_t	conn_handle;
+    uint16_t	start_handle;
+    uint16_t	end_handle;
+} PACKED att_find_info_req_cp;
+#define ATT_FIND_INFO_REQ_CP_SIZE 6
+
+#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ  0x010D
+#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9
+typedef __packed struct _att_find_by_type_value_req_cp{
+    uint16_t	conn_handle;
+    uint16_t	start_handle;
+    uint16_t	end_handle;
+    uint8_t     uuid[2];
+    uint8_t     attr_val_len;
+    uint8_t     attr_val[ATT_MTU - 7];
+} PACKED att_find_by_type_value_req_cp;
+
+#define OCF_ATT_READ_BY_TYPE_REQ  0x010E
+#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7  // without UUID
+typedef __packed struct _att_read_by_type_req_cp{
+    uint16_t	conn_handle;
+    uint16_t	start_handle;
+    uint16_t	end_handle;
+    uint8_t     uuid_type;
+    uint8_t     uuid[16];
+} PACKED att_read_by_type_req_cp;
+
+#define OCF_ATT_READ_BY_GROUP_TYPE_REQ  0x010F
+#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7  // without UUID
+typedef __packed struct _att_read_by_group_type_req_cp{
+    uint16_t	conn_handle;
+    uint16_t	start_handle;
+    uint16_t	end_handle;
+    uint8_t     uuid_type;
+    uint8_t     uuid[16];
+} PACKED att_read_by_group_type_req_cp;
+
+#define OCF_ATT_PREPARE_WRITE_REQ  0x0110
+#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7  // without attr_val
+typedef __packed struct _att_prepare_write_req_cp{
+    uint16_t	conn_handle;
+    uint16_t	attr_handle;
+    uint16_t	value_offset;
+    uint8_t     attr_val_len;
+    uint8_t     attr_val[ATT_MTU-5];
+} PACKED att_prepare_write_req_cp;
+
+#define OCF_ATT_EXECUTE_WRITE_REQ  0x0111
+typedef __packed struct _att_execute_write_req_cp{
+    uint16_t	conn_handle;
+    uint8_t     execute;
+} PACKED att_execute_write_req_cp;
+#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3
+
+#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112
+typedef __packed struct _gatt_disc_all_prim_serivces_cp{
+  uint16_t conn_handle;
+} PACKED gatt_disc_all_prim_services_cp;
+#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2
+
+#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113
+typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{
+  uint16_t    conn_handle;
+  uint8_t     uuid_type;
+  uint8_t     uuid[16];
+} PACKED gatt_disc_prim_service_by_uuid_cp;
+#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid
+
+#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114
+typedef __packed struct _gatt_disc_find_included_services_cp{
+  uint16_t conn_handle;
+  uint16_t start_handle;
+  uint16_t end_handle;
+} PACKED gatt_find_included_services_cp;
+#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6
+
+#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115
+typedef __packed struct _gatt_disc_all_charac_of_serv_cp{
+  uint16_t conn_handle;
+  uint16_t start_attr_handle;
+  uint16_t end_attr_handle;
+} PACKED gatt_disc_all_charac_of_serv_cp;
+#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6
+
+#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116
+
+#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117
+typedef __packed struct _gatt_disc_all_charac_descriptors_cp{
+  uint16_t conn_handle;
+  uint16_t char_val_handle;
+  uint16_t char_end_handle;
+} PACKED gatt_disc_all_charac_descriptors_cp;
+#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6
+
+#define OCF_GATT_READ_CHARAC_VAL   0x0118
+typedef __packed struct _gatt_read_charac_val_cp{
+  uint16_t conn_handle;
+  uint16_t attr_handle;
+} PACKED gatt_read_charac_val_cp;
+#define GATT_READ_CHARAC_VAL_CP_SIZE 4
+
+#define OCF_GATT_READ_USING_CHARAC_UUID  0x0109
+typedef __packed struct _gatt_read_using_charac_uuid_cp{
+    uint16_t	conn_handle;
+    uint16_t	start_handle;
+    uint16_t	end_handle;
+    uint8_t     uuid_type;
+    uint8_t     uuid[16];
+} PACKED gatt_read_using_charac_uuid_cp;
+#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7  // without UUID
+
+#define OCF_GATT_READ_LONG_CHARAC_VAL   0x011A
+typedef __packed struct _gatt_read_long_charac_val_cp{
+  uint16_t conn_handle;
+  uint16_t attr_handle;
+  uint16_t val_offset;
+} PACKED gatt_read_long_charac_val_cp;
+#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6
+
+#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL   0x011B
+#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3  // without set_of_handles
+typedef __packed struct _gatt_read_multiple_charac_val_cp{
+  uint16_t conn_handle;
+  uint8_t num_handles;
+  uint8_t  set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE];
+} PACKED gatt_read_multiple_charac_val_cp;
+
+#define OCF_GATT_WRITE_CHAR_VALUE   0x011C
+
+#define OCF_GATT_WRITE_LONG_CHARAC_VAL   0x011D
+#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7  // without set_of_handles
+typedef __packed struct _gatt_write_long_charac_val_cp{
+  uint16_t conn_handle;
+  uint16_t attr_handle;
+  uint16_t val_offset;
+  uint8_t  val_len;
+  uint8_t  attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE];
+} PACKED gatt_write_long_charac_val_cp;
+
+#define OCF_GATT_WRITE_CHARAC_RELIABLE   0x011E
+#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7  // without set_of_handles
+typedef __packed struct _gatt_write_charac_reliable_cp{
+  uint16_t conn_handle;
+  uint16_t attr_handle;
+  uint16_t val_offset;
+  uint8_t  val_len;
+  uint8_t  attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE];
+} PACKED gatt_write_charac_reliable_cp;
+
+#define OCF_GATT_WRITE_LONG_CHARAC_DESC   0x011F
+#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7  // without set_of_handles
+typedef __packed struct _gatt_write_long_charac_desc_cp{
+  uint16_t conn_handle;
+  uint16_t attr_handle;
+  uint16_t val_offset;
+  uint8_t  val_len;
+  uint8_t  attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE];
+} PACKED gatt_write_long_charac_desc_cp;
+
+#define OCF_GATT_READ_LONG_CHARAC_DESC   0x0120
+typedef __packed struct _gatt_read_long_charac_desc_cp{
+  uint16_t conn_handle;
+  uint16_t attr_handle;
+  uint16_t val_offset;
+} PACKED gatt_read_long_charac_desc_cp;
+#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6
+
+#define OCF_GATT_WRITE_CHAR_DESCRIPTOR      0x0121
+
+#define OCF_GATT_READ_CHAR_DESCRIPTOR       0x0122
+typedef __packed struct _gatt_read_charac_desc_cp{
+  uint16_t conn_handle;
+  uint16_t attr_handle;
+} PACKED gatt_read_charac_desc_cp;
+#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4
+
+#define OCF_GATT_WRITE_WITHOUT_RESPONSE     0x0123
+#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5  // without attr_val
+typedef __packed struct _gatt_write_without_resp_cp{
+  uint16_t conn_handle;
+  uint16_t attr_handle;
+  uint8_t  val_len;
+  uint8_t  attr_val[ATT_MTU - 3];
+} PACKED gatt_write_without_resp_cp;
+
+#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE     0x0124
+#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5  // without attr_val
+typedef __packed struct _gatt_signed_write_without_resp_cp{
+  uint16_t conn_handle;
+  uint16_t attr_handle;
+  uint8_t  val_len;
+  uint8_t  attr_val[ATT_MTU - 13];
+} PACKED gatt_signed_write_without_resp_cp;
+
+#define OCF_GATT_CONFIRM_INDICATION                0x0125
+typedef __packed struct _gatt_confirm_indication_cp{
+	uint16_t	conn_handle;
+} PACKED gatt_confirm_indication_cp;
+#define GATT_CONFIRM_INDICATION_CP_SIZE 2
+
+#define OCF_GATT_WRITE_RESPONSE                    0x0126
+
+#define OCF_GATT_ALLOW_READ		    0x0127
+typedef __packed struct _gatt_allow_read_cp{
+	uint16_t	conn_handle;
+} PACKED gatt_allow_read_cp;
+#define GATT_ALLOW_READ_CP_SIZE 2
+
+#define OCF_GATT_SET_SECURITY_PERMISSION		    0x0128
+typedef __packed struct _gatt_set_security_permission_cp{
+	uint16_t	service_handle;
+    uint16_t	attr_handle;
+    uint8_t	    security_permission;
+} PACKED gatt_set_security_permission_cp;
+#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5
+
+#define OCF_GATT_SET_DESC_VAL		0x0129
+
+#define OCF_GATT_READ_HANDLE_VALUE      0x012A
+typedef __packed struct _gatt_read_handle_val_cp{
+	uint16_t	attr_handle;
+} PACKED gatt_read_handle_val_cp;
+#define GATT_READ_HANDLE_VALUE_RP_SIZE 3
+typedef __packed struct _gatt_read_handle_val_rp{
+    uint8_t		status;
+    uint16_t	value_len;
+	uint8_t		value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE];
+} PACKED gatt_read_handle_val_rp;
+
+#define OCF_GATT_READ_HANDLE_VALUE_OFFSET      0x012B
+typedef __packed struct _gatt_read_handle_val_offset_cp{
+	uint16_t	attr_handle;
+    uint8_t     offset;
+} PACKED gatt_read_handle_val_offset_cp;
+#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2
+typedef __packed struct _gatt_read_handle_val_offset_rp{
+    uint8_t		status;
+    uint8_t		value_len;
+	uint8_t		value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE];
+} PACKED gatt_read_handle_val_offset_rp;
+
+#define OCF_GATT_UPD_CHAR_VAL_EXT		        0x012C
+#define GATT_UPD_CHAR_VAL_EXT_CP_SIZE 10  // without value
+typedef __packed struct _gatt_upd_char_val_ext_cp{
+  uint16_t service_handle;
+  uint16_t char_handle;
+  uint8_t  update_type;
+  uint16_t char_length;
+  uint16_t value_offset;
+  uint8_t  value_length;
+  uint8_t  value[HCI_MAX_PAYLOAD_SIZE-GATT_UPD_CHAR_VAL_EXT_CP_SIZE];
+} PACKED gatt_upd_char_val_ext_cp;
+
+#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ  0x0181
+typedef __packed struct _l2cap_conn_param_update_req_cp{
+  uint16_t conn_handle;
+  uint16_t interval_min;
+  uint16_t interval_max;
+  uint16_t slave_latency;
+  uint16_t timeout_multiplier;
+} PACKED l2cap_conn_param_update_req_cp;
+#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10
+
+#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP  0x0182
+typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{
+  uint16_t conn_handle;
+  uint16_t interval_min;
+  uint16_t interval_max;
+  uint16_t slave_latency;
+  uint16_t timeout_multiplier;
+  uint16_t min_ce_length;
+  uint16_t max_ce_length;
+  uint8_t id;
+  uint8_t accept;
+} PACKED l2cap_conn_param_update_resp_cp_IDB05A1;
+
+typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{
+  uint16_t conn_handle;
+  uint16_t interval_min;
+  uint16_t interval_max;
+  uint16_t slave_latency;
+  uint16_t timeout_multiplier;
+  uint8_t id;
+  uint8_t accept;
+} PACKED l2cap_conn_param_update_resp_cp_IDB04A1;
+
+/**
+ * @defgroup BlueNRG_Events BlueNRG events (vendor specific)
+ * @{
+ */
+
+/**
+ * Vendor specific event for BlueNRG.
+ */
+typedef __packed struct _evt_blue_aci{
+  uint16_t ecode; /**< One of the BlueNRG event codes. */
+  uint8_t  data[VARIABLE_SIZE];
+} PACKED evt_blue_aci;
+
+
+/**
+ * @}
+ */
+
+#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,230 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : bluenrg_gap.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : Header file for BlueNRG's GAP layer. 
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef __BNRG_GAP_H__
+#define __BNRG_GAP_H__
+
+#include <ble_link_layer.h>
+
+/**
+ *@addtogroup GAP GAP
+ *@brief API for GAP layer.
+ *@{
+ */
+
+/**
+ * @name GAP UUIDs
+ * @{
+ */
+#define GAP_SERVICE_UUID                        (0x1800)
+#define DEVICE_NAME_UUID						(0x2A00)
+#define APPEARANCE_UUID							(0x2A01)
+#define PERIPHERAL_PRIVACY_FLAG_UUID			(0x2A02)
+#define RECONNECTION_ADDR_UUID					(0x2A03)
+#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID	(0x2A04)
+/**
+ * @}
+ */
+
+/**
+ * @name Characteristic value lengths
+ * @{
+ */
+#define DEVICE_NAME_CHARACTERISTIC_LEN			        (8)
+#define APPEARANCE_CHARACTERISTIC_LEN			        (2)
+#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN	        (1)
+#define RECONNECTION_ADDR_CHARACTERISTIC_LEN			(6)
+#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN	(8)
+/**
+ * @}
+ */
+
+/*------------- AD types for adv data and scan response data ----------------*/
+
+/**
+ * @defgroup AD_Types AD Types
+ * @brief AD Types
+ * @{
+ */
+
+/* FLAGS AD type */
+#define AD_TYPE_FLAGS							(0x01)
+/* flag bits */
+/**
+ * @anchor Flags_AD_Type_bits
+ * @name Flags AD Type bits
+ * @brief Bits in Flags AD Type
+ * @{
+ */
+#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE	(0x01)
+#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE	(0x02)
+#define FLAG_BIT_BR_EDR_NOT_SUPPORTED			(0x04)
+#define FLAG_BIT_LE_BR_EDR_CONTROLLER			(0x08)
+#define FLAG_BIT_LE_BR_EDR_HOST					(0x10)
+/**
+ * @}
+ */
+
+/**
+ * @name Service UUID AD types
+ * @{
+ */
+#define AD_TYPE_16_BIT_SERV_UUID				(0x02)
+#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST		(0x03)
+#define AD_TYPE_32_BIT_SERV_UUID				(0x04)
+#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST		(0x05)
+#define AD_TYPE_128_BIT_SERV_UUID				(0x06)
+#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST	(0x07)
+/**
+ * @}
+ */
+
+/* LOCAL NAME AD types */
+/**
+ * @name Local name AD types
+ * @{
+ */
+#define AD_TYPE_SHORTENED_LOCAL_NAME			(0x08)
+#define AD_TYPE_COMPLETE_LOCAL_NAME			    (0x09)
+/**
+ * @}
+ */
+
+/* TX power level AD type*/
+#define AD_TYPE_TX_POWER_LEVEL					(0x0A)
+
+/* Class of device */
+#define AD_TYPE_CLASS_OF_DEVICE					(0x0D)
+
+/* security manager TK value AD type */
+#define AD_TYPE_SEC_MGR_TK_VALUE				(0x10)
+
+/* security manager OOB flags */
+#define AD_TYPE_SEC_MGR_OOB_FLAGS				(0x11)
+
+/* slave connection interval AD type */
+#define AD_TYPE_SLAVE_CONN_INTERVAL				(0x12)
+
+/* service solicitation UUID list Ad types*/
+/**
+ * @name Service solicitation UUID list AD types
+ * @{
+ */
+#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST	(0x14)
+#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST	(0x1F)
+#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST	(0x15)
+/**
+ * @}
+ */
+
+/* service data AD type */
+#define AD_TYPE_SERVICE_DATA			(0x16)
+
+/* manufaturer specific data AD type */
+#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA	(0xFF)
+
+/* appearance AD type */
+#define AD_TYPE_APPEARANCE			(0x19)
+
+/* advertising interval AD type */
+#define AD_TYPE_ADVERTISING_INTERVAL		(0x1A)
+
+/**
+ * @}
+ */
+
+#define MAX_ADV_DATA_LEN						(31)
+
+#define DEVICE_NAME_LEN			  				(7)
+#define BD_ADDR_SIZE							(6)
+
+/**
+ * @name Privacy flag values
+ * @{
+ */
+#define PRIVACY_ENABLED							(0x01)
+#define PRIVACY_DISABLED						(0x00)
+/**
+ * @}
+ */
+
+/**
+ * @name Intervals
+ * Intervals in terms of 625 micro sec
+ * @{
+ */
+#define DIR_CONN_ADV_INT_MIN					(0x190)/*250ms*/
+#define DIR_CONN_ADV_INT_MAX					(0x320)/*500ms*/
+#define UNDIR_CONN_ADV_INT_MIN					(0x800)/*1.28s*/
+#define UNDIR_CONN_ADV_INT_MAX					(0x1000)/*2.56s*/
+#define LIM_DISC_ADV_INT_MIN					(0x190)/*250ms*/
+#define LIM_DISC_ADV_INT_MAX					(0x320)/*500ms*/
+#define GEN_DISC_ADV_INT_MIN					(0x800)/*1.28s*/
+#define GEN_DISC_ADV_INT_MAX					(0x1000)/*2.56s*/
+/**
+ * @}
+ */
+
+/**
+ * @name Timeout values
+ * @{
+ */
+#define LIM_DISC_MODE_TIMEOUT					(180000)/* 180 seconds. according to the errata published */
+#define PRIVATE_ADDR_INT_TIMEOUT				(900000)/* 15 minutes */
+/**
+ * @}
+ */
+
+/**
+ * @anchor gap_roles
+ * @name GAP Roles
+ * @{
+*/
+#define GAP_PERIPHERAL_ROLE_IDB05A1			(0x01)
+#define GAP_BROADCASTER_ROLE_IDB05A1		        (0x02)
+#define GAP_CENTRAL_ROLE_IDB05A1			(0x04)
+#define GAP_OBSERVER_ROLE_IDB05A1			(0x08)
+
+#define GAP_PERIPHERAL_ROLE_IDB04A1			(0x01)
+#define GAP_BROADCASTER_ROLE_IDB04A1		        (0x02)
+#define GAP_CENTRAL_ROLE_IDB04A1			(0x03)
+#define GAP_OBSERVER_ROLE_IDB04A1			(0x04)
+/**
+ * @}
+ */
+
+/**
+ * @anchor gap_procedure_codes
+ * @name GAP procedure codes
+ * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event
+ * and aci_gap_terminate_gap_procedure() command.
+ * @{
+ */
+#define GAP_LIMITED_DISCOVERY_PROC                  (0x01)
+#define GAP_GENERAL_DISCOVERY_PROC                  (0x02)
+#define GAP_NAME_DISCOVERY_PROC                     (0x04)
+#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC      (0x08)
+#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC   (0x10)
+#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20)
+#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC    (0x40)
+#define GAP_OBSERVATION_PROC_IDB05A1                (0x80)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* __BNRG_GAP_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,1231 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name          : bluenrg_gap_aci.h
+* Author             : AMS - AAS
+* Version            : V1.0.0
+* Date               : 26-Jun-2014
+* Description        : Header file with GAP commands for BlueNRG FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_GAP_ACI_H__
+#define __BLUENRG_GAP_ACI_H__
+
+/**
+ *@addtogroup GAP GAP
+ *@brief GAP layer.
+ *@{
+ */
+
+/**
+ *@defgroup GAP_Functions GAP functions
+ *@brief API for GAP layer.
+ *@{
+ */
+
+/**
+  * @brief  Initialize the GAP layer.
+  * @note   Register the GAP service with the GATT. 
+  *         All the standard GAP characteristics will also be added:
+  *         @li Device Name
+  *         @li Appearance
+  *         @li Peripheral Preferred Connection Parameters (peripheral role only)
+  *         @code
+
+              tBleStatus ret;
+              uint16_t service_handle, dev_name_char_handle, appearance_char_handle;
+
+              ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle);
+              if(ret){
+                PRINTF("GAP_Init failed.\n");
+                reboot();    
+              }  
+              const char *name = "BlueNRG";  
+              ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name);        
+              if(ret){
+                PRINTF("aci_gatt_update_char_value failed.\n");
+              }  
+  *         @endcode
+  * @param       role     Bitmap of allowed roles: see @ref gap_roles "GAP roles".
+  * @param       privacy_enabled     Enable (1) or disable (0) privacy.
+  * @param       device_name_char_len Length of the device name characteristic
+  * @param[out]  service_handle  Handle of the GAP service.
+  * @param[out]  dev_name_char_handle  Device Name Characteristic handle
+  * @param[out]  appearance_char_handle Appearance Characteristic handle
+  * @retval tBleStatus Value indicating success or error code.
+  */
+tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled,
+                        uint8_t device_name_char_len,
+                        uint16_t* service_handle,
+                        uint16_t* dev_name_char_handle,
+                        uint16_t* appearance_char_handle);
+/**
+  * @brief  Initialize the GAP layer.
+  * @note   Register the GAP service with the GATT.
+  *         All the standard GAP characteristics will also be added:
+  *         @li Device Name
+  *         @li Appearance
+  *         @li Peripheral Privacy Flag (peripheral role only)
+  *         @li Reconnection Address (peripheral role only)
+  *         @li Peripheral Preferred Connection Parameters (peripheral role only)
+  *         @code
+
+              tBleStatus ret;
+              uint16_t service_handle, dev_name_char_handle, appearance_char_handle;
+
+              ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle);
+              if(ret){
+                PRINTF("GAP_Init failed.\n");
+                reboot();    
+              }  
+              const char *name = "BlueNRG";  
+              ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name);        
+              if(ret){
+                PRINTF("aci_gatt_update_char_value failed.\n");
+              }  
+  *         @endcode
+  * @param       role     One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles".
+  * @param[out]  service_handle  Handle of the GAP service.
+  * @param[out]  dev_name_char_handle  Device Name Characteristic handle
+  * @param[out]  appearance_char_handle Appearance Characteristic handle
+  * @retval tBleStatus Value indicating success or error code.
+  */
+tBleStatus aci_gap_init_IDB04A1(uint8_t role,
+                 uint16_t* service_handle,
+                 uint16_t* dev_name_char_handle,
+                 uint16_t* appearance_char_handle);
+
+/**
+  * @brief   Set the Device in non-discoverable mode.
+  * @note    This command will disable the LL advertising.
+  * @retval  tBleStatus Value indicating success or error code.
+  */
+tBleStatus aci_gap_set_non_discoverable(void);
+
+/**
+ * @brief  Put the device in limited discoverable mode
+ *         (as defined in GAP specification volume 3, section 9.2.3).
+ * @note    The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds.
+ *          The advertising can be disabled at any time by issuing
+ *          aci_gap_set_non_discoverable() command.
+ *          The AdvIntervMin and AdvIntervMax parameters are optional. If both
+ *          are set to 0, the GAP will use default values (250 ms and 500 ms respectively).
+ *          Host can set the Local Name, a Service UUID list and the Slave Connection
+ *          Minimum and Maximum. If provided, these data will be inserted into the
+ *          advertising packet payload as AD data. These parameters are optional
+ *          in this command. These values can be also set using aci_gap_update_adv_data()
+ *          separately.
+ *          The total size of data in advertising packet cannot exceed 31 bytes.
+ *          With this command, the BLE Stack will also add automatically the following
+ *          standard AD types:
+ *          @li AD Flags
+ *          @li TX Power Level
+ *
+ *          When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates
+ *          @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event.
+ *
+ *          Example:
+ * @code
+ *
+ *              #define  ADV_INTERVAL_MIN_MS  100
+ *              #define  ADV_INTERVAL_MAX_MS  200
+ *
+ *              tBleStatus ret;
+ *
+ *              const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'};
+ *              const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12};
+ *
+ *              ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625,
+ *                                                     (ADV_INTERVAL_MAX_MS*1000)/0.625,
+ *                                                     STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE,
+ *                                                    sizeof(local_name), local_name,
+ *                                                     sizeof(serviceUUIDList), serviceUUIDList,
+ *                                                     0, 0);
+ * @endcode
+ *
+ * @param       AdvType     One of the advertising types:
+ *               @arg @ref ADV_IND Connectable undirected advertising
+ *               @arg @ref ADV_SCAN_IND Scannable undirected advertising
+ *               @arg @ref ADV_NONCONN_IND Non connectable undirected advertising
+ * @param       AdvIntervMin    Minimum advertising interval.
+ * 								 Range: 0x0020 to 0x4000
+ * 								 Default: 250 ms
+ * 								 Time = N * 0.625 msec
+ * 								 Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND).
+ * @param       AdvIntervMax    Maximum advertising interval.
+ * 								Range: 0x0020 to 0x4000
+ * 								Default: 500 ms
+ * 								Time = N * 0.625 msec
+ * 								Time Range: 20 ms to 10.24 sec  (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND).
+ * @param       OwnAddrType     Type of our address used during advertising
+ *                              (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR).
+ * @param       AdvFilterPolicy  Filter policy:
+ *                               @arg NO_WHITE_LIST_USE
+ *                               @arg WHITE_LIST_FOR_ONLY_SCAN
+ *                               @arg WHITE_LIST_FOR_ONLY_CONN
+ *                               @arg WHITE_LIST_FOR_ALL
+ * @param  LocalNameLen  Length of LocalName array.
+ * @param  LocalName  Array containing the Local Name AD data. First byte is the AD type:
+ *                       @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME.
+ * @param  ServiceUUIDLen Length of ServiceUUIDList array.
+ * @param  ServiceUUIDList  This is the list of the UUIDs AD Types as defined in Volume 3,
+ *  							Section 11.1.1 of GAP Specification. First byte is the AD Type.
+ *  							@arg @ref AD_TYPE_16_BIT_SERV_UUID
+ *  							@arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST
+ *  							@arg @ref AD_TYPE_128_BIT_SERV_UUID
+ *  							@arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST
+ * @param  SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral.
+ * 							 If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000,
+ * 							 Slave Connection Interval Range AD structure will be added in advertising
+ * 							 data.
+ * 							 Connection interval is defined in the following manner:
+ * 							 connIntervalmin = Slave_Conn_Interval_Min x 1.25ms
+ * 							 Slave_Conn_Interval_Min range: 0x0006 to 0x0C80
+ * 							 Value of 0xFFFF indicates no specific minimum.
+ * @param  SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral.
+ * 							 If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000,
+ * 							 Slave Connection Interval Range AD structure will be added in advertising
+ * 							 data.
+ * 							 ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms
+ * 							 Slave_Conn_Interval_Max range: 0x0006 to 0x0C80
+ * 							 Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min.
+ * 							 Value of 0xFFFF indicates no specific maximum.
+ *
+ * @retval tBleStatus Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax,
+					    uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen,
+					    const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList,
+					    uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax);
+/**
+ * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4).
+ * @note  The device will be discoverable until the Host issue Aci_Gap_Set_Non_Discoverable command.
+ * 		  The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses
+ * 		  the default values for advertising intervals (1.28 s and 2.56 s respectively for IDB04A1).
+ *        When using connectable undirected advertising events:\n
+ *        @li Adv_Interval_Min = 30 ms
+ *        @li Adv_Interval_Max = 60 ms
+ *        \nWhen using non-connectable advertising events or scannable undirected advertising events:\n
+ *        @li Adv_Interval_Min = 100 ms
+ *        @li Adv_Interval_Max = 150 ms
+ * 		  Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided,
+ * 		  these data will be inserted into the advertising packet payload as AD data. These parameters are optional
+ * 		  in this command. These values can be also set using aci_gap_update_adv_data() separately.
+ * 		  The total size of data in advertising packet cannot exceed 31 bytes.
+ * 		  With this command, the BLE Stack will also add automatically the following standard AD types:
+ * 		  @li AD Flags
+ * 		  @li TX Power Level
+ *
+ * 		  Usage example:
+ *
+ * 		  @code
+ *
+ *              #define  ADV_INTERVAL_MIN_MS  800
+ *              #define  ADV_INTERVAL_MAX_MS  900
+ *              #define  CONN_INTERVAL_MIN_MS 100
+ *              #define  CONN_INTERVAL_MAX_MS 300
+ *
+ *              tBleStatus ret;
+ *
+ *              const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'};
+ *              const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12};
+ *
+ *              ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625,
+ *                                                     (ADV_INTERVAL_MAX_MS*1000)/625,
+ *                                                     STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE,
+ *                                                     sizeof(local_name), local_name,
+ *                                                     0, NULL,
+ *                                                     (CONN_INTERVAL_MIN_MS*1000)/1250,
+ *                                                     (CONN_INTERVAL_MAX_MS*1000)/1250);
+ * 			@endcode
+ *
+ * @param AdvType One of the advertising types:
+ *                @arg @ref ADV_IND Connectable undirected advertising
+ *                @arg @ref ADV_SCAN_IND Scannable undirected advertising
+ *                @arg @ref ADV_NONCONN_IND Non connectable undirected advertising
+ * @param       AdvIntervMin    Minimum advertising interval.
+ * 								 Range: 0x0020 to 0x4000
+ * 								 Default: 1.28 s
+ * 								 Time = N * 0.625 msec
+ * 								 Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND).
+ * @param       AdvIntervMax    Maximum advertising interval.
+ * 								Range: 0x0020 to 0x4000
+ * 								Default: 2.56 s
+ * 								Time = N * 0.625 msec
+ * 								Time Range: 20 ms to 10.24 sec  (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND).
+ * @param       OwnAddrType     Type of our address used during advertising
+ *                              (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR).
+ * @param       AdvFilterPolicy  Filter policy:
+ *                               @arg @ref NO_WHITE_LIST_USE
+ *                               @arg @ref WHITE_LIST_FOR_ONLY_SCAN
+ *                               @arg @ref WHITE_LIST_FOR_ONLY_CONN
+ *                               @arg @ref WHITE_LIST_FOR_ALL
+ * @param  LocalNameLen  Length of LocalName array.
+ * @param  LocalName  Array containing the Local Name AD data. First byte is the AD type:
+ *                       @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME.
+ * @param  ServiceUUIDLen Length of ServiceUUIDList array.
+ * @param  ServiceUUIDList  This is the list of the UUIDs AD Types as defined in Volume 3,
+ *  							Section 11.1.1 of GAP Specification. First byte is the AD Type.
+ *  							@arg @ref AD_TYPE_16_BIT_SERV_UUID
+ *  							@arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST
+ *  							@arg @ref AD_TYPE_128_BIT_SERV_UUID
+ *  							@arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST
+ * @param  SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral.
+ * 							 If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000,
+ * 							 Slave Connection Interval Range AD structure will be added in advertising
+ * 							 data.
+ * 							 Connection interval is defined in the following manner:
+ * 							 connIntervalmin = Slave_Conn_Interval_Min x 1.25ms
+ * 							 Slave_Conn_Interval_Min range: 0x0006 to 0x0C80
+ * 							 Value of 0xFFFF indicates no specific minimum.
+ * @param  SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral.
+ * 							 If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000,
+ * 							 Slave Connection Interval Range AD structure will be added in advertising
+ * 							 data.
+ * 							 ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms
+ * 							 Slave_Conn_Interval_Max range: 0x0006 to 0x0C80
+ * 							 Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min.
+ * 							 Value of 0xFFFF indicates no specific maximum.
+ *
+ * @retval tBleStatus Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax,
+                             uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen,
+                             const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList,
+                             uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax);
+
+/**
+ * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3).
+ * @note  If the privacy is enabled, the reconnection address is used for advertising, otherwise the address
+ * 		  of the type specified in OwnAddrType is used. The device will be in directed connectable mode only
+ * 		  for 1.28 seconds. If no connection is established within this duration, the device enters non
+ * 		  discoverable mode and advertising will have to be again enabled explicitly.
+ * 		  The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT
+ * 		  if the connection was not established and 0x00 if the connection was successfully established.
+ *
+ * 		  Usage example:
+ * 		  @code
+ *
+ * 		  tBleStatus ret;
+ *
+ * 		  const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02};
+ * 		  ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address);
+ * 		  @endcode
+ *
+ *
+ *
+ * @param own_addr_type  Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR).
+ * @param directed_adv_type  Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV).
+ * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR).
+ * @param initiator_addr     Initiator's address (Little Endian).
+ * @param adv_interv_min     Minimum advertising interval for low duty cycle directed advertising.
+ *                           Range: 0x0020 to 0x4000
+ *							 Time = N * 0.625 msec
+ *							 Time Range: 20 ms to 10.24 sec.
+ * @param adv_interv_max     Maximum advertising interval for low duty cycle directed advertising.
+ *                           Range: 0x0020 to 0x4000
+ *							 Time = N * 0.625 msec
+ *							 Time Range: 20 ms to 10.24 sec.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type,
+                                          const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max);
+/**
+ * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3).
+ * @note  If the privacy is enabled, the reconnection address is used for advertising, otherwise the address
+ * 		  of the type specified in OwnAddrType is used. The device will be in directed connectable mode only
+ * 		  for 1.28 seconds. If no connection is established within this duration, the device enters non
+ * 		  discoverable mode and advertising will have to be again enabled explicitly.
+ * 		  The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT
+ * 		  if the connection was not established and 0x00 if the connection was successfully established.
+ *
+ * 		  Usage example:
+ * 		  @code
+ *
+ * 		  tBleStatus ret;
+ *
+ * 		  const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02};
+ * 		  ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address);
+ * 		  @endcode
+ *
+ *
+ *
+ * @param own_addr_type  Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR).
+ * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR).
+ * @param initiator_addr     Initiator's address (Little Endian).
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr);
+
+/**
+ * @brief Set the IO capabilities of the device.
+ * @note This command has to be given only when the device is not in a connected state.
+ * @param io_capability One of the allowed codes for IO Capability:
+ * 		  @arg @ref IO_CAP_DISPLAY_ONLY
+ * 		  @arg @ref IO_CAP_DISPLAY_YES_NO
+ * 		  @arg @ref IO_CAP_KEYBOARD_ONLY
+ * 		  @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT
+ * 		  @arg @ref IO_CAP_KEYBOARD_DISPLAY
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_io_capability(uint8_t io_capability);
+
+/**
+ * @brief Set the authentication requirements for the device.
+ * @note  If the oob_enable is set to 0, oob_data will be ignored.
+ *        This command has to be given only when the device is not in a connected state.
+ * @param mitm_mode MITM mode:
+ * 					@arg @ref MITM_PROTECTION_NOT_REQUIRED
+ * 					@arg @ref MITM_PROTECTION_REQUIRED
+ * @param oob_enable If OOB data are present or not:
+ * 					 @arg @ref OOB_AUTH_DATA_ABSENT
+ * 					 @arg @ref OOB_AUTH_DATA_PRESENT
+ * @param oob_data   Out-Of-Band data
+ * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process
+ * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process
+ * @param use_fixed_pin If application wants to use a fixed pin or not:
+ * 						@arg @ref USE_FIXED_PIN_FOR_PAIRING
+ * 						@arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING
+ * 						If a fixed pin is not used, it has to be provided by the application with
+ * 						aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event.
+ * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will
+ * 					be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is
+ * 					accepted.
+ * @param bonding_mode One of the bonding modes:
+ * 					   @arg @ref BONDING
+ * 					   @arg @ref NO_BONDING
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode,
+                                        uint8_t oob_enable,
+                                        uint8_t oob_data[16],
+                                        uint8_t min_encryption_key_size,
+                                        uint8_t max_encryption_key_size,
+                                        uint8_t use_fixed_pin,
+                                        uint32_t fixed_pin,
+                                        uint8_t bonding_mode);
+ /**
+  * @brief Set the authorization requirements of the device.
+  * @note This command has to be given when connected to a device if authorization is required to access services
+  *       which require authorization.
+  * @param conn_handle Handle of the connection.
+  * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required
+  * 							@arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables
+  * 							the authorization requirement in the device and when a remote device
+  * 							tries to read/write a characeristic with authorization requirements, the stack will
+  *                             send back an error response with "Insufficient authorization" error code.
+  *                             After pairing is complete a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event
+  * 							will be sent to the Host.
+  * @return Value indicating success or error code.
+  */
+tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable);
+
+/**
+ * @brief Provide the pass key that will be used during pairing.
+ * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event.
+ * @param conn_handle Connection handle
+ * @param passkey	  Pass key that will be used during the pairing process. Must be a number between
+ * 					  0 and 999999.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey);
+
+/**
+ * @brief Authorize a device to access attributes.
+ * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST.
+ *
+ * @param conn_handle Connection handle
+ * @param authorize   @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection)
+ * 					  @arg @ref CONNECTION_REJECTED : Reject (reject connection)
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize);
+
+/**
+ * @brief Put the device into non-connectable mode.
+ * @param adv_type One of the allowed advertising types:
+ *                 @arg @ref ADV_SCAN_IND : Scannable undirected advertising
+ *                 @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising
+ * @param own_address_type If Privacy is disabled, then the peripheral address can be
+ * 			               @arg @ref PUBLIC_ADDR.
+ * 			               @arg @ref STATIC_RANDOM_ADDR.
+ *                         If Privacy is enabled, then the peripheral address can be 
+ *                         @arg @ref RESOLVABLE_PRIVATE_ADDR
+ *                         @arg @ref NON_RESOLVABLE_PRIVATE_ADDR
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type);
+/**
+ * @brief Put the device into non-connectable mode.
+ * @param adv_type One of the allowed advertising types:
+ *                 @arg @ref ADV_SCAN_IND : Scannable undirected advertising
+ *                 @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type);
+
+/**
+ * @brief Put the device into undirected connectable mode.
+ * @note  If privacy is enabled in the device, a resolvable private address is generated and used
+ *        as the advertiser's address. If not, the address of the type specified in own_addr_type
+ *        is used for advertising.
+ * @param own_addr_type Type of our address used during advertising:
+ *                      if BLUENRG (IDB04A1)
+ * 			            @arg @ref PUBLIC_ADDR.
+ * 			            @arg @ref STATIC_RANDOM_ADDR.
+ *                      else if BLUENRG_MS (IDB05A1)
+ *                      If Privacy is disabled:
+ * 			            @arg @ref PUBLIC_ADDR.
+ * 			            @arg @ref STATIC_RANDOM_ADDR.
+ *                      If Privacy is enabled:
+ *                      @arg @ref RESOLVABLE_PRIVATE_ADDR
+ *                      @arg @ref NON_RESOLVABLE_PRIVATE_ADDR
+ * @param adv_filter_policy  Filter policy:
+ *                         @arg @ref NO_WHITE_LIST_USE
+ *                         @arg @ref WHITE_LIST_FOR_ALL
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy);
+
+/**
+ * @brief Send a slave security request to the master.
+ * @note This command has to be issued to notify the master of the security requirements of the slave.
+ * 		 The master may encrypt the link, initiate the pairing procedure, or reject the request.
+ * @param conn_handle Connection handle
+ * @param bonding	   One of the bonding modes:
+ * 					   @arg @ref BONDING
+ * 					   @arg @ref NO_BONDING
+ * @param mitm_protection  If MITM protection is required or not:
+ * 						   @arg @ref MITM_PROTECTION_NOT_REQUIRED
+ * 					       @arg @ref MITM_PROTECTION_REQUIRED
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection);
+
+/**
+ * @brief Update advertising data.
+ * @note This command can be used to update the advertising data for a particular AD type.
+ *       If the AD type specified does not exist, then it is added to the advertising data.
+ *       If the overall advertising data length is more than 31 octets after the update, then
+ *       the command is rejected and the old data is retained.
+ * @param AdvLen Length of AdvData array
+ * @param AdvData Advertisement Data,  formatted as specified in Bluetooth specification
+ *        (Volume 3, Part C, 11), including data length. It can contain more than one AD type.
+ *        Example
+ * @code
+ *  tBleStatus ret;
+ *  const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'};
+ *  const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12};
+ *  const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01};
+ *
+ *  ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE,
+ *                                 8, local_name, 3, serviceUUIDList, 0, 0);
+ *  ret = aci_gap_update_adv_data(5, manuf_data);
+ * @endcode
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData);
+
+/**
+ * @brief Delete an AD Type
+ * @note This command can be used to delete the specified AD type from the advertisement data if
+ * 		 present.
+ * @param ad_type One of the allowed AD types (see @ref AD_Types)
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_delete_ad_type(uint8_t ad_type);
+
+/**
+ * @brief Get the current security settings
+ * @note This command can be used to get the current security settings of the device.
+ * @param mitm_protection 	@arg 0: Not required
+ * 							@arg 1: Required
+ * @param bonding			@arg 0: No bonding mode
+ * 							@arg 1: Bonding mode
+ * @param oob_data			@arg 0: Data absent
+ * 							@arg 1: Data present
+ * @param passkey_required  @arg 0: Not required
+ * 							@arg 1: Fixed pin is present which is being used
+ * 							@arg 2: Passkey required for pairing. An event will be generated
+ * 							when required.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding,
+                                      uint8_t* oob_data, uint8_t* passkey_required);
+
+/**
+ * @brief Add addresses of bonded devices into the controller's whitelist.
+ * @note  The command will return an error if there are no devices in the database or if it was unable
+ * 		  to add the device into the whitelist.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_configure_whitelist(void);
+
+/**
+ * @brief Terminate a connection.
+ * @note  A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected.
+ * @param conn_handle Connection handle
+ * @param reason  Reason for requesting disconnection. The error code can be any of ones as specified
+ * 				  for the disconnected command in the HCI specification (See @ref HCI_Error_codes).
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason);
+
+/**
+ * @brief Clear the security database.
+ * @note  All the devices in the security database will be removed.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_clear_security_database(void);
+
+/**
+ * @brief Allows the security manager to complete the pairing procedure and re-bond with the master.
+ * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated.
+ * @param conn_handle 
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle);
+/**
+ * @brief Allows the security manager to complete the pairing procedure and re-bond with the master.
+ * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_allow_rebond_IDB04A1(void);
+
+/**
+ * @brief Start the limited discovery procedure.
+ * @note  The controller is commanded to start active scanning. When this procedure is started,
+ *        only the devices in limited discoverable mode are returned to the upper layers.
+ *        The procedure is terminated when either the upper layers issue a command to terminate the
+ *        procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code
+ *        set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated
+ *        due to any of the above  reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with
+ *        the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC.
+ *        The device found when the procedure is ongoing is returned to the upper layers through the
+ *        event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1).
+ * @param scanInterval Time interval from when the Controller started its last LE scan until it begins
+ * 					   the subsequent LE scan. The scan interval should be a number in the range
+ * 					   0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					   For a number N, Time = N x 0.625 msec.
+ * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * 					 or equal to Scan_Interval. The scan window should be a number in the range
+ * 					 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					 For a number N, Time = N x 0.625 msec.
+ * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR).
+ * @param filterDuplicates Duplicate filtering enabled or not.
+ * 						   @arg 0x00: Do not filter the duplicates
+ * 						   @arg 0x01: Filter duplicates
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
+						uint8_t own_address_type, uint8_t filterDuplicates);
+
+/**
+ * @brief Start the general discovery procedure.
+ * @note  The controller is commanded to start active scanning. The procedure is terminated when
+ * 		  either the upper layers issue a command to terminate the procedure by issuing the command
+ * 		  aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC
+ * 		  or a timeout happens. When the procedure is terminated due to any of the above reasons,
+ * 		  @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to
+ * 		  @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to
+ * 		  the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND  (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1).
+ * @param scanInterval Time interval from when the Controller started its last LE scan until it begins
+ * 					   the subsequent LE scan. The scan interval should be a number in the range
+ * 					   0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					   For a number N, Time = N x 0.625 msec.
+ * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * 					 or equal to Scan_Interval. The scan window should be a number in the range
+ * 					 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					 For a number N, Time = N x 0.625 msec.
+ * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR).
+ * @param filterDuplicates Duplicate filtering enabled or not.
+ * 						   @arg 0x00: Do not filter the duplicates
+ * 						   @arg 0x01: Filter duplicates
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
+						uint8_t own_address_type, uint8_t filterDuplicates);
+
+/**
+ * @brief Start the name discovery procedure.
+ * @note  A LE_Create_Connection call will be made to the controller by GAP with the initiator filter
+ * 		  policy set to “ignore whitelist and process connectable advertising packets only for the
+ * 		  specified device”. Once a connection is established, GATT procedure is started to read the
+ * 		  device name characteristic. When the read is completed (successfully or unsuccessfully),
+ * 		  a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also
+ * 		  contains the name of the device if the device name was read successfully.
+ * @param scanInterval Time interval from when the Controller started its last LE scan until it begins
+ * 					   the subsequent LE scan. The scan interval should be a number in the range
+ * 					   0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					   For a number N, Time = N x 0.625 msec.
+ * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * 					 or equal to Scan_Interval. The scan window should be a number in the range
+ * 					 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					 For a number N, Time = N x 0.625 msec.
+ * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR).
+ * @param peer_bdaddr Address of the peer device with which a connection has to be established.
+ * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR).
+ * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or
+ * 							equal to Conn_Interval_Max.\n
+ * 							Range: 0x0006 to 0x0C80\n
+ * 							Time = N x 1.25 msec\n
+ * 							Time Range: 7.5 msec to 4 seconds
+ * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or
+ * 							equal to Conn_Interval_Min.\n
+ * 							Range: 0x0006 to 0x0C80\n
+ * 							Time = N x 1.25 msec\n
+ * 							Time Range: 7.5 msec to 4 seconds
+ * @param conn_latency Slave latency for the connection in number of connection events.\n
+ * 						 Range: 0x0000 to 0x01F4
+ * @param supervision_timeout Supervision timeout for the LE Link.\n
+ * 							  Range: 0x000A to 0x0C80\n
+ * 							  Time = N x 10 msec\n
+ * 							  Time Range: 100 msec to 32 seconds
+ * @param min_conn_length Minimum length of connection needed for the LE connection.\n
+ * 						  Range: 0x0000 - 0xFFFF\n
+ * 						  Time = N x 0.625 msec.
+ * @param max_conn_length Maximum length of connection needed for the LE connection.\n
+ * 						  Range: 0x0000 - 0xFFFF\n
+ * 						  Time = N x 0.625 msec.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
+				     uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr,	
+				     uint8_t own_bdaddr_type, uint16_t conn_min_interval,	
+				     uint16_t conn_max_interval, uint16_t conn_latency,	
+				     uint16_t supervision_timeout, uint16_t min_conn_length, 
+				     uint16_t max_conn_length);
+
+/**
+ * @brief Start the auto connection establishment procedure.
+ * @note The devices specified are added to the white list of the controller and a LE_Create_Connection
+ * 		 call will be made to the controller by GAP with the initiator filter policy set to
+ * 		 “use whitelist to determine which advertiser to connect to”. When a command is issued to
+ * 		 terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the
+ * 		 controller by GAP.
+ * 		 The procedure is terminated when either a connection is successfully established with one of
+ * 		 the specified devices in the white list or the procedure is explicitly terminated by issuing
+ * 		 the command aci_gap_terminate_gap_procedure() with the procedure code set to
+ * 		 @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with
+ * 		 the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC.
+ * @param scanInterval Time interval from when the Controller started its last LE scan until it begins
+ * 					   the subsequent LE scan. The scan interval should be a number in the range
+ * 					   0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					   For a number N, Time = N x 0.625 msec.
+ * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * 					 or equal to Scan_Interval. The scan window should be a number in the range
+ * 					 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					 For a number N, Time = N x 0.625 msec.
+ * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR).
+ * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or
+ * 							equal to Conn_Interval_Max.\n
+ * 							Range: 0x0006 to 0x0C80\n
+ * 							Time = N x 1.25 msec\n
+ * 							Time Range: 7.5 msec to 4 seconds
+ * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or
+ * 							equal to Conn_Interval_Min.\n
+ * 							Range: 0x0006 to 0x0C80\n
+ * 							Time = N x 1.25 msec\n
+ * 							Time Range: 7.5 msec to 4 seconds
+ * @param conn_latency Slave latency for the connection in number of connection events.\n
+ * 						 Range: 0x0000 to 0x01F4
+ * @param supervision_timeout Supervision timeout for the LE Link.\n
+ * 							  Range: 0x000A to 0x0C80\n
+ * 							  Time = N x 10 msec\n
+ * 							  Time Range: 100 msec to 32 seconds
+ * @param min_conn_length Minimum length of connection needed for the LE connection.\n
+ * 						  Range: 0x0000 - 0xFFFF\n
+ * 						  Time = N x 0.625 msec.
+ * @param max_conn_length Maximum length of connection needed for the LE connection.\n
+ * 						  Range: 0x0000 - 0xFFFF\n
+ * 						  Time = N x 0.625 msec.
+ * @cond BLUENRG
+ * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address
+ * 						  has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n
+ * @param reconn_addr	Reconnection address used if use_reconn_addr is 1.
+ * @endcond
+ * @param num_whitelist_entries Number of devices that have to be added to the whitelist.
+ * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The
+ * 					 format of the addr_array should be: address type followed by address.
+ * 					 Example:
+ * 					 @code
+ * 					 uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02,
+ * 					 	PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02};
+ * 					 @endcode
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow,
+						 uint8_t own_bdaddr_type, uint16_t conn_min_interval,	
+						 uint16_t conn_max_interval, uint16_t conn_latency,	
+						 uint16_t supervision_timeout, uint16_t min_conn_length, 
+						 uint16_t max_conn_length,
+                         uint8_t num_whitelist_entries,
+                         const uint8_t *addr_array);
+tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow,
+						 uint8_t own_bdaddr_type, uint16_t conn_min_interval,	
+						 uint16_t conn_max_interval, uint16_t conn_latency,	
+						 uint16_t supervision_timeout, uint16_t min_conn_length, 
+						 uint16_t max_conn_length,
+                                                 uint8_t use_reconn_addr,
+                                                 const tBDAddr reconn_addr,
+                                                 uint8_t num_whitelist_entries,
+                                                 const uint8_t *addr_array);
+
+/**
+ * @brief Start a general connection establishment procedure.
+ * @note  The host enables scanning in the controller with the scanner filter policy set
+ *        to “accept all advertising packets” and from the scanning results all the devices
+ *        are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1).
+ *        The upper layer then has to select one of the devices to which it wants to connect
+ *        by issuing the command aci_gap_create_connection(). The procedure is terminated
+ *        when a connection is established or the upper layer terminates the procedure by
+ *        issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to
+ *        @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a
+ *        @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to
+ *        @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC.
+ * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN)
+ * @param scan_interval Time interval from when the Controller started its last LE scan until it begins
+ * 					   the subsequent LE scan. The scan interval should be a number in the range
+ * 					   0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					   For a number N, Time = N x 0.625 msec.
+ * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * 					 or equal to Scan_Interval. The scan window should be a number in the range
+ * 					 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					 For a number N, Time = N x 0.625 msec.
+ * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR).
+ * @param filter_duplicates Duplicate filtering enabled or not.
+ * 						   @arg 0x00: Do not filter the duplicates
+ * 						   @arg 0x01: Filter duplicates
+ * @cond BLUENRG
+ * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address
+ * 						  has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n
+ * @param reconn_addr	Reconnection address used if use_reconn_addr is 1.
+ * @endcond
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window,
+						 uint8_t own_address_type, uint8_t filter_duplicates);
+tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window,
+						 uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr);
+
+/**
+ * @brief Start a selective connection establishment procedure.
+ * @note  The GAP adds the specified device addresses into white list and enables scanning in
+ * 		  the controller with the scanner filter policy set to “accept packets only from
+ * 		  devices in whitelist”. All the devices found are sent to the upper layer by the
+ * 		  event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the
+ * 		  devices to which it wants to connect by issuing the command aci_gap_create_connection().
+ * 		  On completion of the procedure a  @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated
+ * 		  with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC.
+ * 		  The procedure is terminated when a connection is established or the upper layer terminates
+ * 		  the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure
+ * 		  code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC.
+ * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN)
+ * @param scan_interval Time interval from when the Controller started its last LE scan until it begins
+ * 					   the subsequent LE scan. The scan interval should be a number in the range
+ * 					   0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					   For a number N, Time = N x 0.625 msec.
+ * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * 					 or equal to Scan_Interval. The scan window should be a number in the range
+ * 					 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					 For a number N, Time = N x 0.625 msec.
+ * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR).
+ * @param filter_duplicates Duplicate filtering enabled or not.
+ * 						   @arg 0x00: Do not filter the duplicates
+ * 						   @arg 0x01: Filter duplicates
+ * @param num_whitelist_entries Number of devices that have to be added to the whitelist.
+ * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The
+ * 					 format of the addr_array should be: address type followed by address.
+ * 					 Example:
+ * 					 @code
+ * 					 uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02,
+ * 					 	PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02};
+ * 					 @endcode
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window,
+						 uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries,
+                         const uint8_t *addr_array);
+
+/**
+ * @brief Start the direct connection establishment procedure.
+ * @note  A LE_Create_Connection call will be made to the controller by GAP with the initiator filter
+ * 		  policy set to “ignore whitelist and process connectable advertising packets only for the
+ * 		  specified device”. The procedure can be terminated explicitly by the upper layer by issuing
+ * 		  the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the
+ * 		  procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller
+ * 		  by GAP.
+ * 		  On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can
+ * 		  be explicitly terminated by the upper layer by issuing the command
+ * 		  aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC.
+ * @param scanInterval Time interval from when the Controller started its last LE scan until it begins
+ * 					   the subsequent LE scan. The scan interval should be a number in the range
+ * 					   0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					   For a number N, Time = N x 0.625 msec.
+ * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * 					 or equal to Scan_Interval. The scan window should be a number in the range
+ * 					 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * 					 For a number N, Time = N x 0.625 msec.
+ * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR).
+ * @param peer_bdaddr Address of the peer device with which a connection has to be established.
+ * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR).
+ * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or
+ * 							equal to Conn_Interval_Max.\n
+ * 							Range: 0x0006 to 0x0C80\n
+ * 							Time = N x 1.25 msec\n
+ * 							Time Range: 7.5 msec to 4 seconds
+ * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or
+ * 							equal to Conn_Interval_Min.\n
+ * 							Range: 0x0006 to 0x0C80\n
+ * 							Time = N x 1.25 msec\n
+ * 							Time Range: 7.5 msec to 4 seconds
+ * @param conn_latency Slave latency for the connection in number of connection events.\n
+ * 						 Range: 0x0000 to 0x01F4
+ * @param supervision_timeout Supervision timeout for the LE Link.\n
+ * 							  Range: 0x000A to 0x0C80\n
+ * 							  Time = N x 10 msec\n
+ * 							  Time Range: 100 msec to 32 seconds
+ * @param min_conn_length Minimum length of connection needed for the LE connection.\n
+ * 						  Range: 0x0000 - 0xFFFF\n
+ * 						  Time = N x 0.625 msec.
+ * @param max_conn_length Maximum length of connection needed for the LE connection.\n
+ * 						  Range: 0x0000 - 0xFFFF\n
+ * 						  Time = N x 0.625 msec.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow,
+				     uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr,	
+				     uint8_t own_bdaddr_type, uint16_t conn_min_interval,	
+				     uint16_t conn_max_interval, uint16_t conn_latency,	
+				     uint16_t supervision_timeout, uint16_t min_conn_length, 
+				     uint16_t max_conn_length);
+
+/**
+ * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is
+ *  	  returned with the procedure code set to the corresponding procedure.
+ * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes").
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code);
+
+/**
+ * @brief Start the connection parameter update procedure.
+ * @note  Allowed by the Central to update the connection parameter of the specified connection.
+ * 		  A Link Layer Connection Update procedure is started on the controller.
+ * 		  On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to
+ * 		  the upper layer.
+ * @param conn_handle Handle of the connection for which the update procedure has to be started.
+ * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or
+ * 							equal to Conn_Interval_Max.\n
+ * 							Range: 0x0006 to 0x0C80\n
+ * 							Time = N x 1.25 msec\n
+ * 							Time Range: 7.5 msec to 4 seconds
+ * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or
+ * 							equal to Conn_Interval_Min.\n
+ * 							Range: 0x0006 to 0x0C80\n
+ * 							Time = N x 1.25 msec\n
+ * 							Time Range: 7.5 msec to 4 seconds
+ * @param conn_latency Slave latency for the connection in number of connection events.\n
+ * 						 Range: 0x0000 to 0x01F4
+ * @param supervision_timeout Supervision timeout for the LE Link.\n
+ * 							  Range: 0x000A to 0x0C80\n
+ * 							  Time = N x 10 msec\n
+ * 							  Time Range: 100 msec to 32 seconds
+ * @param min_conn_length Minimum length of connection needed for the LE connection.\n
+ * 						  Range: 0x0000 - 0xFFFF\n
+ * 						  Time = N x 0.625 msec.
+ * @param max_conn_length Maximum length of connection needed for the LE connection.\n
+ * 						  Range: 0x0000 - 0xFFFF\n
+ * 						  Time = N x 0.625 msec.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval,	
+                                           uint16_t conn_max_interval, uint16_t conn_latency,	
+                                           uint16_t supervision_timeout, uint16_t min_conn_length, 
+                                           uint16_t max_conn_length);
+
+/**
+ * @brief Send a pairing request.
+ * @note  Send the SM pairing request to start a pairing process from a Central. The authentication
+ * 		  requirements and  IO capabilities should be set before issuing this command using
+ * 		  aci_gap_set_io_capability() and aci_gap_set_auth_requirement().
+ * 		  A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed.
+ * @param conn_handle Handle of the connection for which the pairing request has to be sent.
+ * @param force_rebond  @arg 0x00: Pairing request is sent only if the device has not previously bonded
+ * 						@arg 0x01: Pairing request will be sent even if the device was previously bonded
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond);
+
+/**
+ * @brief Resolve a private address.
+ * @note  This command tries to resolve the address provided with the IRKs present in its database. If
+ * 		  the address is resolved successfully with any one of the IRKs present in the database, it
+ * 		  returns success.
+ * @param[in] address Address to be resolved.
+ * @param[out] actual_address The public or static random address of the peer device, distributed during pairing phase.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address);
+
+/**
+ * @brief Resolve a private address.
+ * @note  This command tries to resolve the address provided with the IRKs present in its database. If
+ * 		  the address is resolved successfully with any one of the IRKs present in the database, it
+ * 		  returns success.
+ * @param address Address to be resolved.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address);
+
+/**
+ * @brief This command gets the list of bonded devices.
+ * @note  It returns the number of addresses and the corresponding address types and values.
+ *        Example:
+ *        @code
+ *        tBleStatus ret;
+ *        uint8_t num_devices = 0;
+ *        uint8_t device_list[12*7];
+ *        ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list));
+ *        for(int i = 0; i < num_devices; i+=7){
+ *        	uint8_t addr_type = device_list[i];
+ *        	uint8_t addr = device_list[i+1];
+ *        	printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]);
+ *        }
+ *        @endcode
+ *
+ * @param[out] num_devices The number of bonded devices.
+ * @param[out] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address
+ *        				  type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR.
+ * @param device_list_size Maximum size of the device_list buffer used to return the device list.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size);
+
+/**
+ * @brief Puts the device into broadcast mode
+ * @note  A privacy enabled device uses either a resolvable private address or a non-resolvable private address
+ * 		  as specified in the own_addr_type parameter of the command.
+ * @param adv_interv_min    Minimum advertising interval.
+ * 							Range: 0x00A0 to 0x4000
+ * 							Time = N * 0.625 msec
+ * 							Time Range: 100 ms to 10.24 sec
+ * @param adv_interv_max    Maximum advertising interval.
+ * 						    Range: 0x00A0 to 0x4000
+ * 							Time = N * 0.625 msec
+ * 							Time Range: 100 ms to 10.24 sec
+ * @param adv_type One of the allowed advertising types:
+ *                @arg @ref ADV_SCAN_IND Scannable undirected advertising
+ *                @arg @ref ADV_NONCONN_IND Non connectable undirected advertising
+ * @param own_addr_type If Privacy is disabled, the broadcaster address can be
+ * 			               @arg @ref PUBLIC_ADDR.
+ * 			               @arg @ref STATIC_RANDOM_ADDR.
+ *                         If Privacy is enabled, then the broadcaster address can be
+ *                         @arg @ref RESOLVABLE_PRIVATE_ADDR
+ *                         @arg @ref NON_RESOLVABLE_PRIVATE_ADDR
+ * @param adv_data_length Length of the advertising data in the advertising packet
+ * @param adv_data		  Advertising data used by the device while advertising
+ * @param num_whitelist_entries Number of devices to be added to whitelist
+ * @param addr_array It will contain the addresses that have to be added into the whitelist. The
+ * 					 format of the addr_array should be: address type followed by address.
+ * 					 Example:
+ * 					 @code
+ * 					 uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02,
+ * 					 	PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02};
+ * 					 @endcode
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type,
+                                      uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data,  uint8_t num_whitelist_entries,
+                                      const uint8_t *addr_array);
+
+/**
+ * @brief Starts an observation procedure, when the device is in Observer role.
+ * @note  The host enables scanning in the controller. The advertising reports are sent to the upper layer
+ *        using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth
+ *        Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event.
+ * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan.
+ * 		  The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec
+ * 		  to 10240 msec. For a number N, Time = N * 0.625 msec.
+ * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval.
+ * 		  The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec
+ * 		  to 10240 msec. For a number N, Time = N * 0.625 msec.
+ * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN)
+ * @param own_address_type If Privacy is disabled, then the scanner address can be
+ * 			               @arg @ref PUBLIC_ADDR.
+ * 			               @arg @ref STATIC_RANDOM_ADDR.
+ *                         If Privacy is enabled, then the scanner address can be
+ *                         @arg @ref RESOLVABLE_PRIVATE_ADDR
+ *                         @arg @ref NON_RESOLVABLE_PRIVATE_ADDR
+ * @param filter_duplicates Duplicate filtering enabled or not.
+ * 						   @arg 0x00: Do not filter the duplicates
+ * 						   @arg 0x01: Filter duplicates
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type,
+						 uint8_t own_address_type, uint8_t filter_duplicates);
+
+/**
+ * @brief The command finds whether a device is bonded.
+ * @note If the device is using a resolvable private address and it has been bonded, then the command will return
+ *       BLE_STATUS_SUCCESS.
+ * @param peer_address_type The address type of the peer device
+ *                         @arg @ref PUBLIC_ADDR.
+ * 			               @arg @ref RANDOM_ADDR.
+ * @param peer_address Address used by the peer device while advertising.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup GAP_Events GAP events
+ * @{
+ */
+
+/**
+ * This event is generated by the controller when the limited discoverable
+ *  mode ends due to timeout (180 seconds). No parameters in the event.
+ */
+#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE     (0x0400)
+
+
+/**
+ * This event is generated when the pairing process has completed successfully
+ * or a pairing procedure timeout has occurred or the pairing has failed.
+ * This is to notify the application that we have paired with a remote device
+ * so that it can take further actions or to notify that a timeout has occurred
+ *  so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt.
+ */
+#define EVT_BLUE_GAP_PAIRING_CMPLT                (0x0401)
+typedef __packed struct _evt_gap_pairing_cmplt{
+  uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */
+  /**
+   * 0x00: Pairing Success. Pairing with a remote device was successful\n
+   * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n
+   * 0x02: Pairing Failed. The pairing failed with the remote device.
+   */
+  uint8_t  status;
+} PACKED evt_gap_pairing_cmplt;
+
+
+/**
+ * This event is generated by the Security manager to the application when a pass key is required for pairing.
+ * When this event is received, the application has to respond with the aci_gap_pass_key_response() command.
+ * See @ref _evt_gap_pass_key_req.
+ */
+#define EVT_BLUE_GAP_PASS_KEY_REQUEST             (0x0402)
+typedef __packed struct _evt_gap_pass_key_req{
+  uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */
+} PACKED evt_gap_pass_key_req;
+
+
+/**
+ * This event is generated by the Security manager to the application when the application
+ * has set that authorization is required for reading/writing of attributes. This event will
+ * be generated as soon as the pairing is complete. When this event is received,
+ * aci_gap_authorization_response() command should be used by the application.
+ * See @ref _evt_gap_author_req.
+ */
+#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST        (0x0403)
+typedef __packed struct _evt_gap_author_req{
+  uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */
+} PACKED evt_gap_author_req;
+
+/**
+ * This event is generated when the slave security request is successfully sent to the master.
+ * No parameters for this event.
+ */
+#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED     (0X0404)
+
+/**
+ * This event is generated on the slave when a aci_gap_slave_security_request()  is called to reestablish the bond
+ * with a master but the master has lost the bond. When this event is received, the upper layer has to issue the
+ * command aci_gap_allow_rebond() in order to allow the slave to continue the pairing process with the master.
+ * On the master this event is raised when aci_gap_send_pairing_request() is called to reestablish a bond with a slave
+ * but the slave has lost the bond. In order to create a new bond the master has to launch aci_gap_send_pairing_request()
+ * with force_rebond set to 1.
+ * No parameters for this event
+ */
+#define EVT_BLUE_GAP_BOND_LOST                    (0X0405)
+
+/**
+ * The event is given by the GAP layer to the upper layers when a device is discovered during scanning
+ * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found.
+ */
+#define EVT_BLUE_GAP_DEVICE_FOUND                 (0x0406)
+typedef __packed struct _evt_gap_device_found{
+  	uint8_t		evt_type;     /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */
+	uint8_t		bdaddr_type;  /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */
+	tBDAddr	    bdaddr;       /**< Address of the peer device found during scanning. */
+	uint8_t		data_length;  /**< Length of advertising or scan response data. */
+	uint8_t		data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */
+} PACKED evt_gap_device_found;
+
+/**
+ * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated
+ * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete.
+ */
+#define EVT_BLUE_GAP_PROCEDURE_COMPLETE           (0x0407)
+typedef __packed struct _evt_gap_procedure_complete{
+  uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */
+  /**
+   * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed
+   * due to authentication requirements).
+   */
+  uint8_t status;
+  /**
+   * Procedure specific data.\n
+   * @li For Name Discovery Procedure:\n
+   * the name of the peer device if the procedure completed successfully.
+   * @li For General Connection Establishment Procedure:\n
+   * The reconnection address written to the peripheral device if the peripheral is privacy enabled
+   */
+  uint8_t data[VARIABLE_SIZE];
+} PACKED evt_gap_procedure_complete;
+
+/**
+ * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral
+ * is not able to resolve the private address of the peer device after connecting to it.
+ */
+#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1          (0x0408)
+typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{
+  uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's.  */
+} PACKED evt_gap_addr_not_resolved_IDB05A1;
+/**
+ * This event is raised when the reconnection address is generated during the general connection
+ * establishment procedure. The same address is set into the peer device also as a part of the general
+ * connection establishment procedure. In order to make use of the reconnection address the next time
+ * while connecting to the bonded peripheral, the application needs to use this reconnection address
+ * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc()
+ * and aci_gap_start_auto_conn_establish_proc().
+ */
+#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1       (0x0408)
+typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{
+  uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */
+} PACKED evt_gap_reconnection_addr_IDB04A1;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,1128 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name          : bluenrg_gatt_aci.h
+* Author             : AMS - AAS
+* Version            : V1.0.0
+* Date               : 26-Jun-2014
+* Description        : Header file with GATT commands for BlueNRG FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_GATT_ACI_H__
+#define __BLUENRG_GATT_ACI_H__
+
+#include "bluenrg_gatt_server.h"
+
+/**
+ *@addtogroup GATT GATT
+ *@brief GATT layer.
+ *@{
+ */
+
+/**
+ *@defgroup GATT_Functions GATT functions
+ *@brief API for GATT layer.
+ *@{
+ */
+
+/**
+  * @brief  Initialize the GATT layer for server and client roles.
+  * @note   It adds also the GATT service with Service Changed Characteristic.
+ *           Until this command is issued the GATT channel will not process any commands
+  *          even if the connection is opened. This command has to be given
+  *          before using any of the GAP features.
+  * @return Value indicating success or error code.
+  */
+tBleStatus aci_gatt_init(void);
+
+/**
+ * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs
+ *        to reserve the handle ranges for this service using max_attr_records parameter. This
+ *        parameter specifies the maximum number of attribute records that can be added to this
+ *        service (including the service attribute, include attribute, characteristic attribute,
+ *        characteristic value attribute and characteristic descriptor attribute). Handle of the
+ *        created service is returned.
+ * @note  Service declaration is taken from the service pool. The attributes for characteristics and descriptors
+ *            are allocated from the attribute pool.
+ * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types".
+ * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field
+ * @param service_type Primary or secondary service. See @ref Service_type "Service Type".
+ * @param max_attr_records Maximum number of attribute records that can be added to this service
+ *                         (including the service declaration itself)
+ * @param[out] serviceHandle Handle of the Service. When this service is added to the service,
+ * 							 a handle is allocated by the server to this service. Server also
+ * 							 allocates a range of handles for this service from serviceHandle to
+ * 							 <serviceHandle + max_attr_records>.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type,
+			     const uint8_t* service_uuid,
+			     uint8_t service_type,
+			     uint8_t max_attr_records,
+			     uint16_t *serviceHandle);
+
+/**
+ * @brief Include a service given by included_start_handle and included_end_handle to another service
+ * 		  given by service_handle. Attribute server creates an INCLUDE definition attribute and return
+ * 		  the handle of this attribute in included_handle.
+ * @param service_handle Handle of the service to which another service has to be included
+ * @param included_start_handle Start Handle of the service which has to be included in service
+ * @param included_end_handle End Handle of the service which has to be included in service
+ * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs".
+ * @param[in] included_uuid 16-bit or 128-bit UUID.
+ * @param[out] included_handle Handle of the include declaration.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle,
+				    uint16_t included_end_handle, uint8_t included_uuid_type,
+				    const uint8_t* included_uuid, uint16_t *included_handle);
+
+/**
+ * @brief Add a characteristic to a service.
+ * @param serviceHandle Handle of the service to which the characteristic has to be added.
+ * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types".
+ *         @arg @ref UUID_TYPE_16
+ *         @arg @ref UUID_TYPE_128
+ * @param charUuid 16-bit or 128-bit UUID.
+ * @param charValueLen Maximum length of the characteristic value.
+ * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3,
+ *        Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties".
+ * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions".
+ * 			@arg ATTR_PERMISSION_NONE
+ * 			@arg ATTR_PERMISSION_AUTHEN_READ
+ * 			@arg ATTR_PERMISSION_AUTHOR_READ
+ * 			@arg ATTR_PERMISSION_ENCRY_READ
+ * 			@arg ATTR_PERMISSION_AUTHEN_WRITE
+ * 			@arg ATTR_PERMISSION_AUTHOR_WRITE
+ * 			@arg ATTR_PERMISSION_ENCRY_WRITE
+ * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server
+ * 					  on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask".
+ * 		   @arg GATT_DONT_NOTIFY_EVENTS
+ * 		   @arg GATT_NOTIFY_ATTRIBUTE_WRITE
+ * 		   @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP
+ * 		   @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP
+ * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16.
+ * @param isVariable If the attribute has a variable length value field (1) or not (0).
+ * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration.
+ * 		  The attribute that holds the characteristic value is allocated at the next handle, followed by the Client
+ * 		  Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE
+ * 		  properties.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_add_char(uint16_t serviceHandle,
+			     uint8_t charUuidType,
+			     const uint8_t* charUuid, 
+			     uint8_t charValueLen, 
+			     uint8_t charProperties,
+			     uint8_t secPermissions,
+			     uint8_t gattEvtMask,
+			     uint8_t encryKeySize,
+			     uint8_t isVariable,
+			     uint16_t* charHandle);
+
+/**
+ * Add a characteristic descriptor to a service.
+ * @param serviceHandle Handle of the service to which the characteristic belongs
+ * @param charHandle Handle of the characteristic to which description has to be added.
+ * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types".
+ *         @arg @ref UUID_TYPE_16
+ *         @arg @ref UUID_TYPE_128
+ * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG
+ * 		(Well_known_UUIDs) or a user-defined one.
+ * @param descValueMaxLen The maximum length of the descriptor value
+ * @param descValueLen Current Length of the characteristic descriptor value
+ * @param[in] descValue Value of the characteristic description
+ * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions".
+ * 			@arg ATTR_PERMISSION_NONE
+ * 			@arg ATTR_PERMISSION_AUTHEN_READ
+ * 			@arg ATTR_PERMISSION_AUTHOR_READ
+ * 			@arg ATTR_PERMISSION_ENCRY_READ
+ * 			@arg ATTR_PERMISSION_AUTHEN_WRITE
+ * 			@arg ATTR_PERMISSION_AUTHOR_WRITE
+ * 			@arg ATTR_PERMISSION_ENCRY_WRITE
+ * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions".
+ * 			@arg ATTR_NO_ACCESS
+ * 			@arg ATTR_ACCESS_READ_ONLY
+ * 			@arg ATTR_ACCESS_WRITE_REQ_ONLY
+ * 			@arg ATTR_ACCESS_READ_WRITE
+ * 			@arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE
+ * 			@arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED
+ * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server
+ * 					  on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask".
+ * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16.
+ * @param isVariable If the attribute has a variable length value field (1) or not (0).
+ * @param[out] descHandle Handle of the Characteristic Descriptor.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle,
+                                  uint16_t charHandle,
+                                  uint8_t descUuidType,
+                                  const uint8_t* uuid, 
+                                  uint8_t descValueMaxLen,
+                                  uint8_t descValueLen,
+                                  const void* descValue, 
+                                  uint8_t secPermissions,
+                                  uint8_t accPermissions,
+                                  uint8_t gattEvtMask,
+                                  uint8_t encryKeySize,
+                                  uint8_t isVariable,
+                                  uint16_t* descHandle);
+
+/**
+ * @brief Update a characteristic value in a service.
+ * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication)
+ *   	 will be sent to the client after sending this command to the BlueNRG. The command is queued into the
+ *   	 BlueNRG command queue. If the buffer is full, because previous commands could not be still processed,
+ *   	 the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or
+ *   	 indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate
+ *   	 than what is allowed by the link. Throughput on BLE link depends on connection interval and
+ *   	 connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request()
+ *   	 for more info on how to suggest new connection parameters from a slave). If the application does not
+ *   	 want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function
+ *   	 returns @ref BLE_STATUS_SUCCESS or any other error code.\n
+ *   	 Example:\n
+ *   	 Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some
+ *   	 notifications will be lost.
+ *   	 @code
+ *   	 tBleStatus Free_Fall_Notify(void)
+ *		 {
+ *		 	uint8_t val;
+ * 			tBleStatus ret;
+ *
+ *			val = 0x01;
+ *			ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val);
+ *
+ *			if (ret != BLE_STATUS_SUCCESS){
+ *			  PRINTF("Error while updating FFall characteristic.\n") ;
+ *			  return BLE_STATUS_ERROR ;
+ *			}
+ *		    return BLE_STATUS_SUCCESS;
+ *		 }
+ *		 @endcode
+ *		 Here if BlueNRG buffer become full, the application try again to send the notification.
+ *		 @code
+ *       struct timer t;
+ *       Timer_Set(&t, CLOCK_SECOND*10);
+ *       while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){
+ *         // Radio is busy (buffer full).
+ *         if(Timer_Expired(&t))
+ *           break;
+ *       }
+ *       @endcode
+ *
+ * @param servHandle Handle of the service to which characteristic belongs
+ * @param charHandle Handle of the characteristic
+ * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0,
+ * 						and the attribute value is of variable length, then the length of the attribute will
+ * 						be set to the charValueLen. If the charValOffset is set to a value greater than 0,
+ * 						then the length of the attribute will be set to the maximum length as specified for
+ * 						the attribute while adding the characteristic.
+ * @param charValueLen Length of the characteristic value in octets
+ * @param[in] charValue Characteristic value
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_update_char_value(uint16_t servHandle, 
+				      uint16_t charHandle,
+				      uint8_t charValOffset,
+				      uint8_t charValueLen,   
+				      const void *charValue);
+/**
+ * @brief Delete the specified characteristic from the service.
+ * @param servHandle Handle of the service to which characteristic belongs
+ * @param charHandle Handle of the characteristic to be deleted
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle);
+
+/**
+ * @brief Delete the specified service from the GATT server database.
+ * @param servHandle Handle of the service to be deleted
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_del_service(uint16_t servHandle);
+
+/**
+ * @brief Delete the Include definition from the service.
+ * @param servHandle Handle of the service to which Include definition belongs
+ * @param includeServHandle Handle of the Included definition to be deleted
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle);
+
+/**
+ * @brief Perform an ATT MTU exchange procedure.
+ * @note  When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP
+ * 		  event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated
+ * 		  to indicate the end of the procedure.
+ * @param conn_handle Connection handle for which the command is given.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle);
+
+/**
+ * @brief Send a @a Find @a Information @a Request.
+ * @note This command is used to obtain the mapping of attribute handles with their associated
+ * 		 types. The responses of the procedure are given through the
+ * 		 @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by
+ * 		 a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param start_handle Starting handle of the range of attributes to be discovered on the server
+ * @param end_handle Ending handle of the range of attributes to be discovered on the server
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle);
+
+/**
+ * @brief Send a @a Find @a By @a Type @a Value @a Request
+ * @note The Find By Type Value Request is used to obtain the handles of attributes that
+ * 		 have a given 16-bit UUID attribute type and a given attribute value.
+ * 		 The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event.
+ * 		 The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param start_handle 	First requested handle number
+ * @param end_handle 	Last requested handle number
+ * @param uuid			2 octet UUID to find (little-endian)
+ * @param attr_val_len  Length of attribute value (maximum value is ATT_MTU - 7).
+ * @param attr_val		Attribute value to find
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+                                          uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val);
+
+/**
+ * @brief Send a @a Read @a By @a Type @a Request
+ * @note  The Read By Type Request is used to obtain the values of attributes where the attribute type
+ * 		  is known but the handle is not known.
+ * 		  The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event.
+ * 		  The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param start_handle First requested handle number
+ * @param end_handle Last requested handle number
+ * @param uuid_type @arg @ref UUID_TYPE_16
+ *         			@arg @ref UUID_TYPE_128
+ * @param uuid 2 or 16 octet UUID
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+                                    uint8_t  uuid_type, uint8_t* uuid);
+
+/**
+ * @brief Send a @a Read @a By @a Group @a Type @a Request
+ * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute
+ * 		 type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping
+ * 		 attribute types are: «Primary Service», «Secondary Service» and «Characteristic».
+ * 		 The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event.
+ * 		 The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param start_handle First requested handle number
+ * @param end_handle Last requested handle number
+ * @param uuid_type @arg @ref UUID_TYPE_16
+ *         			@arg @ref UUID_TYPE_128
+ * @param uuid 2 or 16 octet UUID
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+                                    uint8_t  uuid_type, uint8_t* uuid);
+
+/**
+ * @brief Send a @a Prepare @a Write @a Request
+ * @note  The Prepare Write Request is used to request the server to prepare to write the value of an attribute.
+ * 		 The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event.
+ * 		 The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param attr_handle The handle of the attribute to be written
+ * @param value_offset The offset of the first octet to be written
+ * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5).
+ * @param attr_val 	   The value of the attribute to be written
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset,
+                                    uint8_t  attr_val_len, uint8_t* attr_val);
+
+/**
+ * @brief Send an @a Execute @a Write @a Request
+ * @note The Execute Write Request is used to request the server to write or cancel the write of all the
+ *  	 prepared values currently held in the prepare queue from this client.
+ *  	 The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event.
+ *  	 The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param execute @arg 0x00 – Cancel all prepared writes
+ * 				  @arg 0x01 – Immediately write all pending prepared values.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute);
+
+/**
+ * @brief This command will start the GATT client procedure to discover all primary services on the server.
+ * @note  The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event.
+ * 		  The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle);
+
+/**
+ * @brief Start the procedure to discover the primary services of the specified UUID on the server.
+ * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event.
+ *  	 The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param uuid_type @arg @ref UUID_TYPE_16
+ *         			@arg @ref UUID_TYPE_128
+ * @param uuid 2 or 16 octet UUID
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid);
+
+/**
+ * @brief Start the procedure to find all included services.
+ * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event.
+ * 		 The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param start_handle Start handle of the service
+ * @param end_handle End handle of the service
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle,
+					   uint16_t end_handle);
+
+/**
+ * @brief Start the procedure to discover all the characteristics of a given service.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * 		 Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param start_attr_handle Start attribute handle of the service
+ * @param end_attr_handle End attribute handle of the service
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle,
+					    uint16_t end_attr_handle);
+
+/**
+ * @brief Start the procedure to discover all the characteristics specified by a UUID.
+ * @note  When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ *  	  Before procedure completion the response packets are given through
+ *        @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param start_handle 	Start attribute handle of the service
+ * @param end_handle 	End attribute handle of the service
+ * @param uuid_type @arg @ref UUID_TYPE_16
+ *         			@arg @ref UUID_TYPE_128
+ * @param uuid 2 or 16 octet UUID
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle,
+				                     uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid);
+
+/**
+ * @brief Start the procedure to discover all characteristic descriptors on the server.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * 		 Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param char_val_handle Starting handle of the characteristic
+ * @param char_end_handle End handle of the characteristic
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle,
+						uint16_t char_end_handle);
+
+/**
+ * @brief Start the procedure to read the attribute value.
+ * @note  When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * 		  Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the characteristic to be read
+ * @return Value indicating success or error code.\n
+ * 		 It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n
+ *		- If the exchange has already taken place\n
+ *		- If GATT is expecting response for previous request\n
+ *		- Already a request is in the queue to be sent\n
+ *		- Channel not open\n
+ *		- Already one GATT procedure is started
+ */
+tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle);
+
+/**
+ * @brief Start the procedure to read all the characteristics specified by the UUID.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * 		 Before procedure completion the response packets are given through
+ * 		 @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param start_handle Starting handle of the range to be searched
+ * @param end_handle End handle of the range to be searched
+ * @param uuid_type @arg @ref UUID_TYPE_16
+ *         			@arg @ref UUID_TYPE_128
+ * @param uuid 2 or 16 octet UUID
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+                                    uint8_t  uuid_type, uint8_t* uuid);
+
+/**
+ * @brief Start the procedure to read a long characteristic value.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * 		 Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the characteristic to be read
+ * @param val_offset Offset from which the value needs to be read
+ * @return Value indicating success or error code.\n
+ * 		 It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n
+ *		- If the exchange has already taken place\n
+ *		- If GATT is expecting response for previous request\n
+ *		- Already a request is in the queue to be sent\n
+ *		- Channel not open\n
+ *		- Already one GATT procedure is started
+ */
+tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle,
+					 uint16_t val_offset);
+
+/**
+ * @brief Start a procedure to read multiple characteristic values from a server.
+ * @note This sub-procedure is used to read multiple Characteristic Values from a server when the
+ *  	 client knows the Characteristic Value Handles.
+ *  	 When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ *  	 Before procedure completion the response packets are given through
+ *  	 @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param num_handles The number of handles for which the value has to be read
+ * @param set_of_handles The handles for which the attribute value has to be read
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, 
+                                             uint8_t* set_of_handles);
+
+/**
+ * @brief Start the procedure to write a characteristic value.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the characteristic to be written
+ * @param value_len Length of the value to be written
+ * @param[in] attr_value Value to be written
+ * @return Value indicating success or error code.\n
+ * 		 It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n
+ *		- If the exchange has already taken place\n
+ *		- If GATT is expecting response for previous request\n
+ *		- Already a request is in the queue to be sent\n
+ *		- Channel not open\n
+ *		- Already one GATT procedure is started
+ */
+tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle,
+				       uint8_t value_len, uint8_t *attr_value);
+
+/**
+ * @brief Start the procedure to write a long characteristic value.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * 		 During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP
+ * 		 events are raised.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute to be written
+ * @param val_offset Offset at which the attribute has to be written
+ * @param val_len Length of the value to be written
+ * @param attr_val Value to be written
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle,
+                                          uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val);
+
+/**
+ * @brief Start the procedure to write a characteristic reliably.
+ * @note When the procedure is completed, a  @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ *  	 During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP
+ * 		 events are raised.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute to be written
+ * @param val_offset Offset at which the attribute has to be written
+ * @param val_len Length of the value to be written
+ * @param attr_val Value to be written
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle,
+                                          uint16_t val_offset, uint8_t val_len, uint8_t* attr_val);
+
+/**
+ * @brief Start the procedure to write a long characteristic descriptor.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * 		 During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP
+ * 		 events are raised.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute to be written
+ * @param val_offset Offset at which the attribute has to be written
+ * @param val_len Length of the value to be written
+ * @param attr_val Value to be written
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle,
+                                          uint16_t val_offset, uint8_t val_len, uint8_t* attr_val);
+
+/**
+ * @brief Start the procedure to read a long characteristic value.
+ * @note  When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * 		  Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP
+ * 		  event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the characteristic descriptor
+ * @param val_offset Offset from which the value needs to be read
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle,
+                                          uint16_t val_offset);
+
+/**
+ * @brief Start the procedure to write a characteristic descriptor.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute to be written
+ * @param value_len Length of the value to be written
+ * @param[in] attr_value Value to be written
+ * @return Value indicating success or error code.\n
+ * 		 It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n
+ *		- If the exchange has already taken place\n
+ *		- If GATT is expecting response for previous request\n
+ *		- Already a request is in the queue to be sent\n
+ *		- Channel not open\n
+ *		- Already one GATT procedure is started
+ */
+tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle,
+					   uint8_t value_len, uint8_t *attr_value);
+
+/**
+ * @brief Start the procedure to read the descriptor specified.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * 		 Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the descriptor to be read
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle);
+
+/**
+ * @brief Start the procedure to write a characteristic value without waiting for any response from the server.
+ * @note No events are generated after this command is executed.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute to be written
+ * @param val_len Length of the value to be written (up to ATT_MTU - 3)
+ * @param[in] attr_val Value to be written
+ * @return Value indicating success or error code.\n
+ * 		 It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n
+ *		- If the exchange has already taken place\n
+ *		- If GATT is expecting response for previous request\n
+ *		- Already a request is in the queue to be sent\n
+ *		- Channel not open\n
+ *		- Already one GATT procedure is started
+ */
+tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle,
+                                              uint8_t val_len, const uint8_t* attr_val);
+
+/**
+ * @brief Start a signed write without response from the server.
+ * @note  The procedure i used to write a characteristic value with an authentication signature without waiting
+ * 		  for any response from the server. It cannot be used when the link is encrypted.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute to be written
+ * @param val_len Length of the value to be written (up to ATT_MTU - 13).
+ * @param attr_val Value to be written
+ * @return Value indicating success or error code
+ */
+tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle,
+                                              uint8_t val_len, uint8_t* attr_val);
+
+/**
+ * @brief Confirm an indication
+ * @note  This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION.
+ * @param conn_handle Connection handle for which the command is given.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle);
+
+/**
+ * @brief Allow or reject a write request from a client.
+ * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ.
+ *  	 If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed,
+ *  	 then the status has to be set to 1 and the error code has to be set to the error code that has to be
+ *  	 passed to the client.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ.
+ * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n
+ * 					   0x01: The value cannot be written to the attribute specified by the attr_handle.
+ * @param err_code  The error code that has to be passed to the client in case the write has to be rejected.
+ * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ.
+ * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_write_response(uint16_t conn_handle,
+                                   uint16_t attr_handle,
+                                   uint8_t write_status,
+                                   uint8_t err_code,
+                                   uint8_t att_val_len,
+                                   uint8_t *att_val);
+
+/**
+ * @brief Allow the GATT server to send a response to a read request from a client.
+ * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ
+ * 		 or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response
+ * 		 can be sent to the client. So if the application wishes to update any of the attributes before
+ * 		 they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value
+ * 		 and then give this command. The application should perform the required operations within 30 seconds,
+ * 		 otherwise the GATT procedure will go to timeout.
+ * @param conn_handle Connection handle for which the command is given.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_allow_read(uint16_t conn_handle);
+
+/**
+ * @brief Set the security permission for the attribute handle specified.
+ * @note  Currently the setting of security permission is allowed only for client configuration descriptor.
+ * @param service_handle Handle of the service which contains the attribute whose security
+ * 						 permission has to be modified.
+ * @param attr_handle	Handle of the attribute whose security permission has to be modified.
+ * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions".
+ * 			@arg ATTR_PERMISSION_NONE
+ * 			@arg ATTR_PERMISSION_AUTHEN_READ
+ * 			@arg ATTR_PERMISSION_AUTHOR_READ
+ * 			@arg ATTR_PERMISSION_ENCRY_READ
+ * 			@arg ATTR_PERMISSION_AUTHEN_WRITE
+ * 			@arg ATTR_PERMISSION_AUTHOR_WRITE
+ * 			@arg ATTR_PERMISSION_ENCRY_WRITE
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle,
+                                            uint8_t security_permission);
+
+/**
+ * @brief This command sets the value of the descriptor specified by charDescHandle.
+ * @param servHandle Handle of the service which contains the descriptor.
+ * @param charHandle Handle of the characteristic which contains the descriptor.
+ * @param charDescHandle Handle of the descriptor whose value has to be set.
+ * @param charDescValOffset Offset from which the descriptor value has to be updated.
+ * @param charDescValueLen Length of the descriptor value
+ * @param[in] charDescValue descriptor value
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_set_desc_value(uint16_t servHandle,
+				   uint16_t charHandle,
+				   uint16_t charDescHandle,
+				   uint16_t charDescValOffset,
+				   uint8_t charDescValueLen,
+				   const void *charDescValue);
+
+/**
+ * @brief Reads the value of the attribute handle specified from the local GATT database.
+ * @param attr_handle Handle of the attribute to read
+ * @param data_len Length of the data buffer.
+ * @param[out] data_len_out_p Length of the read attribute.
+ * @param[out] data Pointer to the buffer that will contain the read value.
+ * 				The buffer will be filled with the attribute value.
+ * 				The length will be the minimum between the provided data_len and the actual length of the
+ * 				attribute (in data_len_out_p).
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data);
+
+   /**
+ * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset.
+ * @param attr_handle Handle of the attribute to read
+ * @param offset      Offset from which the value needs to be read
+ * @param data_len    Length of the data buffer.
+ * @param[out] data_len_out_p Length of the read attribute.
+ * @param[out] data Pointer to the buffer that will contain the read value.
+ * 				The buffer will be filled with the attribute value.
+ * 				The length will be the minimum between the provided data_len and the actual length of the
+ * 				attribute (in data_len_out_p).
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data);
+/**
+ * @brief Update the value of a characteristic and sends notifications or indications.
+ * @note This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute
+ *  	 up to 512 bytes and indicate selectively the generation of indications and notifications.
+ * @param service_handle Handle of the service to which the characteristic belongs.
+ * @param char_handle Handle of the characteristic
+ * @param update_type Bitmask that controls generation of notifications and indications. It can be a combination
+ * 						@arg @ref NOTIFICATION (0x01): send notification, if enabled.
+ * 						@arg @ref INDICATION (0x02): send indication, if enabled.
+ * 					  If set to 0 no notifications or indications are sent.
+ * @param char_length Total length of the characteristic value. In case of a variable size characteristic,
+ * 					  this field specifies the new length of the characteristic value after the update;
+ * 					  in case of fixed length characteristic this field is ignored.
+ * @param value_offset The offset from which the attribute value has to be updated
+ * @param value_length Length of the value to be updated
+ * @param[out] value   Updated characteristic value
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle,
+                                                  uint8_t update_type, uint16_t char_length,
+                                                  uint16_t value_offset, uint8_t value_length,
+                                                  const uint8_t* value);
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup GATT_Events GATT events
+ * The structures are the data field of @ref evt_blue_aci.
+ * @{
+ */
+
+/**
+ * This event (if enabled, see @ref Gatt_Event_Mask "Gatt Event Mask") is raised to the application
+ * by the GATT server when a client modifies any attribute on the server, as consequence of one of
+ * the following GATT procedures:
+ * @li write without response
+ * @li signed write without response
+ * @li write characteristic value
+ * @li write long characteristic value
+ * @li reliable write.
+ * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1.
+ */
+#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED          (0x0C01)
+typedef __packed struct _evt_gatt_attr_modified_IDB05A1{
+  uint16_t conn_handle; /**< The connection handle which modified the attribute. */
+  uint16_t attr_handle; /**< Handle of the attribute that was modified. */
+  uint8_t  data_length; /**< The length of the data */
+  uint16_t  offset; /**< Offset from which the write has been performed by the peer device */
+  uint8_t  att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */
+} PACKED evt_gatt_attr_modified_IDB05A1;
+
+typedef __packed struct _evt_gatt_attr_modified_IDB04A1{
+  uint16_t conn_handle; /**< The connection handle which modified the attribute. */
+  uint16_t attr_handle; /**< Handle of the attribute that was modified. */
+  uint8_t  data_length; /**< The length of the data */
+  uint8_t  att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */
+} PACKED evt_gatt_attr_modified_IDB04A1;
+
+/**
+ * This event is generated by the client/server to the application on a GATT timeout (30 seconds).
+ * See @ref _evt_gatt_procedure_timeout.
+ */
+#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT           (0x0C02)
+typedef __packed struct _evt_gatt_procedure_timeout{
+	uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */
+} PACKED evt_gatt_procedure_timeout;
+
+/**
+ * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration().
+ * See @ref _evt_att_exchange_mtu_resp.
+ */
+#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP		  (0x0C03)
+typedef __packed struct _evt_att_exchange_mtu_resp{
+  uint16_t conn_handle; /**< The connection handle related to the response */
+  uint8_t  event_data_length; /**< Length of following data (always 1). */
+  uint16_t server_rx_mtu; /**< Attribute server receive MTU size */
+} PACKED evt_att_exchange_mtu_resp;
+
+/**
+ * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and
+ * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp.
+ */
+#define EVT_BLUE_ATT_FIND_INFORMATION_RESP	  (0x0C04)
+typedef __packed struct _evt_att_find_information_resp{
+  uint16_t conn_handle;			/**< The connection handle related to the response */
+  uint8_t  event_data_length;	/**< Length of following data. */
+  uint8_t  format;				/**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */
+  /**
+   *  A sequence of handle-uuid pairs.\n
+   *  @li if format=1, each pair is:\n
+   *  [2 octets for handle, 2 octets for UUIDs] \n
+   *  @li if format=2, each pair is:\n
+   *  [2 octets for handle, 16 octets for UUIDs]
+   */
+  uint8_t  handle_uuid_pair[VARIABLE_SIZE];
+} PACKED evt_att_find_information_resp;
+
+/**
+ * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See
+ * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp.
+ */
+#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP	  (0x0C05)
+typedef __packed struct _evt_att_find_by_type_val_resp{
+  uint16_t conn_handle;				/**< The connection handle related to the response */
+  uint8_t  event_data_length;		/**< Length of following data. */
+  /**
+   *  Handles Information List as defined in Bluetooth Core v4.0 spec.
+   *  A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle]
+   */
+  uint8_t  handles_info_list[VARIABLE_SIZE];
+} PACKED evt_att_find_by_type_val_resp;
+
+/**
+ * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and
+ * aci_gatt_disc_all_charac_of_serv().
+ * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp.
+ */
+#define EVT_BLUE_ATT_READ_BY_TYPE_RESP		  (0x0C06)
+typedef __packed struct _evt_att_read_by_type_resp{
+  uint16_t conn_handle;				/**< The connection handle related to the response */
+  uint8_t  event_data_length;		/**< Length of following data. */
+  uint8_t  handle_value_pair_length; /**< The size of each attribute handle-value pair */
+  /**
+   *  Attribute Data List as defined in Bluetooth Core v4.0 spec.
+   *  A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value]
+   */
+  uint8_t  handle_value_pair[VARIABLE_SIZE];
+} PACKED evt_att_read_by_type_resp;
+
+/**
+ * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val().
+ * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp.
+ */
+#define EVT_BLUE_ATT_READ_RESP			  (0x0C07)
+typedef __packed struct _evt_att_read_resp{
+  uint16_t conn_handle;				/**< The connection handle related to the response. */
+  uint8_t  event_data_length;		/**< Length of following data. */
+  uint8_t  attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */
+} PACKED evt_att_read_resp;
+
+/**
+ * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val().
+ * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp.
+ */
+#define EVT_BLUE_ATT_READ_BLOB_RESP		  (0x0C08)
+typedef __packed struct _evt_att_read_blob_resp{
+  uint16_t conn_handle;				/**< The connection handle related to the response. */
+  uint8_t  event_data_length;		/**< Length of following data. */
+  uint8_t  part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */
+} PACKED evt_att_read_blob_resp;
+
+/**
+ * This event is generated in response to a @a Read @a Multiple @a Request.
+ * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp.
+ */
+#define EVT_BLUE_ATT_READ_MULTIPLE_RESP		  (0x0C09)
+typedef __packed struct _evt_att_read_mult_resp{
+  uint16_t conn_handle;				/**< The connection handle related to the response. */
+  uint8_t  event_data_length;		/**< Length of following data. */
+  uint8_t  set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/
+} PACKED evt_att_read_mult_resp;
+
+/**
+ * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services().
+ * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp.
+ */
+#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP           (0x0C0A)
+typedef __packed struct _evt_att_read_by_group_resp{
+  uint16_t conn_handle;				/**< The connection handle related to the response. */
+  uint8_t  event_data_length;		/**< Length of following data. */
+  uint8_t  attribute_data_length;   /**< The size of each Attribute Data. */
+  /**
+   *  A list of Attribute Data where the attribute data is composed by:
+   *  @li 2 octets for Attribute Handle
+   *  @li 2 octets for End Group Handle
+   *  @li (attribute_data_length - 4) octets for Attribute Value
+   */
+  uint8_t  attribute_data_list[VARIABLE_SIZE];
+} PACKED evt_att_read_by_group_resp;
+
+/**
+ * This event is generated in response to a @a Prepare @a Write @a Request.
+ * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp.
+ */
+#define EVT_BLUE_ATT_PREPARE_WRITE_RESP		  (0x0C0C)
+typedef __packed struct _evt_att_prepare_write_resp{
+  uint16_t conn_handle;				/**< The connection handle related to the response. */
+  uint8_t  event_data_length;		/**< Length of following data. */
+  uint16_t  attribute_handle;		/**< The handle of the attribute to be written. */
+  uint16_t  offset;					/**< The offset of the first octet to be written. */
+  uint8_t  part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */
+} PACKED evt_att_prepare_write_resp;
+
+/**
+ * This event is generated in response to an @a Execute @a Write @a Request.
+ * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp.
+ */
+#define EVT_BLUE_ATT_EXEC_WRITE_RESP		  (0x0C0D)
+typedef __packed struct _evt_att_exec_write_resp{
+  uint16_t conn_handle;			/**< The connection handle related to the response. */
+  uint8_t  event_data_length; 	/**< Always 0. */
+} PACKED evt_att_exec_write_resp;
+
+/**
+ * This event is generated when an indication is received from the server.
+ * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication.
+ */
+#define EVT_BLUE_GATT_INDICATION		  (0x0C0E)
+typedef __packed struct _evt_gatt_indication{
+  uint16_t conn_handle;		  			/**< The connection handle related to the event. */
+  uint8_t  event_data_length; 			/**< Length of following data. */
+  uint16_t attr_handle;					/**< The handle of the attribute. */
+  uint8_t  attr_value[VARIABLE_SIZE]; 	/**< The current value of the attribute. */
+} PACKED evt_gatt_indication;
+
+/**
+ * This event is generated when a notification is received from the server.
+ * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification.
+ */
+#define EVT_BLUE_GATT_NOTIFICATION		  (0x0C0F)
+typedef __packed struct _evt_gatt_notification{
+  uint16_t conn_handle;					/**< The connection handle related to the event. */
+  uint8_t  event_data_length; 			/**< Length of following data. */
+  uint16_t attr_handle;					/**< The handle of the attribute. */
+  uint8_t  attr_value[VARIABLE_SIZE]; 	/**< The current value of the attribute. */
+} PACKED evt_gatt_attr_notification;
+
+/**
+ * This event is generated when a GATT client procedure completes either with error or successfully.
+ * See @ref _evt_gatt_procedure_complete.
+ */
+#define EVT_BLUE_GATT_PROCEDURE_COMPLETE          (0x0C10)
+typedef __packed struct _evt_gatt_procedure_complete{
+  uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */
+  uint8_t  data_length; /**< Length of error_code field (always 1). */
+  /**
+   * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS).
+   */
+  uint8_t  error_code;
+} PACKED evt_gatt_procedure_complete;
+
+/**
+ * This event is generated when an Error Response is received from the server. The error response can be given
+ * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended
+ * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp.
+ */
+#define EVT_BLUE_GATT_ERROR_RESP                  (0x0C11)
+typedef __packed struct _evt_gatt_error_resp{
+  uint16_t conn_handle;			/**< The connection handle related to the event. */
+  uint8_t  event_data_length;	/**< Length of following data. */
+  uint8_t  req_opcode;			/**< The request that generated this error response. */
+  uint16_t attr_handle;			/**< The attribute handle that generated this error response. */
+  uint8_t  error_code;			/**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec.  */
+} PACKED evt_gatt_error_resp;
+
+/**
+ * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using
+ * Characteristic UUID" procedure.
+ * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1),
+ * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a
+ * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp.
+ */
+#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12)
+typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{
+  uint16_t conn_handle;						/**< The connection handle related to the event. */
+  uint8_t  event_data_length;				/**< Length of following data. */
+  uint16_t attr_handle;						/**< The handle of the attribute. */
+  /**
+   * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1),
+   * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a
+   * "Read using Characteristic UUID" has been performed.
+   */
+  uint8_t  attr_value[VARIABLE_SIZE];
+} PACKED evt_gatt_disc_read_char_by_uuid_resp;
+
+/**
+ * This event is given to the application when a write request, write command or signed write command
+ * is received by the server from the client. This event will be given to the application only if the
+ * event bit for this event generation is set when the characteristic was added.
+ * When this event is received, the application has to check whether the value being requested for write
+ * is allowed to be written and respond with the command aci_gatt_write_response().
+ * If the write is rejected by the application, then the value of the attribute will not be modified.
+ * In case of a write request, an error response will be sent to the client, with the error code as specified by the application.
+ * In case of write/signed write commands, no response is sent to the client but the attribute is not modified.
+ * See @ref evt_gatt_write_permit_req.
+ */
+#define EVT_BLUE_GATT_WRITE_PERMIT_REQ            (0x0C13)
+typedef __packed struct _evt_gatt_write_permit_req{
+  uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */
+  uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */
+  uint8_t  data_length; /**< Length of data field. */
+  uint8_t  data[VARIABLE_SIZE]; /**< The data that the client has requested to write */
+} PACKED evt_gatt_write_permit_req;
+
+/**
+ * This event is given to the application when a read request or read blob request is received by the server
+ * from the client. This event will be given to the application only if the event bit for this event generation
+ * is set when the characteristic was added.
+ * On receiving this event, the application can update the value of the handle if it desires and when done
+ * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client.
+ * See @ref evt_gatt_read_permit_req.
+ *
+ */
+#define EVT_BLUE_GATT_READ_PERMIT_REQ             (0x0C14)
+typedef __packed struct _evt_gatt_read_permit_req{
+  uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */
+  uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */
+  uint8_t  data_length; /**< Length of offset field. */
+  uint16_t offset;      /**< Contains the offset from which the read has been requested */
+} PACKED evt_gatt_read_permit_req;
+
+/**
+ * This event is given to the application when a read multiple request or read by type request is received
+ * by the server from the client. This event will be given to the application only if the event bit for this
+ * event generation is set when the characteristic was added.
+ * On receiving this event, the application can update the values of the handles if it desires and when done
+ * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client.
+ * See @ref evt_gatt_read_multi_permit_req.
+ *
+ */
+#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ       (0x0C15)
+typedef __packed struct _evt_gatt_read_multi_permit_req{
+  uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */
+  uint8_t  data_length; /**< Length of data field. */
+  uint8_t  data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */
+} PACKED evt_gatt_read_multi_permit_req;
+
+/**
+ * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2).
+ * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES.
+ * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value().
+ * See @ref evt_gatt_tx_pool_vailable.
+ *
+ */
+#define EVT_BLUE_GATT_TX_POOL_AVAILABLE           (0x0C16)
+typedef __packed struct _evt_gatt_tx_pool_available{
+  uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */
+  uint16_t available_buffers; /**< Length of data field. */
+} PACKED evt_gatt_tx_pool_available;
+
+/**
+ * This event is raised on the server when the client confirms the reception of an indication.
+ */
+#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT    (0x0C17)
+typedef __packed struct _evt_gatt_server_confirmation{
+  uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */
+} PACKED evt_gatt_server_confirmation;
+/**
+ * This event is given to the application when a prepare write request
+ * is received by the server from the client. This event will be given to the application only if the
+ * event bit for this event generation is set when the characteristic was added.
+ * When this event is received, the application has to check whether the value being requested for write
+ * is allowed to be written and respond with the command aci_gatt_write_response().
+ * Based on the response from the application, the attribute value will be modified by the stack.
+ * If the write is rejected by the application, then the value of the attribute will not be modified
+ * and an error response will be sent to the client, with the error code as specified by the application.
+ * See @ref evt_gatt_write_permit_req.
+ */
+#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ            (0x0C18)
+typedef __packed struct _evt_gatt_prepare_write_permit_req{
+  uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */
+  uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */
+  uint16_t offset; /**< The offset from which the prepare write has been requested */
+  uint8_t  data_length; /**< Length of data field. */
+  uint8_t  data[VARIABLE_SIZE]; /**< The data that the client has requested to write */
+} PACKED evt_gatt_prepare_write_permit_req;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+ 
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,229 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : bluenrg_gatt_server.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : Header file for BlueNRG's GATT server layer.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BNRG_GATT_SERVER_H__
+#define __BNRG_GATT_SERVER_H__
+
+#include "ble_compiler.h"
+#include "ble_status.h"
+
+/**
+ *@addtogroup GATT GATT
+ *@{
+ */
+
+/**
+ * @anchor Well-Known_UUIDs
+ * @name Well-Known UUIDs
+ * @{
+ */
+#define PRIMARY_SERVICE_UUID                       (0x2800)
+#define SECONDARY_SERVICE_UUID                     (0x2801)
+#define INCLUDE_SERVICE_UUID                       (0x2802)
+#define CHARACTERISTIC_UUID                        (0x2803)
+#define CHAR_EXTENDED_PROP_DESC_UUID               (0x2900)
+#define CHAR_USER_DESC_UUID                        (0x2901)
+#define CHAR_CLIENT_CONFIG_DESC_UUID               (0x2902)
+#define CHAR_SERVER_CONFIG_DESC_UUID               (0x2903)
+#define CHAR_FORMAT_DESC_UUID                      (0x2904)
+#define CHAR_AGGR_FMT_DESC_UUID                    (0x2905)
+#define GATT_SERVICE_UUID                          (0x1801)
+#define GAP_SERVICE_UUID                           (0x1800)
+#define SERVICE_CHANGED_UUID                       (0x2A05)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Access_permissions
+ * @name Access permissions
+ * Access permissions for an attribute
+ * @{
+ */
+#define ATTR_NO_ACCESS                             (0x00)
+#define ATTR_ACCESS_READ_ONLY                      (0x01) 
+#define ATTR_ACCESS_WRITE_REQ_ONLY                 (0x02)
+#define ATTR_ACCESS_READ_WRITE                     (0x03)
+#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE         (0x04)
+#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED           (0x08)
+/**
+ * Allows all write procedures
+ */
+#define ATTR_ACCESS_WRITE_ANY                      (0x0E)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Char_properties
+ * @name Characteristic properties.
+ * @{
+ */
+#define CHAR_PROP_BROADCAST 					(0x01)
+#define CHAR_PROP_READ							(0x02)
+#define CHAR_PROP_WRITE_WITHOUT_RESP			(0x04)
+#define CHAR_PROP_WRITE			                (0x08)
+#define CHAR_PROP_NOTIFY			            (0x10)
+#define CHAR_PROP_INDICATE			            (0x20)
+#define CHAR_PROP_SIGNED_WRITE                  (0x40)
+#define CHAR_PROP_EXT           	            (0x80)
+/**
+ * @}
+ */
+
+
+/**
+ * @anchor Security_permissions
+ * @name Security permissions for an attribute.
+ * @{
+ */
+#define ATTR_PERMISSION_NONE                       (0x00) /**< No security. */
+#define ATTR_PERMISSION_AUTHEN_READ                (0x01) /**< Need authentication to read */
+#define ATTR_PERMISSION_AUTHOR_READ                (0x02) /**< Need authorization to read */
+#define ATTR_PERMISSION_ENCRY_READ                 (0x04) /**< Link must be encrypted to read */
+#define ATTR_PERMISSION_AUTHEN_WRITE               (0x08) /**< Need authentication to write */
+#define ATTR_PERMISSION_AUTHOR_WRITE               (0x10) /**< Need authorization to write */
+#define ATTR_PERMISSION_ENCRY_WRITE                (0x20) /**< Link must be encrypted for write */
+/**
+ * @}
+ */
+
+/**
+ * @anchor UUID_Types
+ * @name Type of UUID (16 bit or 128 bit).
+ * @{
+ */
+#define UUID_TYPE_16                               (0x01)
+#define UUID_TYPE_128                              (0x02)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Service_type
+ * @name Type of service (primary or secondary)
+ * @{
+ */
+#define PRIMARY_SERVICE                            (0x01)
+#define SECONDARY_SERVICE                          (0x02)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Gatt_Event_Mask
+ * @name Gatt Event Mask
+ * Type of event generated by GATT server
+ * @{
+ */
+#define GATT_DONT_NOTIFY_EVENTS                       (0x00) /**< Do not notify events. */
+#define GATT_NOTIFY_ATTRIBUTE_WRITE                   (0x01) /**< The application will be notified when a client writes to this attribute.
+                                                                  An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */
+#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP  (0x02) /**< The application will be notified when a write request, a write cmd
+                                                                    or a signed write cmd are received by the server for this attribute.
+                                                                    An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */
+#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP   (0x04) /**< The application will be notified when a read request of any type is
+                                                                  received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */
+/**
+ * @}
+ */
+
+/** 
+ * @name Type of characteristic length
+ * See aci_gatt_add_char()
+ * @{
+ */
+#define CHAR_VALUE_LEN_CONSTANT           (0x00)
+#define CHAR_VALUE_LEN_VARIABLE           (0x01)
+/**
+ * @}
+ */
+
+
+/**
+ * @name Encryption key size
+ * @{
+ */
+/**
+ * Minimum encryption key size
+ */
+#define MIN_ENCRY_KEY_SIZE                (7)
+
+/**
+ * Maximum encryption key size
+ */
+#define MAX_ENCRY_KEY_SIZE                (0x10)
+/**
+ * @}
+ */
+
+/**
+ * @name Characteristic Presentation Format
+ * @{
+ */
+typedef __packed struct _charactFormat {
+    uint8_t format;
+    int8_t exp;
+    uint16_t unit;
+    uint8_t name_space;
+    uint16_t desc;
+} PACKED charactFormat;
+
+/**
+ * @}
+ */
+
+/**
+ * @name Format
+ * @{
+ */
+#define FORMAT_UINT8         0x04
+#define FORMAT_UINT16        0x06
+#define FORMAT_SINT16        0x0E
+#define FORMAT_SINT24        0x0F
+/**
+ * @}
+ */
+
+/**
+ * @name Unit
+ * @{
+ */
+#define UNIT_UNITLESS        0x2700
+#define UNIT_TEMP_CELSIUS    0x272F
+#define UNIT_PRESSURE_BAR    0x2780
+/**
+ * @}
+ */
+
+
+/**
+ * ATT MTU size
+ */
+#define ATT_MTU       (23)
+
+/**
+ * @}
+ */
+
+ /**
+ * @name Update type of aci_gatt_upd_char_val_ext().
+ * @{
+ */
+
+#define NOTIFICATION         1
+#define INDICATION           2
+
+#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,385 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name          : bluenrg_hal_aci.h
+* Author             : AMS - AAS
+* Version            : V1.0.0
+* Date               : 26-Jun-2014
+* Description        : Header file with HCI commands for BlueNRG
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_HAL_ACI_H__
+#define __BLUENRG_HAL_ACI_H__
+
+/**
+ *@addtogroup HAL HAL
+ *@brief Hardware Abstraction Layer.
+ *@{
+ */
+
+/**
+ * @defgroup HAL_Functions HAL functions
+ * @brief API for BlueNRG HAL layer.
+ * @{
+ */
+
+/**
+ * @brief This command retrieves the buid number of the firmware.
+ * @param[out] build_number Build number identifying the firmware release.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number);
+
+/**
+ * @brief This command writes a value to a low level configure data structure.
+ * @note  It is useful to setup directly some low level parameters for the system at runtime.
+ * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n
+ * 				 See @ref Config_vals.
+ *
+ * @param len Length of data to be written
+ * @param[out] val Data to be written
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_write_config_data(uint8_t offset, 
+                                    uint8_t len,
+                                    const uint8_t *val);
+
+/**
+ * @brief This command requests the value in the low level configure data structure.
+ *        The number of read bytes changes for different Offset.
+ * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n
+ * 				 See @ref Config_vals.
+ * @param data_len Length of the data buffer
+ * @param[out] data_len_out_p length of the data returned by the read.
+ * @param[out] data Read data
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data);
+
+/**
+ * @brief This command sets the TX power level of the BlueNRG.
+ * @note  By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines
+ *        the output power level (dBm).
+ *        When the system starts up or reboots, the default TX power level will be used, which is
+ *        the maximum value of 8dBm. Once this command is given, the output power will be changed
+ *        instantly, regardless if there is Bluetooth communication going on or not. For example,
+ *        for debugging purpose, the BlueNRG can be set to advertise all the time and use this
+ *        command to observe the signal strength changing. The system will keep the last received
+ *        TX power level from the command, i.e. the 2nd command overwrites the previous TX power
+ *        level. The new TX power level remains until another Set TX Power command, or the system
+ *        reboots.\n
+ * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the
+ * 						right value, depending on the selected hardware configuration for the RF network:
+ * 						normal mode or high power mode.
+ * @param pa_level Can be from 0 to 7. Set the PA level value.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level);
+
+/**
+ * @brief This command returns the number of packets sent in Direct Test Mode.
+ * @note  When the Direct TX test is started, a 32-bit counter is used to count how many packets
+ *        have been transmitted. This command can be used to check how many packets have been sent
+ *        during the Direct TX test.\n
+ *        The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again.
+ *        The counter is not cleared until the next Direct TX test starts.
+ * @param[out] number_of_packets Number of packets sent during the last Direct TX test.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets);
+
+/**
+ * @brief Put the device in standby mode.
+ * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the
+ * 		 device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode,
+ * 		 the device can still wake up itself with the internal timer. But in standby mode, this timer is
+ * 		 disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command
+ * 		 sent via SPI bus.
+ * 		 The command is only accepted when there is no other Bluetooth activity. Otherwise an error code
+ * 		 ERR_COMMAND_DISALLOWED will be returned.
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_device_standby(void);
+
+/**
+ * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel.
+ * @note  The frequency sine wave at the specific channel may be used for test purpose only.
+ * 		  The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc.
+ * 		  This command shouldn't be used when normal Bluetooth activities are ongoing.
+ * 		  The tone should be stopped by aci_hal_tone_stop() command.
+ *
+ * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the
+ * 					 channel central frequency minus 250 kHz.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_tone_start(uint8_t rf_channel);
+
+/**
+ * This command is used to stop the previously started aci_hal_tone_start() command.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_tone_stop(void);
+
+/**
+ * @brief This command returns the status of all the connections.
+ * @note  This command returns the status of the 8 Bluetooth low energy links managed by the device.
+ * @param[out] link_status Array of link status (8 links). See @ref Link_Status.
+ * @param[out] conn_handle Array of connection handles for each link.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]);
+
+/**
+ * @brief This command returns the anchor period and the largest available slot.
+ * @note  This command returns information about the anchor period to help application in selecting
+ * 		  slot timings when operating in multi-link scenarios.
+ * @param anchor_period Current anchor period (multiple of 0.625 ms).
+ * @param max_free_slot Maximum available time (multiple of 0.625 ms) that can be allocated for a new slot.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup HAL_Events HAL events
+ * The structures are the data field of @ref evt_blue_aci.
+ * @{
+ */
+
+/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */
+#define EVT_BLUE_HAL_INITIALIZED                 (0x0001)
+typedef __packed struct _evt_hal_initialized{
+  uint8_t reason_code; /**< Reset reason. See @ref Reset_Reasons */
+} PACKED evt_hal_initialized;
+
+/**
+ * This event is generated when an overflow occurs in the event queue read by the external microcontroller.
+ * This is normally caused when the external microcontroller does not read pending events.
+ * The returned bitmap indicates which event has been lost. Please note that one bit set to 1 indicates one or
+ * more occurrences of the particular events. The event EVT_BLUE_HAL_EVENTS_LOST cannot be lost and it will
+ * be inserted in the event queue as soon as a position is freed in the event queue. This event should not
+ * happen under normal operating condition where external microcontroller promptly reads events signaled by
+ * IRQ pin. It is provided to detected unexpected behavior of the external microcontroller or to allow
+ * application to recover situations where critical events are lost.
+ */
+#define EVT_BLUE_HAL_EVENTS_LOST_IDB05A1                (0x0002)
+typedef __packed struct _evt_hal_events_lost{
+  uint8_t  lost_events[8]; /**< Bitmap of lost events. Each bit indicates one or more occurrences of the specific event. See @ref Lost_Events */
+} PACKED evt_hal_events_lost_IDB05A1;
+
+
+/**
+ * This event is given to the application after the @ref ACI_BLUE_INITIALIZED_EVENT
+ * when a system crash is detected. This events returns system crash information for debugging purposes.
+ * Information reported are useful to understand the root cause of the crash.
+ */
+#define EVT_BLUE_HAL_CRASH_INFO_IDB05A1                 (0x0003)
+typedef __packed struct _evt_hal_crash_info{
+  uint8_t  crash_type; /**< Type of crash: Assert failed (0), NMI Fault (1), Hard Fault (2)  */
+  uint32_t sp; /**< SP register */
+  uint32_t r0; /**< R0 register  */
+  uint32_t r1; /**< R1 register  */
+  uint32_t r2; /**< R2 register  */
+  uint32_t r3; /**< R3 register  */
+  uint32_t r12; /**< R12 register  */
+  uint32_t lr; /**< LR register  */
+  uint32_t pc; /**< PC register  */
+  uint32_t xpsr; /**< xPSR register  */
+  uint8_t  debug_data_len; /**< length of debug_data field  */
+  uint8_t  debug_data[VARIABLE_SIZE]; /**< Debug data */  
+} PACKED evt_hal_crash_info_IDB05A1;
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @anchor Reset_Reasons
+ * @name Reset Reasons
+ * See @ref EVT_BLUE_HAL_INITIALIZED.
+ * @{
+ */
+#define RESET_NORMAL            1 /**< Normal startup. */
+#define RESET_UPDATER_ACI       2 /**< Updater mode entered with ACI command */
+#define RESET_UPDATER_BAD_FLAG  3 /**< Updater mode entered due to a bad BLUE flag */
+#define RESET_UPDATER_PIN       4 /**< Updater mode entered with IRQ pin */
+#define RESET_WATCHDOG          5 /**< Reset caused by watchdog */
+#define RESET_LOCKUP            6 /**< Reset due to lockup */
+#define RESET_BROWNOUT          7 /**< Brownout reset */
+#define RESET_CRASH             8 /**< Reset caused by a crash (NMI or Hard Fault) */
+#define RESET_ECC_ERR           9 /**< Reset caused by an ECC error */
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Config_vals Offsets and lengths for configuration values.
+ * @brief Offsets and lengths for configuration values.
+ * 		  See aci_hal_write_config_data().
+ * @{
+ */
+
+/**
+ * @name Configuration values.
+ * See @ref aci_hal_write_config_data().
+ * @{
+ */
+#define CONFIG_DATA_PUBADDR_OFFSET          (0x00) /**< Bluetooth public address */
+#define CONFIG_DATA_DIV_OFFSET              (0x06) /**< DIV used to derive CSRK */
+#define CONFIG_DATA_ER_OFFSET               (0x08) /**< Encryption root key used to derive LTK and CSRK */
+#define CONFIG_DATA_IR_OFFSET               (0x18) /**< Identity root key used to derive LTK and CSRK */
+#define CONFIG_DATA_LL_WITHOUT_HOST         (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host.
+ 	 	 	 	 	 	 	 	 	 	 	 	 	 It can be written only if aci_hal_write_config_data() is the first command 	 	 	 	 	 	 	 	 	 	 	 	 after reset. */
+#define CONFIG_DATA_RANDOM_ADDRESS          (0x80) /**< Stored static random address. Read-only. */
+
+/**
+ * Select the BlueNRG mode configurations.\n
+ * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB)
+ * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB)
+ * @li Mode 3: master/slave, 8 connections, RAM1 and RAM2.
+ * @li Mode 4: master/slave, 4 connections, RAM1 and RAM2 simultaneous scanning and advertising.
+ */
+#define CONFIG_DATA_MODE_OFFSET 			(0x2D)
+
+#define CONFIG_DATA_WATCHDOG_DISABLE 		(0x2F) /**< Set to 1 to disable watchdog. It is enabled by default. */
+/**
+ * @}
+ */
+
+/**
+ * @name Length for configuration values.
+ * See @ref aci_hal_write_config_data().
+ * @{
+ */
+#define CONFIG_DATA_PUBADDR_LEN             (6)
+#define CONFIG_DATA_DIV_LEN                 (2)
+#define CONFIG_DATA_ER_LEN                  (16)
+#define CONFIG_DATA_IR_LEN                  (16)
+#define CONFIG_DATA_LL_WITHOUT_HOST_LEN     (1)
+#define CONFIG_DATA_MODE_LEN                (1)
+#define CONFIG_DATA_WATCHDOG_DISABLE_LEN    (1)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Link_Status
+ * @name Status of the link
+ * See @ref aci_hal_get_link_status().
+ * @{
+ */
+#define STATUS_IDLE                         0
+#define STATUS_ADVERTISING                  1
+#define STATUS_CONNECTED_AS_SLAVE           2
+#define STATUS_SCANNING                     3
+#define STATUS_CONNECTED_AS_MASTER          5
+#define STATUS_TX_TEST                      6
+#define STATUS_RX_TEST                      7
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+ /**
+ * @anchor Lost_Events
+ * @name Lost events bitmap
+ * See @ref EVT_BLUE_HAL_EVENTS_LOST.
+ * @{
+ */   
+#define EVT_DISCONN_COMPLETE_BIT                                     0
+#define EVT_ENCRYPT_CHANGE_BIT                                       1
+#define EVT_READ_REMOTE_VERSION_COMPLETE_BIT                         2
+#define EVT_CMD_COMPLETE_BIT                                         3
+#define EVT_CMD_STATUS_BIT                                           4
+#define EVT_HARDWARE_ERROR_BIT                                       5
+#define EVT_NUM_COMP_PKTS_BIT                                        6
+#define EVT_ENCRYPTION_KEY_REFRESH_BIT                               7
+#define EVT_BLUE_HAL_INITIALIZED_BIT                                 8
+#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE_BIT                    9
+#define EVT_BLUE_GAP_PAIRING_CMPLT_BIT                               10
+#define EVT_BLUE_GAP_PASS_KEY_REQUEST_BIT                            11
+#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST_BIT                       12
+#define EVT_BLUE_GAP_SECURITY_REQ_INITIATED_BIT                      13
+#define EVT_BLUE_GAP_BOND_LOST_BIT                                   14
+#define EVT_BLUE_GAP_PROCEDURE_COMPLETE_BIT                          15
+#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_BIT                           16
+#define EVT_BLUE_L2CAP_CONN_UPDATE_RESP_BIT                          17
+#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT_BIT                         18
+#define EVT_BLUE_L2CAP_CONN_UPDATE_REQ_BIT                           19
+#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_BIT                         20
+#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT_BIT                          21
+#define EVT_BLUE_EXCHANGE_MTU_RESP_BIT                               22
+#define EVT_BLUE_ATT_FIND_INFORMATION_RESP_BIT                       23
+#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP_BIT                       24
+#define EVT_BLUE_ATT_READ_BY_TYPE_RESP_BIT                           25
+#define EVT_BLUE_ATT_READ_RESP_BIT                                   26
+#define EVT_BLUE_ATT_READ_BLOB_RESP_BIT                              27
+#define EVT_BLUE_ATT_READ_MULTIPLE_RESP_BIT                          28
+#define EVT_BLUE_ATT_READ_BY_GROUP_RESP_BIT                          29
+#define EVT_BLUE_ATT_WRITE_RESP_BIT                                  30
+#define EVT_BLUE_ATT_PREPARE_WRITE_RESP_BIT                          31
+#define EVT_BLUE_ATT_EXEC_WRITE_RESP_BIT                             32
+#define EVT_BLUE_GATT_INDICATION_BIT                                 33
+#define EVT_BLUE_GATT_NOTIFICATION_BIT                               34
+#define EVT_BLUE_GATT_PROCEDURE_COMPLETE_BIT                         35
+#define EVT_BLUE_GATT_ERROR_RESP_BIT                                 36
+#define EVT_BLUE_GATT_DISC_READ_CHARAC_BY_UUID_RESP_BIT              37
+#define EVT_BLUE_GATT_WRITE_PERMIT_REQ_BIT                           38
+#define EVT_BLUE_GATT_READ_PERMIT_REQ_BIT                            39
+#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ_BIT                      40
+#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_BIT                          41
+#define EVT_BLUE_GATT_SERVER_RX_CONFIRMATION_BIT                     42
+#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ_BIT                   43
+#define EVT_LL_CONNECTION_COMPLETE_BIT                               44
+#define EVT_LL_ADVERTISING_REPORT_BIT                                45
+#define EVT_LL_CONNECTION_UPDATE_COMPLETE_BIT                        46
+#define EVT_LL_READ_REMOTE_USED_FEATURES_BIT                         47
+#define EVT_LL_LTK_REQUEST_BIT                                       48   
+/**
+ * @}
+ */
+
+/**
+ * @name Hardware error event codes
+ * See @ref EVT_HARDWARE_ERROR.
+ * @{
+ */
+/**
+ * Error on the SPI bus has been detected, most likely caused by incorrect SPI configuration on the external micro-controller.
+ */
+#define SPI_FRAMING_ERROR           0
+/**
+ * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME
+ * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device.
+ */
+#define RADIO_STATE_ERROR           1
+/**
+ * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME
+ * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device.
+ */
+#define TIMER_OVERRUN_ERROR         2 
+   
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,166 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name          : bluenrg_l2cap_aci.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 26-Jun-2014
+* Description        : Header file with L2CAP commands for BlueNRG FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_L2CAP_ACI_H__
+#define __BLUENRG_L2CAP_ACI_H__
+
+/**
+ *@addtogroup L2CAP L2CAP
+ *@brief L2CAP layer.
+ *@{
+ */
+
+/**
+ *@defgroup L2CAP_Functions L2CAP functions
+ *@brief API for L2CAP layer.
+ *@{
+ */
+
+/**
+ * @brief Send an L2CAP Connection Parameter Update request from the slave to the master.
+ * @note  An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request
+ * 		  (accepts or rejects).
+ * @param conn_handle Connection handle on which the connection parameter update request has to be sent.
+ * @param interval_min Defines minimum value for the connection event interval in the following manner:
+ *						connIntervalMin = interval_min x 1.25ms
+ * @param interval_max Defines maximum value for the connection event interval in the following manner:
+ * 						connIntervalMax = interval_max x 1.25ms
+ * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped).
+ * @param timeout_multiplier Defines connection timeout parameter in the following manner:
+ * 							 timeout_multiplier x 10ms.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min,
+							 uint16_t interval_max, uint16_t slave_latency,
+							 uint16_t timeout_multiplier);
+/**
+ * @brief Accept or reject a connection update.
+ * @note  This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller.
+ * 		  The accept parameter has to be set if the connection parameters given in the event are acceptable.
+ * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event.
+ * @param interval_min The connection interval parameter as received in the l2cap connection update request event
+ * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event.
+ * @param slave_latency The slave latency parameter as received in the l2cap connection update request event.
+ * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event.
+ * @param min_ce_length Minimum length of connection event needed for the LE connection.\n
+ * 						Range: 0x0000 - 0xFFFF\n
+ * 						Time = N x 0.625 msec.
+ * @param max_ce_length Maximum length of connection event needed for the LE connection.\n
+ * 						Range: 0x0000 - 0xFFFF\n
+ * 						Time = N x 0.625 msec.
+ * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event.
+ * @param accept @arg 0x00: The connection update parameters are not acceptable.
+ *               @arg 0x01: The connection update parameters are acceptable.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min,
+							 uint16_t interval_max, uint16_t slave_latency,
+							 uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length,
+                                                         uint8_t id, uint8_t accept);
+ /**
+ * @brief Accept or reject a connection update.
+ * @note  This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller.
+ * 		  The accept parameter has to be set if the connection parameters given in the event are acceptable.
+ * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event.
+ * @param interval_min The connection interval parameter as received in the l2cap connection update request event
+ * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event.
+ * @param slave_latency The slave latency parameter as received in the l2cap connection update request event.
+ * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event.
+ * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event.
+ * @param accept @arg 0x00: The connection update parameters are not acceptable.
+ *               @arg 0x01: The connection update parameters are acceptable.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min,
+							 uint16_t interval_max, uint16_t slave_latency,
+							 uint16_t timeout_multiplier, uint8_t id, uint8_t accept);
+
+/**
+ * @}
+ */
+   
+/**
+ * @defgroup L2CAP_Events L2CAP events
+ * @{
+ */
+
+/**
+ * This event is generated when the master responds to the L2CAP connection update request packet.
+ * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec.
+ */
+#define EVT_BLUE_L2CAP_CONN_UPD_RESP		  (0x0800)
+typedef __packed struct _evt_l2cap_conn_upd_resp{
+  uint16_t conn_handle;         /**< The connection handle related to the event. */
+  uint8_t  event_data_length;  /**< Length of following data. */
+/**
+ * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet.
+ * @li 0x01 in case of Command Reject.
+ */
+  uint8_t  code;
+  uint8_t  identifier;    /**< Identifier of the response. It is equal to the request. */
+  uint16_t l2cap_length;  /**< Length of following data. It should always be 2 */
+/**
+ * Result code (parameters accepted or rejected) in case of Connection Parameter Update
+ * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01).
+ */
+  uint16_t result;
+} PACKED evt_l2cap_conn_upd_resp;
+
+/**
+ * This event is generated when the master does not respond to the connection update request
+ * within 30 seconds.
+ */
+#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT      (0x0801)
+typedef __packed struct _evt_l2cap_procedure_timeout{
+  uint16_t conn_handle;         /**< The connection handle related to the event. */
+  uint8_t  event_data_length;  /**< Length of following data. It should be always 0 for this event. */
+} PACKED evt_l2cap_procedure_timeout;
+
+/**
+ * The event is given by the L2CAP layer when a connection update request is received from the slave.
+ * The application has to respond by calling aci_l2cap_connection_parameter_update_response().
+ */
+#define EVT_BLUE_L2CAP_CONN_UPD_REQ		  	  (0x0802)
+typedef __packed struct _evt_l2cap_conn_upd_req{
+/**
+ * Handle of the connection for which the connection update request has been received.
+ * The same handle has to be returned while responding to the event with the command
+ * aci_l2cap_connection_parameter_update_response().
+ */
+  uint16_t conn_handle; 
+  uint8_t  event_data_length; /**< Length of following data. */
+/**
+ * This is the identifier which associates the request to the
+ * response. The same identifier has to be returned by the upper
+ * layer in the command aci_l2cap_connection_parameter_update_response().
+ */
+  uint8_t  identifier; 
+  uint16_t l2cap_length;  /**< Length of the L2CAP connection update request. */
+  uint16_t interval_min;  /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */
+  uint16_t interval_max;  /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */
+  uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */
+  uint16_t timeout_mult;  /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */
+} PACKED evt_l2cap_conn_upd_req;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,78 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name          : bluenrg_updater_aci.h
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 26-Jun-2014
+* Description        : Header file with updater commands for BlueNRG FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_UPDATER_ACI_H__
+#define __BLUENRG_UPDATER_ACI_H__
+
+#include <ble_compiler.h>
+
+/**
+ * @defgroup Updater Updater
+ * @brief Updater.
+ * @{
+ */
+
+/**
+ * @defgroup Updater_Functions Updater functions
+ * @brief API for BlueNRG Updater.
+ * @{
+ */
+
+tBleStatus aci_updater_start(void);
+
+tBleStatus aci_updater_reboot(void);
+
+tBleStatus aci_get_updater_version(uint8_t *version);
+
+tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size);
+
+tBleStatus aci_erase_blue_flag(void);
+
+tBleStatus aci_reset_blue_flag(void);
+
+tBleStatus aci_updater_erase_sector(uint32_t address);
+
+tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data);
+
+tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data);
+
+tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc);
+
+tBleStatus aci_updater_hw_version(uint8_t *version);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Updater_Events Updater events
+ * @{
+ */
+/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */
+#define EVT_BLUE_INITIALIZED                      (0x0001)
+typedef __packed struct _evt_blue_initialized{
+  uint8_t reason_code;
+} PACKED evt_blue_initialized;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+
+#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,204 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name          : bluenrg_utils.h
+* Author             : AMS - VMA, RF Application Team
+* Version            : V1.0.1
+* Date               : 03-October-2014
+* Description        : Header file for BlueNRG utility functions 
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+/**
+ * @file  bluenrg_utils.h
+ * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description
+ *
+ * <!-- Copyright 2014 by STMicroelectronics.  All rights reserved.       *80*-->
+**/
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __BLUENRG_UTILS_H
+#define __BLUENRG_UTILS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ble_hal_types.h" 
+#include "ble_compiler.h"
+
+/* Exported types ------------------------------------------------------------*/
+typedef struct{
+  uint8_t stack_mode;
+  uint8_t day;
+  uint8_t month;
+  uint8_t year;
+  uint16_t slave_sca_ppm;
+  uint8_t master_sca;
+  uint16_t hs_startup_time; /* In system time units*/
+} IFR_config2_TypeDef;
+
+/**
+ * Structure inside IFR for configuration options. 
+ */
+typedef __packed struct{
+  uint8_t cold_ana_act_config_table[64];
+  uint8_t hot_ana_config_table[64];
+  uint8_t stack_mode;
+  uint8_t gpio_config;
+  uint8_t rsrvd1[2];
+  uint32_t rsrvd2[3];
+  uint32_t max_conn_event_time;
+  uint32_t ls_crystal_period;
+  uint32_t ls_crystal_freq;
+  uint16_t slave_sca_ppm;
+  uint8_t master_sca;
+  uint8_t rsrvd3;
+  uint16_t hs_startup_time; /* In system time units*/
+  uint8_t rsrvd4[2];
+  uint32_t uid;
+  uint8_t rsrvd5;
+  uint8_t year;  
+  uint8_t month;
+  uint8_t day;
+  uint32_t unused[5];
+} PACKED IFR_config_TypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+extern const IFR_config_TypeDef IFR_config;
+
+/* Exported macros -----------------------------------------------------------*/
+#define FROM_US_TO_SYS_TIME(us)      ((uint16_t)(us/2.4414)+1)
+#define FROM_SYS_TIME_TO_US(sys)     ((uint16_t)(sys*2.4414))
+
+/* Convert 2 digit BCD number to an integer */
+#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10)
+
+/* Convert 2 digit number to a BCD number */
+#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10)
+
+/** 
+  * Return values 
+  */ 
+#define BLE_UTIL_SUCCESS                 0
+#define BLE_UTIL_UNSUPPORTED_VERSION     1
+#define BLE_UTIL_WRONG_IMAGE_SIZE        2
+#define BLE_UTIL_ACI_ERROR               3
+#define BLE_UTIL_CRC_ERROR               4
+#define BLE_UTIL_PARSE_ERROR             5
+#define BLE_UTIL_WRONG_VERIFY            6
+
+/* Exported functions ------------------------------------------------------- */ 
+/**
+  * @brief  Flash a new firmware using internal bootloader.
+  * @param  fw_image     Pointer to the firmware image (raw binary data,
+  *                      little-endian).
+  * @param  fw_size      Size of the firmware image. The firmware image size shall
+  *                      be multiple of 4 bytes.
+  * @retval int      It returns 0 if successful, or a number not equal to 0 in
+  *                  case of error (ACI_ERROR, UNSUPPORTED_VERSION,
+  *                  WRONG_IMAGE_SIZE, CRC_ERROR)
+  */
+int program_device(const uint8_t *fw_image, uint32_t fw_size);
+
+/**
+  * @brief  Read raw data from IFR (3 64-bytes blocks).
+  * @param  data     Pointer to the buffer that will contain the read data.
+  *                  Its size must be 192 bytes. This data can be parsed by
+  *                  parse_IFR_data_config().
+  * @retval int      It returns 0 if successful, or a number not equal to 0 in
+  *                  case of error (ACI_ERROR, UNSUPPORTED_VERSION)
+  */
+int read_IFR(uint8_t data[192]);
+
+/**
+  * @brief  Verify raw data from IFR (3 64-bytes blocks).
+  * @param  ifr_data Pointer to the buffer that will contain the data to verify.
+  *                  Its size must be 192 bytes.
+  * @retval int      It returns 0 if successful, or a number not equal to 0 in
+                     case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY)
+  */
+uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data);
+
+/**
+  * @brief  Program raw data to IFR (3 64-bytes blocks).
+  * @param  ifr_image     Pointer to the buffer that will contain the data to program.
+  *                  Its size must be 192 bytes.
+  * @retval int      It returns 0 if successful
+  */
+int program_IFR(const IFR_config_TypeDef *ifr_image);
+
+/**
+  * @brief  Parse IFR raw data.
+  * @param  data     Pointer to the raw data: last 64 bytes read from IFR sector.
+  * @param  IFR_config     Data structure that will be filled with parsed data.
+  * @retval None
+  */
+void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config);
+
+/**
+  * @brief  Check for the correctness of parsed data.
+  * @param  IFR_config     Data structure filled with parsed data.
+  * @retval int      It returns 0 if successful, or PARSE_ERROR in case data is
+  *                  not correct.
+  */
+int IFR_validate(IFR_config2_TypeDef *IFR_config);
+
+/**
+  * @brief  Modify IFR data. (Last 64-bytes block).
+  * @param  IFR_config   Structure that contains the new parameters inside the
+  *                      IFR configuration data.
+  * @note   It is highly recommended to parse the IFR configuration from
+  *         a working IFR block (this should be done with parse_IFR_data_config()).
+  *         Then it is possible to write the new parameters inside the IFR_config
+  *         structure.
+  * @param  data     Pointer to the buffer that contains the original data. It
+  *                  will be modified according to the new data in the IFR_config
+  *                  structure. Then this data must be written in the last
+  *                  64-byte block in the IFR.
+  *                  Its size must be 64 bytes.
+  * @retval None
+  */
+void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]);
+
+/**
+  * @brief  Get BlueNRG hardware and firmware version
+  * @param  hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31).
+  * @param  fwVersion This parameter returns the Firmware Version in the format 0xJJMN
+  *                   where JJ = Major Version number, M = Minor Version number and N = Patch Version number.
+  * @retval Status of the call
+  */
+uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion);
+
+/**
+  * @brief  Get BlueNRG updater version
+  * @param  version This parameter returns the updater version. If the updadter version is 0x03 
+  *                 the chip has the updater old, needs to update the bootloader.
+  * @retval Status of the call
+  */
+uint8_t getBlueNRGUpdaterVersion(uint8_t *version);
+
+/**
+  * @brief  Get BlueNRG HW version in bootloader mode
+  * @param  version This parameter returns the updater HW version.
+  * @retval Status of the call
+  */
+uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version);
+
+/**
+  * @brief  Verifies if the bootloader is patched or not. This function shall be used to fix a bug on
+  *         the HW bootloader related to the 32 MHz external crystal oscillator.
+  * @retval TRUE if the HW bootloader is already patched, FALSE otherwise
+  */
+uint8_t isHWBootloader_Patched(void);
+   
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__BLUENRG_UTILS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,77 @@
+/**
+  ******************************************************************************
+  * @file    bluenrg_targets.h
+  * @author  AST / EST
+  * @version V0.0.1
+  * @date    24-July-2015
+  * @brief   This header file is intended to manage the differences between 
+  *          the different supported base-boards which might mount the
+  *          X_NUCLEO_IDB0XA1 BlueNRG BLE Expansion Board.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+ 
+/* Define to prevent from recursive inclusion --------------------------------*/
+#ifndef _BLUENRG_TARGETS_H_
+#define _BLUENRG_TARGETS_H_
+ 
+#if !defined(BLUENRG_PIN_SPI_MOSI)
+#define BLUENRG_PIN_SPI_MOSI   (D11)
+#endif
+#if !defined(BLUENRG_PIN_SPI_MISO)
+#define BLUENRG_PIN_SPI_MISO   (D12)
+#endif
+#if !defined(BLUENRG_PIN_SPI_nCS)
+#define BLUENRG_PIN_SPI_nCS    (A1)
+#endif
+#if !defined(BLUENRG_PIN_SPI_RESET)
+#define BLUENRG_PIN_SPI_RESET  (D7)
+#endif
+#if !defined(BLUENRG_PIN_SPI_IRQ)
+#define BLUENRG_PIN_SPI_IRQ    (A0)
+#endif
+
+/* NOTE: Refer to README for further details regarding BLUENRG_PIN_SPI_SCK */
+#if !defined(BLUENRG_PIN_SPI_SCK)
+#define BLUENRG_PIN_SPI_SCK    (D3)
+#endif
+
+/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv)
+ *       Mode 0x01: slave or master, 1 connection
+ *       Mode 0x02: slave or master, 1 connection
+ *       Mode 0x03: master/slave, 8 connections
+ *       Mode 0x04: master/slave, 4 connections (simultaneous scanning and advertising)
+ *       Check Table 285 of 
+ *       BlueNRG-MS Bluetooth LE stack application command interface (ACI) User Manual (UM1865) at st.com
+ */
+#if !defined(BLUENRG_STACK_MODE)
+#define BLUENRG_STACK_MODE (0x04)
+#endif
+
+#endif // _BLUENRG_TARGTES_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,62 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef _BTLE_H_
+#define _BTLE_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "ble_hci.h"
+#include "ble_hci_le.h"
+#include "bluenrg_aci.h"
+#include "ble_hci_const.h"
+#include "bluenrg_hal_aci.h"
+#include "stm32_bluenrg_ble.h"
+#include "bluenrg_gap.h"
+#include "bluenrg_gatt_server.h"
+
+extern uint16_t g_gap_service_handle;
+extern uint16_t g_appearance_char_handle;
+extern uint16_t g_device_name_char_handle;
+extern uint16_t g_preferred_connection_parameters_char_handle;
+
+void btleInit(void);
+void SPI_Poll(void);
+void User_Process(void);
+void setConnectable(void);
+void setVersionString(uint8_t hwVersion, uint16_t fwVersion);
+const char* getVersionString(void);
+tBleStatus btleStartRadioScan(uint8_t scan_type,
+                              uint16_t scan_interval,
+                              uint16_t scan_window,
+                              uint8_t own_address_type);
+
+
+extern int btle_handler_pending;
+extern void btle_handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,104 @@
+/**
+  ******************************************************************************
+  * @file    stm32_bluenrg_ble.h
+  * @author  CL
+  * @version V1.0.1
+  * @date    15-June-2014
+  * @brief   
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+  
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32_BLUENRG_BLE_H
+#define __STM32_BLUENRG_BLE_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 	 
+	 
+
+#include <stdint.h>
+#include "ble_gp_timer.h"
+#include "ble_hal.h"
+
+/** @addtogroup BSP
+ *  @{
+ */
+
+/** @addtogroup X-NUCLEO-IDB04A1
+ *  @{
+ */
+ 
+/** @addtogroup STM32_BLUENRG_BLE
+ *  @{
+ */
+
+/** @defgroup STM32_BLUENRG_BLE_Exported_Functions 
+ * @{
+ */
+  
+// FIXME: add prototypes for BlueNRG here
+void BlueNRG_RST(void);
+uint8_t BlueNRG_DataPresent(void);
+void    BlueNRG_HW_Bootloader(void);
+int32_t BlueNRG_SPI_Read_All(uint8_t *buffer,
+                             uint8_t buff_size);
+int32_t BlueNRG_SPI_Write(uint8_t* data1,
+                          uint8_t* data2,
+                          uint8_t Nb_bytes1,
+                          uint8_t Nb_bytes2);
+void Clear_SPI_EXTI_Flag(void);
+
+void print_csv_time(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+ 
+/**
+ * @}
+ */
+ 
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32_BLUENRG_BLE_H */
+    
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,195 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif 
+#include "ble_debug.h"
+
+#ifndef __PAYLOAD_H__
+#define __PAYLOAD_H__
+
+class UnitPayload
+{
+public:
+    uint8_t length;
+    uint8_t id;    
+    uint8_t *data;
+    uint8_t *idptr;    
+
+    
+    
+    void set_length(uint8_t l) {
+        length=l;   
+    }
+
+    void set_id(uint8_t i) {
+        id=i;
+    }
+
+    void set_data(uint8_t* data1) {
+        for(int j=0;j<length;j++)
+        {
+            data[j]=data1[j];
+        }   
+    }
+
+    uint8_t get_length()  {
+        return length;      
+    }
+
+    uint8_t get_id()  {
+        return id;      
+    }
+
+    uint8_t* get_data() {
+        return data;        
+    }
+
+};
+
+class Payload {
+    UnitPayload *payload;
+    int stringLength;
+    int payloadUnitCount;
+    
+public:
+    Payload(const uint8_t *tokenString, uint8_t string_ength);
+    Payload();
+    ~Payload();
+    uint8_t getPayloadUnitCount();
+    
+    uint8_t getIDAtIndex(int index);  
+    uint8_t getLengthAtIndex(int index);   
+    uint8_t* getDataAtIndex(int index);    
+    int8_t getInt8AtIndex(int index);  
+    uint16_t getUint16AtIndex(int index); 
+    uint8_t* getSerializedAdDataAtIndex(int index);         
+};
+
+
+class PayloadUnit {
+private:        
+    uint8_t* lenPtr;
+    uint8_t* adTypePtr;
+    uint8_t* dataPtr;
+    
+public:
+    PayloadUnit() {
+        lenPtr = NULL;
+        adTypePtr = NULL;
+        dataPtr = NULL;
+    }
+    
+    PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) {
+        lenPtr = len;
+        adTypePtr = adType;
+        dataPtr = data;
+    }    
+    
+    void setLenPtr(uint8_t *len)   {
+        lenPtr = len;
+    } 
+    
+    void setAdTypePtr(uint8_t *adType)   {
+        adTypePtr = adType;
+    }  
+    
+    void setDataPtr(uint8_t *data)   {
+        dataPtr = data;
+    }      
+    
+    uint8_t* getLenPtr()   {
+        return lenPtr;
+    } 
+    
+    uint8_t* getAdTypePtr()   {
+        return adTypePtr;
+    }  
+    
+    uint8_t* getDataPtr()   {
+        return dataPtr;
+    }   
+    
+    void printDataAsHex()   {
+        int i = 0;
+        PRINTF("AdData=");
+        for(i=0; i<*lenPtr-1; i++) {
+            PRINTF("0x%x ", dataPtr[i]);
+        }
+        PRINTF("\n");
+    }     
+    
+    void printDataAsString()   {
+        int i = 0;
+        PRINTF("AdData=");
+        for(i=0; i<*lenPtr-1; i++) {
+            PRINTF("%c", dataPtr[i]);
+        }
+        PRINTF("\n");
+    }                                                   
+    
+};
+
+class PayloadPtr {
+private:
+    PayloadUnit *unit;
+    int payloadUnitCount;
+public:    
+    PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) {
+        // initialize private data members
+        int stringLength = string_ength;
+        payloadUnitCount = 0;
+        
+        int index = 0;
+        while(index!=stringLength) {
+            int len=tokenString[index];
+            index=index+1+len;
+            payloadUnitCount++;               
+        }
+        
+        // allocate memory to unit
+        unit = new PayloadUnit[payloadUnitCount];
+        int i = 0;
+        int nextUnitOffset = 0;
+        
+        while(i<payloadUnitCount) {           
+            unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset);
+            unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1);
+            unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2);
+            
+            nextUnitOffset += *unit[i].getLenPtr()+1;
+            i++;
+
+        }
+    }
+    
+    PayloadUnit getUnitAtIndex(int index) {
+        return unit[index];
+    }
+    
+    int getPayloadUnitCount() { return payloadUnitCount; }
+    
+    ~PayloadPtr() {
+        if(unit) delete[] unit;
+
+        unit = NULL;
+    }
+};    
+
+#endif // __PAYLOAD_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,46 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+// utility functions
+
+#ifndef __UTIL_H__
+#define __UTIL_H__
+
+#include "ble_status.h"
+#include "ble_hal_types.h"
+
+#define STORE_LE_16(buf, val)    ( ((buf)[0] =  (uint8_t) (val)    ) , \
+    ((buf)[1] =  (uint8_t) (val>>8) ) )
+
+#define STORE_LE_32(buf, val)    ( ((buf)[0] =  (uint8_t) (val)     ) , \
+    ((buf)[1] =  (uint8_t) (val>>8)  ) , \
+    ((buf)[2] =  (uint8_t) (val>>16) ) , \
+    ((buf)[3] =  (uint8_t) (val>>24) ) )
+
+#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \
+    do {\
+        uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \
+        uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \
+        uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \
+        uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \
+    }while(0)
+
+
+tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL);
+
+#endif // __UTIL_H__
+		
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/mbed_lib.json	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,16 @@
+{
+    "name": "bluenrg",
+    "target_overrides": {
+        "K64F": {
+            "target.macros_add": ["BLUENRG_PIN_SPI_SCK=D13"]
+        },
+        "DISCO_L475VG_IOT01A": {
+            "target.macros_add": ["BLUENRG_PIN_SPI_MOSI=PC_12",
+                                  "BLUENRG_PIN_SPI_MISO=PC_11",
+                                  "BLUENRG_PIN_SPI_nCS=PD_13",
+                                  "BLUENRG_PIN_SPI_RESET=PA_8",
+                                  "BLUENRG_PIN_SPI_IRQ=PE_6",
+                                  "BLUENRG_PIN_SPI_SCK=PC_10"]
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/module.json	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,37 @@
+{
+  "name": "x-nucleo-idb0xa1",
+  "version": "2.2.0",
+  "description": "ST driver for the mbed BLE API.",
+  "keywords": [
+    "expansion",
+    "board",
+    "x-nucleo",
+    "nucleo",
+    "ST",
+    "STM",
+    "Bluetooth",
+    "BLE"
+  ],
+  "author": "Andrea Palmieri",
+  "repository": {
+    "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git",
+    "type": "git"
+  },
+  "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1",
+  "licenses": [
+    {
+      "url": "https://spdx.org/licenses/Apache-2.0",
+      "type": "Apache-2.0"
+    }
+  ],
+  "extraIncludes": [
+    "x-nucleo-idb0xa1",
+    "x-nucleo-idb0xa1/utils",
+    "x-nucleo-idb0xa1/platform",
+    "x-nucleo-idb0xa1/bluenrg-hci"
+  ],
+  "dependencies": {
+    "mbed-drivers": ">=0.11.3",
+    "ble": "^2.7.0"
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,474 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/**
+  ******************************************************************************
+  * @file    BlueNRGDevice.cpp
+  * @author  STMicroelectronics
+  * @brief   Implementation of BLEDeviceInstanceBase
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */
+
+/** @defgroup BlueNRGDevice
+ *  @brief BlueNRG BLE_API Device Adaptation
+ *  @{
+ */
+ 
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif
+#include "BlueNRGDevice.h"
+#include "BlueNRGGap.h"
+#include "BlueNRGGattServer.h"
+
+#include "btle.h"
+#include "ble_utils.h"
+#include "ble_osal.h"
+
+#include "ble_debug.h"
+#include "stm32_bluenrg_ble.h"
+
+extern "C" {
+    #include "ble_hci.h"
+    #include "bluenrg_utils.h"
+}
+
+#define HEADER_SIZE 5
+#define MAX_BUFFER_SIZE 255
+
+/**
+ * The singleton which represents the BlueNRG transport for the BLEDevice.
+ *
+ * See file 'bluenrg_targets.h' for details regarding the peripheral pins used!
+ */
+#include "bluenrg_targets.h"
+
+BlueNRGDevice bluenrgDeviceInstance(BLUENRG_PIN_SPI_MOSI,
+                                    BLUENRG_PIN_SPI_MISO,
+                                    BLUENRG_PIN_SPI_SCK,
+                                    BLUENRG_PIN_SPI_nCS,
+                                    BLUENRG_PIN_SPI_RESET,
+                                    BLUENRG_PIN_SPI_IRQ);
+
+/**
+* BLE-API requires an implementation of the following function in order to
+* obtain its transport handle.
+*/
+BLEInstanceBase *
+createBLEInstance(void)
+{
+    return (&bluenrgDeviceInstance);
+}
+
+/**************************************************************************/
+/**
+    @brief  Constructor
+     * @param mosi mbed pin to use for MOSI line of SPI interface
+     * @param miso mbed pin to use for MISO line of SPI interface
+     * @param sck mbed pin to use for SCK line of SPI interface
+     * @param cs mbed pin to use for not chip select line of SPI interface
+     * @param rst mbed pin to use for BlueNRG reset
+     * @param irq mbed pin for BlueNRG IRQ
+*/
+/**************************************************************************/
+BlueNRGDevice::BlueNRGDevice(PinName mosi,
+                             PinName miso,
+                             PinName sck,
+                             PinName cs,
+                             PinName rst,
+                             PinName irq) :
+	isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq)
+{
+    // Setup the spi for 8 bit data, low clock polarity,
+    // 1-edge phase, with an 8MHz clock rate
+    spi_.format(8, 0);
+    spi_.frequency(8000000);
+
+    // Deselect the BlueNRG chip by keeping its nCS signal high
+    nCS_ = 1;
+
+    wait_us(500);
+
+    // Prepare communication between the host and the BlueNRG SPI interface
+    HCI_Init();
+
+    // Set the interrupt handler for the device
+    irq_.mode(PullDown); // set irq mode
+    irq_.rise(&HCI_Isr);
+}
+
+/**************************************************************************/
+/**
+    @brief  Destructor
+*/
+/**************************************************************************/
+BlueNRGDevice::~BlueNRGDevice(void)
+{
+}
+
+/**
+  * @brief  Get BlueNRG HW version in bootloader mode
+  * @param  hw_version The HW version is written to this parameter
+  * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise
+  */
+uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version)
+{
+	uint8_t status;
+
+	status = getBlueNRGUpdaterHWVersion(hw_version);
+
+	return (status);
+}
+
+/**
+  * @brief  Flash a new firmware using internal bootloader.
+  * @param  fw_image     Pointer to the firmware image (raw binary data,
+  *                      little-endian).
+  * @param  fw_size      Size of the firmware image. The firmware image size shall
+  *                      be multiple of 4 bytes.
+  * @retval int      It returns BLE_STATUS_SUCCESS on success, or a number
+  *                  not equal to 0 in case of error
+  *                  (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR)
+  */
+int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size)
+{
+	int status = program_device(fw_image, fw_size);
+
+	return (status);
+}
+
+
+/**
+  * @brief  Initialises anything required to start using BLE
+  * @param[in] instanceID
+  *              The ID of the instance to initialize.
+  * @param[in] callback
+  *              A callback for when initialization completes for a BLE
+  *              instance. This is an optional parameter set to NULL when not
+  *              supplied.
+  *
+  * @return BLE_ERROR_NONE if the initialization procedure was started
+  *         successfully.
+  */
+ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback)
+{
+	if (isInitialized) {
+        	BLE::InitializationCompleteCallbackContext context = {
+        	    BLE::Instance(instanceID),
+        	    BLE_ERROR_ALREADY_INITIALIZED
+        	};
+        	callback.call(&context);
+        	return BLE_ERROR_ALREADY_INITIALIZED;
+    	}
+
+	// Init the BlueNRG/BlueNRG-MS stack
+	btleInit();
+
+	isInitialized = true;
+	BLE::InitializationCompleteCallbackContext context = {
+	        BLE::Instance(instanceID),
+	        BLE_ERROR_NONE
+	};
+	callback.call(&context);
+
+	return BLE_ERROR_NONE;
+}
+
+
+/**
+    @brief  Resets the BLE HW, removing any existing services and
+            characteristics
+    @param[in] void
+    @returns    void
+*/
+void BlueNRGDevice::reset(void)
+{
+    /* Reset BlueNRG SPI interface. Hold reset line to 0 for 1500us */
+    rst_ = 0;
+    wait_us(1500);
+    rst_ = 1;
+
+    /* Wait for the radio to come back up */
+    wait_us(5000);
+}
+
+/*!
+  @brief  Wait for any BLE Event like BLE Connection, Read Request etc.
+  @param[in] void
+  @returns    char *
+*/
+void BlueNRGDevice::waitForEvent(void)
+{
+	bool must_return = false;
+
+	do {
+		bluenrgDeviceInstance.processEvents();
+
+		if(must_return) return;
+
+		__WFE(); /* it is recommended that SEVONPEND in the
+			    System Control Register is NOT set */
+		must_return = true; /* after returning from WFE we must guarantee
+				       that conrol is given back to main loop before next WFE */
+	} while(true);
+
+}
+
+/*!
+    @brief  get GAP version
+    @brief Get the BLE stack version information
+    @param[in] void
+    @returns    char *
+    @returns char *
+*/
+const char *BlueNRGDevice::getVersion(void)
+{
+    return getVersionString();
+}
+
+/**************************************************************************/
+/*!
+    @brief  get reference to GAP object
+    @param[in] void
+    @returns    Gap&
+*/
+/**************************************************************************/
+Gap        &BlueNRGDevice::getGap()
+{
+    return BlueNRGGap::getInstance();
+}
+
+const Gap  &BlueNRGDevice::getGap() const
+{
+    return BlueNRGGap::getInstance();
+}
+
+/**************************************************************************/
+/*!
+    @brief  get reference to GATT server object
+    @param[in] void
+    @returns    GattServer&
+*/
+/**************************************************************************/
+GattServer &BlueNRGDevice::getGattServer()
+{
+    return BlueNRGGattServer::getInstance();
+}
+
+const GattServer &BlueNRGDevice::getGattServer() const
+{
+    return BlueNRGGattServer::getInstance();
+}
+
+/**************************************************************************/
+/*!
+    @brief  shut down the BLE device
+    @param[out] error if any
+*/
+/**************************************************************************/
+ble_error_t  BlueNRGDevice::shutdown(void) {
+    PRINTF("BlueNRGDevice::reset\n");
+
+    if (!isInitialized) {
+        return BLE_ERROR_INITIALIZATION_INCOMPLETE;
+    }
+
+    /* Reset the BlueNRG device first */
+    reset();
+
+    /* Shutdown the BLE API and BlueNRG glue code */
+    ble_error_t error;
+
+    /* GattServer instance */
+    error = BlueNRGGattServer::getInstance().reset();
+    if (error != BLE_ERROR_NONE) {
+       return error;
+    }
+
+    /* GattClient instance */
+    error = BlueNRGGattClient::getInstance().reset();
+    if (error != BLE_ERROR_NONE) {
+        return error;
+    }
+
+    /* Gap instance */
+    error = BlueNRGGap::getInstance().reset();
+    if (error != BLE_ERROR_NONE) {
+        return error;
+    }
+
+    isInitialized = false;
+
+    PRINTF("BlueNRGDevice::reset complete\n");
+    return BLE_ERROR_NONE;
+
+}
+
+/**
+ * @brief  Reads from BlueNRG SPI buffer and store data into local buffer.
+ * @param  buffer   : Buffer where data from SPI are stored
+ * @param  buff_size: Buffer size
+ * @retval int32_t  : Number of read bytes
+ */
+int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size)
+{
+  uint16_t byte_count;
+  uint8_t len = 0;
+  uint8_t char_ff = 0xff;
+  volatile uint8_t read_char;
+
+	uint8_t i = 0;
+	volatile uint8_t tmpreg;
+
+  uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00};
+  uint8_t header_slave[HEADER_SIZE];
+
+  /* Select the chip */
+  nCS_ = 0;
+
+  /* Read the header */
+  for (i = 0; i < 5; i++)
+  {
+		tmpreg = spi_.write(header_master[i]);
+		header_slave[i] = (uint8_t)(tmpreg);
+  }
+
+  if (header_slave[0] == 0x02) {
+    /* device is ready */
+    byte_count = (header_slave[4]<<8)|header_slave[3];
+
+    if (byte_count > 0) {
+
+      /* avoid to read more data that size of the buffer */
+      if (byte_count > buff_size){
+        byte_count = buff_size;
+      }
+
+      for (len = 0; len < byte_count; len++){
+        read_char = spi_.write(char_ff);
+				buffer[len] = read_char;
+      }
+    }
+  }
+  /* Release CS line to deselect the chip */
+  nCS_ = 1;
+
+  // Add a small delay to give time to the BlueNRG to set the IRQ pin low
+  // to avoid a useless SPI read at the end of the transaction
+  for(volatile int i = 0; i < 2; i++)__NOP();
+
+#ifdef PRINT_CSV_FORMAT
+  if (len > 0) {
+    print_csv_time();
+    for (int i=0; i<len; i++) {
+      PRINT_CSV(" %02x", buffer[i]);
+    }
+    PRINT_CSV("\n");
+  }
+#endif
+
+  return len;
+}
+
+/**
+ * @brief  Writes data from local buffer to SPI.
+ * @param  data1    : First data buffer to be written
+ * @param  data2    : Second data buffer to be written
+ * @param  Nb_bytes1: Size of first data buffer to be written
+ * @param  Nb_bytes2: Size of second data buffer to be written
+ * @retval Number of read bytes
+ */
+int32_t BlueNRGDevice::spiWrite(uint8_t* data1,
+				uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2)
+{
+	int32_t result = 0;
+	uint32_t i;
+	volatile uint8_t tmpreg;
+
+  unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00};
+  unsigned char header_slave[HEADER_SIZE]  = {0xaa, 0x00, 0x00, 0x00, 0x00};
+
+  disable_irq();
+
+  /* CS reset */
+  nCS_ = 0;
+
+  /* Exchange header */
+  for (i = 0; i < 5; i++)
+  {
+		tmpreg = spi_.write(header_master[i]);
+		header_slave[i] = tmpreg;
+  }
+
+  if (header_slave[0] == 0x02) {
+    /* SPI is ready */
+    if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) {
+
+      /*  Buffer is big enough */
+			for (i = 0; i < Nb_bytes1; i++) {
+				spi_.write(*(data1 + i));
+      }
+      for (i = 0; i < Nb_bytes2; i++) {
+				spi_.write(*(data2 + i));
+      }
+    } else {
+      /* Buffer is too small */
+      result = -2;
+    }
+  } else {
+    /* SPI is not ready */
+    result = -1;
+  }
+
+  /* Release CS line */
+  //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
+  nCS_ = 1;
+
+  enable_irq();
+
+  return result;
+}
+
+bool BlueNRGDevice::dataPresent()
+{
+    return (irq_ == 1);
+}
+
+void BlueNRGDevice::disable_irq()
+{
+    irq_.disable_irq();
+}
+
+void BlueNRGDevice::enable_irq()
+{
+    irq_.enable_irq();
+}
+
+void BlueNRGDevice::processEvents() {
+    btle_handler();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,68 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BlueNRGDiscoveredCharacteristic.h"
+#include "BlueNRGGattClient.h"
+
+void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn,
+                                            Gap::Handle_t     connectionHandleIn,
+                                            DiscoveredCharacteristic::Properties_t    propsIn,
+                                            GattAttribute::Handle_t  declHandleIn,
+                                            GattAttribute::Handle_t  valueHandleIn,
+                                            GattAttribute::Handle_t  lastHandleIn)
+{
+    gattc       = gattcIn;
+    connHandle  = connectionHandleIn;
+    declHandle  = declHandleIn;
+    valueHandle = valueHandleIn;
+    lastHandle  = lastHandleIn;
+
+    props._broadcast       = propsIn.broadcast();
+    props._read            = propsIn.read();
+    props._writeWoResp     = propsIn.writeWoResp();
+    props._write           = propsIn.write();
+    props._notify          = propsIn.notify();
+    props._indicate        = propsIn.indicate();
+    props._authSignedWrite = propsIn.authSignedWrite();
+}
+
+void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient         *gattcIn,
+                                            Gap::Handle_t            connectionHandleIn,
+                                            UUID   uuidIn,
+                                            DiscoveredCharacteristic::Properties_t    propsIn,
+                                            GattAttribute::Handle_t  declHandleIn,
+                                            GattAttribute::Handle_t  valueHandleIn,
+                                            GattAttribute::Handle_t  lastHandleIn)
+{
+    gattc       = gattcIn;
+    connHandle  = connectionHandleIn;
+    uuid        = uuidIn;
+    declHandle  = declHandleIn;
+    valueHandle = valueHandleIn;
+    lastHandle  = lastHandleIn;
+
+    props._broadcast       = propsIn.broadcast();
+    props._read            = propsIn.read();
+    props._writeWoResp     = propsIn.writeWoResp();
+    props._write           = propsIn.write();
+    props._notify          = propsIn.notify();
+    props._indicate        = propsIn.indicate();
+    props._authSignedWrite = propsIn.authSignedWrite();
+}
+
+ void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t  lastHandleIn) {
+     lastHandle = lastHandleIn;
+ }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,1477 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/**
+  ******************************************************************************
+  * @file    BlueNRGGap.cpp
+  * @author  STMicroelectronics
+  * @brief   Implementation of BLE_API Gap Class
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */
+
+/** @defgroup BlueNRGGap
+ *  @brief BlueNRG BLE_API GAP Adaptation
+ *  @{
+ */
+
+#include "BlueNRGDevice.h"
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif
+#include "ble_payload.h"
+#include "ble_utils.h"
+#include "ble_debug.h"
+
+/*
+ * Utility to process GAP specific events (e.g., Advertising timeout)
+ */
+void BlueNRGGap::Process(void)
+{
+    if(AdvToFlag) {
+        AdvToFlag = false;
+        stopAdvertising();
+    }
+
+    if(ScanToFlag) {
+        ScanToFlag = false;
+        stopScan();
+    }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the advertising parameters and payload for the device.
+            Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API
+
+    @params[in] advData
+                The primary advertising data payload
+    @params[in] scanResponse
+                The optional Scan Response payload if the advertising
+                type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
+                in \ref GapAdveritinngParams
+
+    @returns    \ref ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @retval     BLE_ERROR_BUFFER_OVERFLOW
+                The proposed action would cause a buffer overflow.  All
+                advertising payloads must be <= 31 bytes, for example.
+
+    @retval     BLE_ERROR_NOT_IMPLEMENTED
+                A feature was requested that is not yet supported in the
+                nRF51 firmware or hardware.
+
+    @retval     BLE_ERROR_PARAM_OUT_OF_RANGE
+                One of the proposed values is outside the valid range.
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
+{
+    PRINTF("BlueNRGGap::setAdvertisingData\n\r");
+    /* Make sure we don't exceed the advertising payload length */
+    if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
+        PRINTF("Exceeded the advertising payload length\n\r");
+        return BLE_ERROR_BUFFER_OVERFLOW;
+    }
+
+    /* Make sure we have a payload! */
+    if (advData.getPayloadLen() != 0) {
+        PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen());
+
+        /* Align the GAP Service Appearance Char value coherently
+           This setting is duplicate (see below GapAdvertisingData::APPEARANCE)
+           since BLE API has an overloaded function for appearance
+        */
+        STORE_LE_16(deviceAppearance, advData.getAppearance());
+        setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]));
+
+
+        for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) {
+            loadPtr.getUnitAtIndex(index);
+
+            PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr()));
+            PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()));
+
+            switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) {
+            /**< TX Power Level (in dBm) */
+            case GapAdvertisingData::TX_POWER_LEVEL:
+                {
+                PRINTF("Advertising type: TX_POWER_LEVEL\n\r");
+                int8_t enHighPower = 0;
+                int8_t paLevel = 0;
+
+                int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr();
+                tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel);
+#ifdef DEBUG
+                PRINTF("dbm=%d, ret=%d\n\r", dbm, ret);
+                PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);
+#endif
+                if(ret == BLE_STATUS_SUCCESS) {
+                  aci_hal_set_tx_power_level(enHighPower, paLevel);
+                }
+                break;
+                }
+            /**< Appearance */
+            case GapAdvertisingData::APPEARANCE:
+                {
+                PRINTF("Advertising type: APPEARANCE\n\r");
+
+                GapAdvertisingData::Appearance appearanceP;
+                memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2);
+
+                PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]);
+
+                appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]);
+                /* Align the GAP Service Appearance Char value coherently */
+                setAppearance(appearanceP);
+                break;
+                }
+
+            } // end switch
+
+        } //end for
+
+    }
+
+    // update the advertising data in the shield if advertising is running
+    if (state.advertising == 1) {
+        tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload());
+
+        if(BLE_STATUS_SUCCESS != ret) {
+            PRINTF(" error while setting scan response data (ret=0x%x)\n", ret);
+            switch (ret) {
+                case BLE_STATUS_TIMEOUT:
+                    return BLE_STACK_BUSY;
+                default:
+                    return BLE_ERROR_UNSPECIFIED;
+            }
+        }
+
+        ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload());
+        if (ret) {
+            PRINTF("error while setting the payload\r\n");
+            return BLE_ERROR_UNSPECIFIED;
+        }
+    }
+
+    _advData = advData;
+    _scanResponse = scanResponse;
+
+    return BLE_ERROR_NONE;
+}
+
+/*
+ * Utility to set ADV timeout flag
+ */
+void BlueNRGGap::setAdvToFlag(void) {
+    AdvToFlag = true;
+    signalEventsToProcess();
+}
+
+/*
+ * ADV timeout callback
+ */
+#ifdef AST_FOR_MBED_OS
+static void advTimeoutCB(void)
+{
+    BlueNRGGap::getInstance().stopAdvertising();
+}
+#else
+static void advTimeoutCB(void)
+{
+    BlueNRGGap::getInstance().setAdvToFlag();
+
+    Timeout& t = BlueNRGGap::getInstance().getAdvTimeout();
+    t.detach(); /* disable the callback from the timeout */
+}
+#endif /* AST_FOR_MBED_OS */
+
+/*
+ * Utility to set SCAN timeout flag
+ */
+void BlueNRGGap::setScanToFlag(void) {
+    ScanToFlag = true;
+    signalEventsToProcess();
+}
+
+static void scanTimeoutCB(void)
+{
+    BlueNRGGap::getInstance().setScanToFlag();
+
+    Timeout& t = BlueNRGGap::getInstance().getScanTimeout();
+    t.detach(); /* disable the callback from the timeout */
+}
+
+/**************************************************************************/
+/*!
+    @brief  Starts the BLE HW, initialising any services that were
+            added before this function was called.
+
+    @param[in]  params
+                Basic advertising details, including the advertising
+                delay, timeout and how the device should be advertised
+
+    @note   All services must be added before calling this function!
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+
+ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams &params)
+{
+    tBleStatus ret;
+    int err;
+
+    /* Make sure we support the advertising type */
+    if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
+        /* ToDo: This requires a proper security implementation, etc. */
+        return BLE_ERROR_NOT_IMPLEMENTED;
+    }
+
+    /* Check interval range */
+    if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
+        /* Min delay is slightly longer for unconnectable devices */
+        if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
+                (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
+            return BLE_ERROR_PARAM_OUT_OF_RANGE;
+        }
+    } else {
+        if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
+                (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
+            return BLE_ERROR_PARAM_OUT_OF_RANGE;
+        }
+    }
+
+    /* Check timeout is zero for Connectable Directed */
+    if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
+        /* Timeout must be 0 with this type, although we'll never get here */
+        /* since this isn't implemented yet anyway */
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    /* Check timeout for other advertising types */
+    if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
+            (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    /*
+     * Advertising filter policy setting
+     * FIXME: the Security Manager should be implemented
+     */
+    AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode();
+    if(mode != ADV_POLICY_IGNORE_WHITELIST) {
+        ret = aci_gap_configure_whitelist();
+        if(ret != BLE_STATUS_SUCCESS) {
+          PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret);
+          return BLE_ERROR_OPERATION_NOT_PERMITTED;
+        }
+    }
+
+    uint8_t advFilterPolicy = NO_WHITE_LIST_USE;
+    switch(mode) {
+        case ADV_POLICY_FILTER_SCAN_REQS:
+            advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN;
+            break;
+        case ADV_POLICY_FILTER_CONN_REQS:
+            advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN;
+            break;
+        case ADV_POLICY_FILTER_ALL_REQS:
+            advFilterPolicy = WHITE_LIST_FOR_ALL;
+            break;
+        default:
+            advFilterPolicy = NO_WHITE_LIST_USE;
+            break;
+    }
+
+    /* Check the ADV type before setting scan response data */
+    if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED ||
+        params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) {
+
+        /* set scan response data */
+        PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen());
+        ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload());
+
+        if(BLE_STATUS_SUCCESS!=ret) {
+            PRINTF(" error while setting scan response data (ret=0x%x)\n", ret);
+            switch (ret) {
+              case BLE_STATUS_TIMEOUT:
+                return BLE_STACK_BUSY;
+              default:
+                return BLE_ERROR_UNSPECIFIED;
+            }
+        }
+    } else {
+        hci_le_set_scan_resp_data(0, NULL);
+    }
+
+    setAdvParameters();
+    PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType());
+
+    err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload());
+
+    if (err) {
+        PRINTF("error while setting the payload\r\n");
+        return BLE_ERROR_UNSPECIFIED;
+    }
+
+    tBDAddr dummy_addr = { 0 };
+    uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval;
+    uint16_t advIntervalMax = advIntervalMin + 1;
+
+    err = hci_le_set_advertising_parameters(
+        advIntervalMin,
+        advIntervalMax,
+        params.getAdvertisingType(),
+    	addr_type,
+        0x00,
+        dummy_addr,
+        /* all channels */ 7,
+    	advFilterPolicy
+    );
+
+    if (err) {
+        PRINTF("impossible to set advertising parameters\n\r");
+        PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1);
+        PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy);
+        return BLE_ERROR_INVALID_PARAM;
+    }
+
+    err = hci_le_set_advertise_enable(0x01);
+    if (err) {
+        PRINTF("impossible to start advertising\n\r");
+        return BLE_ERROR_UNSPECIFIED;
+    }
+
+    if(params.getTimeout() != 0) {
+        PRINTF("!!! attaching adv to!!!\n");
+#ifdef AST_FOR_MBED_OS
+        minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000));
+#else
+        advTimeout.attach(advTimeoutCB, params.getTimeout());
+#endif
+    }
+
+    return BLE_ERROR_NONE;
+
+}
+
+
+/**************************************************************************/
+/*!
+    @brief  Stops the BLE HW and disconnects from any devices
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::stopAdvertising(void)
+{
+    if(state.advertising == 1) {
+
+        int err = hci_le_set_advertise_enable(0);
+        if (err) {
+            return BLE_ERROR_OPERATION_NOT_PERMITTED;
+        }
+
+        PRINTF("Advertisement stopped!!\n\r") ;
+        //Set GapState_t::advertising state
+        state.advertising = 0;
+    }
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Disconnects if we are connected to a central device
+
+    @param[in]  reason
+                Disconnection Reason
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason)
+{
+    tBleStatus ret;
+
+    ret = aci_gap_terminate(connectionHandle, reason);
+
+    if (BLE_STATUS_SUCCESS != ret){
+        PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ;
+        switch (ret) {
+          case ERR_COMMAND_DISALLOWED:
+            return BLE_ERROR_OPERATION_NOT_PERMITTED;
+          case BLE_STATUS_TIMEOUT:
+            return BLE_STACK_BUSY;
+          default:
+            return BLE_ERROR_UNSPECIFIED;
+        }
+    }
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Disconnects if we are connected to a central device
+
+    @param[in]  reason
+                Disconnection Reason
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason)
+{
+    return disconnect(m_connectionHandle, reason);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the 16-bit connection handle
+
+    @param[in]  conn_handle
+                Connection Handle which is set in the Gap Instance
+
+    @returns    void
+*/
+/**************************************************************************/
+void BlueNRGGap::setConnectionHandle(uint16_t conn_handle)
+{
+    m_connectionHandle = conn_handle;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the 16-bit connection handle
+
+    @param[in]  void
+
+    @returns    uint16_t
+                Connection Handle of the Gap Instance
+*/
+/**************************************************************************/
+uint16_t BlueNRGGap::getConnectionHandle(void)
+{
+    return m_connectionHandle;
+}
+
+/**************************************************************************/
+/*!
+    @brief      Sets the BLE device address. SetAddress will reset the BLE
+                device and re-initialize BTLE. Will not start advertising.
+
+    @param[in]  type
+                Type of Address
+
+    @param[in]  address[6]
+                Value of the Address to be set
+
+    @returns    ble_error_t
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address)
+{
+    if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    if(type == BLEProtocol::AddressType::PUBLIC){
+        tBleStatus ret = aci_hal_write_config_data(
+            CONFIG_DATA_PUBADDR_OFFSET,
+            CONFIG_DATA_PUBADDR_LEN,
+            address
+        );
+        if(ret != BLE_STATUS_SUCCESS) {
+            return BLE_ERROR_OPERATION_NOT_PERMITTED;
+        }
+    } else if  (type == BLEProtocol::AddressType::RANDOM_STATIC) {
+        // ensure that the random static address is well formed
+        if ((address[5] & 0xC0) != 0xC0) {
+            return BLE_ERROR_PARAM_OUT_OF_RANGE;
+        }
+
+        // thanks to const correctness of the API ...
+        tBDAddr random_address = { 0 };
+        memcpy(random_address, address, sizeof(random_address));
+        int err = hci_le_set_random_address(random_address);
+        if (err) {
+            return BLE_ERROR_OPERATION_NOT_PERMITTED;
+        }
+
+        // It is not possible to get the bluetooth address when it is set
+        // store it locally in class data member
+        memcpy(bdaddr, address, sizeof(bdaddr));
+    } else {
+        // FIXME random addresses are not supported yet
+        // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE
+        // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE
+        return BLE_ERROR_NOT_IMPLEMENTED;
+    }
+
+    // if we're here then the address was correctly set
+    // commit it inside the addr_type
+    addr_type = type;
+    isSetAddress = true;
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief      Returns boolean if the address of the device has been set
+                or not
+
+    @returns    bool
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+bool BlueNRGGap::getIsSetAddress()
+{
+    return isSetAddress;
+}
+
+/**************************************************************************/
+/*!
+    @brief      Returns the address of the device if set
+
+    @returns    Pointer to the address if Address is set else NULL
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address)
+{
+    uint8_t bdaddr[BDADDR_SIZE];
+    uint8_t data_len_out;
+
+    // precondition, check that pointers in input are valid
+    if (typeP == NULL || address == NULL) {
+        return BLE_ERROR_INVALID_PARAM;
+    }
+
+    if (addr_type == BLEProtocol::AddressType::PUBLIC) {
+        tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr);
+        if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) {
+            return BLE_ERROR_UNSPECIFIED;
+        }
+    } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) {
+        // FIXME hci_read_bd_addr and
+        // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1
+        // does not work, use the address stored in class data member
+        memcpy(bdaddr, this->bdaddr, sizeof(bdaddr));
+    } else {
+        // FIXME: should be implemented with privacy features
+        // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE
+        // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE
+        return BLE_ERROR_NOT_IMPLEMENTED;
+    }
+
+    *typeP = addr_type;
+    memcpy(address, bdaddr, BDADDR_SIZE);
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief      obtains preferred connection params
+
+    @returns    ble_error_t
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params)
+{
+    static const size_t parameter_size = 2;
+
+    if (!g_preferred_connection_parameters_char_handle) {
+        return BLE_ERROR_OPERATION_NOT_PERMITTED;
+    }
+
+    // Peripheral preferred connection parameters are an array of 4 uint16_t
+    uint8_t parameters_packed[parameter_size * 4];
+    uint16_t bytes_read = 0;
+
+    tBleStatus err = aci_gatt_read_handle_value(
+        g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE,
+        sizeof(parameters_packed),
+        &bytes_read,
+        parameters_packed
+    );
+
+    PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read);
+
+    // check that the read succeed and the result have the expected length
+    if (err || bytes_read != sizeof(parameters_packed)) {
+        return BLE_ERROR_UNSPECIFIED;
+    }
+
+    // memcpy field by field
+    memcpy(&params->minConnectionInterval, parameters_packed, parameter_size);
+    memcpy(&params->maxConnectionInterval, &parameters_packed[parameter_size], parameter_size);
+    memcpy(&params->slaveLatency, &parameters_packed[2 * parameter_size], parameter_size);
+    memcpy(&params->connectionSupervisionTimeout, &parameters_packed[3 * parameter_size], parameter_size);
+
+    return BLE_ERROR_NONE;
+}
+
+
+/**************************************************************************/
+/*!
+    @brief      sets preferred connection params
+
+    @returns    ble_error_t
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params)
+{
+    static const size_t parameter_size = 2;
+    uint8_t parameters_packed[parameter_size * 4];
+
+    // ensure that parameters are correct
+    // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C]
+    // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC
+    if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) &&
+        params->minConnectionInterval != 0xFFFF) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) &&
+        params->maxConnectionInterval != 0xFFFF) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    if (params->slaveLatency > 0x01F3) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) &&
+        params->connectionSupervisionTimeout != 0xFFFF) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    // copy the parameters inside the byte array
+    memcpy(parameters_packed, &params->minConnectionInterval, parameter_size);
+    memcpy(&parameters_packed[parameter_size], &params->maxConnectionInterval, parameter_size);
+    memcpy(&parameters_packed[2 * parameter_size], &params->slaveLatency, parameter_size);
+    memcpy(&parameters_packed[3 * parameter_size], &params->connectionSupervisionTimeout, parameter_size);
+
+    tBleStatus err = aci_gatt_update_char_value(
+        g_gap_service_handle,
+        g_preferred_connection_parameters_char_handle,
+        /* offset */ 0,
+        sizeof(parameters_packed),
+        parameters_packed
+    );
+
+    if (err) {
+        PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ;
+        switch (err) {
+          case BLE_STATUS_INVALID_HANDLE:
+          case BLE_STATUS_INVALID_PARAMETER:
+            return BLE_ERROR_INVALID_PARAM;
+          case BLE_STATUS_INSUFFICIENT_RESOURCES:
+            return BLE_ERROR_NO_MEM;
+          case BLE_STATUS_TIMEOUT:
+            return BLE_STACK_BUSY;
+          default:
+            return BLE_ERROR_UNSPECIFIED;
+        }
+    }
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief      updates preferred connection params
+
+    @returns    ble_error_t
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params)
+{
+    tBleStatus ret = BLE_STATUS_SUCCESS;
+
+    if(gapRole == Gap::CENTRAL) {
+        ret = aci_gap_start_connection_update(handle,
+                                              params->minConnectionInterval,
+                                              params->maxConnectionInterval,
+                                              params->slaveLatency,
+                                              params->connectionSupervisionTimeout,
+                                              CONN_L1, CONN_L2);
+    } else {
+        ret = aci_l2cap_connection_parameter_update_request(handle,
+                                                            params->minConnectionInterval,
+                                                            params->maxConnectionInterval,
+                                                            params->slaveLatency,
+                                                            params->connectionSupervisionTimeout);
+    }
+
+    if (BLE_STATUS_SUCCESS != ret){
+        PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ;
+        switch (ret) {
+          case ERR_INVALID_HCI_CMD_PARAMS:
+          case BLE_STATUS_INVALID_PARAMETER:
+            return BLE_ERROR_INVALID_PARAM;
+          case ERR_COMMAND_DISALLOWED:
+          case BLE_STATUS_NOT_ALLOWED:
+            return BLE_ERROR_OPERATION_NOT_PERMITTED;
+          default:
+            return BLE_ERROR_UNSPECIFIED;
+        }
+    }
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the Device Name Characteristic
+
+    @param[in]  deviceName
+                pointer to device name to be set
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName)
+{
+    tBleStatus ret;
+    uint8_t nameLen = 0;
+
+    nameLen = strlen((const char*)deviceName);
+    PRINTF("DeviceName Size=%d\n\r", nameLen);
+
+    ret = aci_gatt_update_char_value(g_gap_service_handle,
+                                     g_device_name_char_handle,
+                                     0,
+                                     nameLen,
+                                     deviceName);
+
+    if (BLE_STATUS_SUCCESS != ret){
+        PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ;
+        switch (ret) {
+          case BLE_STATUS_INVALID_HANDLE:
+          case BLE_STATUS_INVALID_PARAMETER:
+            return BLE_ERROR_INVALID_PARAM;
+          case BLE_STATUS_INSUFFICIENT_RESOURCES:
+            return BLE_ERROR_NO_MEM;
+          case BLE_STATUS_TIMEOUT:
+            return BLE_STACK_BUSY;
+          default:
+            return BLE_ERROR_UNSPECIFIED;
+        }
+    }
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the Device Name Characteristic
+
+    @param[in]  deviceName
+                pointer to device name
+
+    @param[in]  lengthP
+                pointer to device name length
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
+{
+    tBleStatus ret;
+
+    ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
+                                     *lengthP,
+                                     (uint16_t *)lengthP,
+                                     deviceName);
+    PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP);
+    if (ret == BLE_STATUS_SUCCESS) {
+        return BLE_ERROR_NONE;
+    } else {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the Device Appearance Characteristic
+
+    @param[in]  appearance
+                device appearance
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance)
+{
+    tBleStatus ret;
+    uint8_t deviceAppearance[2];
+
+    STORE_LE_16(deviceAppearance, appearance);
+    PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]);
+
+    ret = aci_gatt_update_char_value(g_gap_service_handle,
+                                     g_appearance_char_handle,
+                                     0, 2, (uint8_t *)deviceAppearance);
+    if (BLE_STATUS_SUCCESS == ret){
+        return BLE_ERROR_NONE;
+    }
+
+    PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret);
+    switch (ret) {
+      case BLE_STATUS_INVALID_HANDLE:
+      case BLE_STATUS_INVALID_PARAMETER:
+        return BLE_ERROR_INVALID_PARAM;
+      case BLE_STATUS_INSUFFICIENT_RESOURCES:
+        return BLE_ERROR_NO_MEM;
+      case BLE_STATUS_TIMEOUT:
+        return BLE_STACK_BUSY;
+      default:
+        return BLE_ERROR_UNSPECIFIED;
+    }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the Device Appearance Characteristic
+
+    @param[in]  appearance
+                pointer to device appearance value
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
+{
+    tBleStatus ret;
+    uint16_t lengthP = 2;
+
+    ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
+                                     lengthP,
+                                     &lengthP,
+                                     (uint8_t*)appearanceP);
+    PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP);
+    if (ret == BLE_STATUS_SUCCESS) {
+        return BLE_ERROR_NONE;
+    } else {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+}
+
+GapScanningParams* BlueNRGGap::getScanningParams(void)
+{
+  return &_scanningParams;
+}
+
+static void makeConnection(void)
+{
+  BlueNRGGap::getInstance().createConnection();
+}
+
+void BlueNRGGap::Discovery_CB(Reason_t reason,
+                              uint8_t adv_type,
+                              uint8_t addr_type,
+                              uint8_t *addr,
+                              uint8_t *data_length,
+                              uint8_t *data,
+                              uint8_t *RSSI)
+{
+  switch (reason) {
+  case DEVICE_FOUND:
+    {
+      GapAdvertisingParams::AdvertisingType_t type;
+      bool isScanResponse = false;
+
+      /*
+       * Whitelisting (scan policy):
+       * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) &&
+       * Private Random Address
+       * => scan_results = FALSE
+       * FIXME: the Security Manager should be implemented
+       */
+      ScanningPolicyMode_t mode = getScanningPolicyMode();
+      PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type);
+      if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV ||
+         (addr_type == RESOLVABLE_PRIVATE_ADDR ||
+          addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) {
+        return;
+      }
+
+      switch(adv_type) {
+      case ADV_IND:
+        type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
+        break;
+      case ADV_DIRECT_IND:
+        type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED;
+        break;
+      case ADV_SCAN_IND:
+      case SCAN_RSP:
+        type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED;
+        isScanResponse = true;
+        break;
+      case ADV_NONCONN_IND:
+        type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED;
+        break;
+      default:
+        type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
+      }
+
+      PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n",
+             *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
+      if(!_connecting) {
+        processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data);
+      }
+      PRINTF("!!!After processAdvertisementReport\n\r");
+    }
+    break;
+
+  case DISCOVERY_COMPLETE:
+    // The discovery is complete. If this is due to a stop scanning (i.e., the device
+    // we are interested in has been found) and a connection has been requested
+    // then we start the device connection.
+    PRINTF("DISCOVERY_COMPLETE\n\r");
+    _scanning = false;
+
+    // Since the DISCOVERY_COMPLETE event can be received during the scanning interval,
+    // we need to delay the starting of connection
+    uint16_t delay = (_scanningParams.getInterval()*0.625);
+
+#ifdef AST_FOR_MBED_OS
+    if(_connecting) {
+      minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay));
+    }
+#else
+    Clock_Wait(delay);
+    if(_connecting) {
+      makeConnection();
+    }
+#endif /* AST_FOR_MBED_OS */
+
+    break;
+  }
+}
+
+ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams)
+{
+
+  tBleStatus ret = BLE_STATUS_SUCCESS;
+
+  // Stop ADV before scanning
+  /*
+  if (state.advertising == 1) {
+    stopAdvertising();
+  }
+  */
+
+  /*
+   * Whitelisting (scan policy):
+   * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) &&
+   * White List is empty
+   * => scan operation = FAILURE
+   * FIXME: the Security Manager should be implemented
+   */
+  ScanningPolicyMode_t mode = getScanningPolicyMode();
+  uint8_t whiteListSize = whitelistAddresses.size;
+  if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) {
+    return BLE_ERROR_OPERATION_NOT_PERMITTED;
+  }
+
+  ret = btleStartRadioScan(scanningParams.getActiveScanning(),
+                           scanningParams.getInterval(),
+                           scanningParams.getWindow(),
+                           addr_type);
+
+  PRINTF("Scanning...\n\r");
+  PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000);
+  PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000);
+  //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval());
+  //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1);
+  //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2);
+  if (BLE_STATUS_SUCCESS == ret){
+    PRINTF("Observation Procedure Started\n");
+    _scanning = true;
+
+    if(scanningParams.getTimeout() != 0) {
+        PRINTF("!!! attaching scan to!!!\n");
+        scanTimeout.attach(scanTimeoutCB, scanningParams.getTimeout());
+    }
+
+    return BLE_ERROR_NONE;
+  }
+
+  // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED
+  switch (ret) {
+    case BLE_STATUS_INVALID_CID:
+      PRINTF("Observation Procedure not implemented!!!\n\r");
+      return BLE_ERROR_NOT_IMPLEMENTED;
+    default:
+      PRINTF("Observation Procedure failed (0x%02X)\n\r", ret);
+      return BLE_ERROR_UNSPECIFIED;
+  }
+
+}
+
+ble_error_t BlueNRGGap::stopScan() {
+  tBleStatus ret = BLE_STATUS_SUCCESS;
+
+  if(_scanning) {
+    ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC);
+
+    if (ret != BLE_STATUS_SUCCESS) {
+      PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret);
+      return BLE_ERROR_UNSPECIFIED;
+    } else {
+      PRINTF("Discovery Procedure Terminated\n");
+      return BLE_ERROR_NONE;
+    }
+  }
+
+  return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  set Tx power level
+    @param[in] txPower Transmission Power level
+    @returns    ble_error_t
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setTxPower(int8_t txPower)
+{
+    tBleStatus ret;
+
+    int8_t enHighPower = 0;
+    int8_t paLevel = 0;
+
+    ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel);
+    if(ret!=BLE_STATUS_SUCCESS) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);
+    ret = aci_hal_set_tx_power_level(enHighPower, paLevel);
+    if(ret!=BLE_STATUS_SUCCESS) {
+      return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  get permitted Tx power values
+    @param[in] values pointer to pointer to permitted power values
+    @param[in] num number of values
+*/
+/**************************************************************************/
+void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
+    static const int8_t permittedTxValues[] = {
+        -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8
+    };
+
+    *valueArrayPP = permittedTxValues;
+    *countP = sizeof(permittedTxValues) / sizeof(int8_t);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Set advertising parameters according to the current state
+            Parameters value is set taking into account guidelines of the BlueNRG
+            time slots allocation
+*/
+/**************************************************************************/
+void BlueNRGGap::setAdvParameters(void)
+{
+  uint32_t advIntMS;
+
+  if(state.connected == 1) {
+    advIntMS = (conn_min_interval*1.25)-GUARD_INT;
+    advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS);
+
+    PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval);
+  } else {
+    advInterval = _advParams.getIntervalInADVUnits();
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Set connection parameters according to the current state (ADV and/or SCAN)
+            Parameters value is set taking into account guidelines of the BlueNRG
+            time slots allocation
+*/
+/**************************************************************************/
+void BlueNRGGap::setConnectionParameters(void)
+{
+  if (state.connected == 1) {
+
+    PRINTF("state.connected=1\r\n");
+    scanInterval = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(conn_min_interval*1.25);
+    scanWindow = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(((conn_min_interval*1.25)/100)*60); // scanWin ~= 60%(scanInt)
+
+  } else if (state.advertising == 1) {
+
+    if (_scanningParams.getInterval() < advInterval) {
+      PRINTF("state.adv=1 scanInterval<advInterval\r\n");
+      scanInterval = advInterval;
+      scanWindow = advInterval;
+    } else {
+      PRINTF("state.adv=1 scanInterval>=advInterval\r\n");
+      scanInterval = _scanningParams.getInterval();
+      scanWindow = _scanningParams.getWindow();
+    }
+
+    if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms
+        conn_min_interval = MAX_INT_CONN;
+        conn_max_interval = MAX_INT_CONN;
+    } else {
+        conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25;
+        conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25;
+    }
+
+  } else {
+
+    PRINTF("state.adv = 0\r\n");
+
+    scanInterval = _scanningParams.getInterval();
+    scanWindow = _scanningParams.getWindow();
+    if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) ||
+       SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms
+        conn_min_interval = DEF_INT_CONN;
+        conn_max_interval = DEF_INT_CONN;
+    } else {
+        conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25;
+        conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25;
+    }
+  }
+  PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval));
+  PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow));
+  PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25));
+  PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25));
+
+}
+
+ble_error_t BlueNRGGap::createConnection ()
+{
+  tBleStatus ret;
+
+  /*
+     Before creating connection, set parameters according
+     to previous or current procedure (ADV and/or SCAN)
+   */
+  setConnectionParameters();
+
+  /*
+    Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min,
+    Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max
+  */
+  ret = aci_gap_create_connection(scanInterval,
+				  scanWindow,
+				  _peerAddrType,
+				  (unsigned char*)_peerAddr,
+				  addr_type,
+				  conn_min_interval, conn_max_interval, 0,
+				  SUPERV_TIMEOUT, CONN_L1, CONN_L1);
+
+  //_connecting = false;
+
+  if (ret != BLE_STATUS_SUCCESS) {
+    PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret);
+    return BLE_ERROR_UNSPECIFIED;
+  } else {
+    PRINTF("Connection started.\n");
+    _connecting = false;
+    return BLE_ERROR_NONE;
+  }
+}
+
+ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr,
+                                 Gap::AddressType_t peerAddrType,
+                                 const ConnectionParams_t *connectionParams,
+                                 const GapScanningParams *scanParams)
+{
+  /* avoid compiler warnings about unused variables */
+  (void)connectionParams;
+
+  setScanParams(scanParams->getInterval(),
+                scanParams->getWindow(),
+                scanParams->getTimeout(),
+                scanParams->getActiveScanning()
+               );
+
+  // Save the peer address
+  for(int i=0; i<BDADDR_SIZE; i++) {
+    _peerAddr[i] = peerAddr[i];
+  }
+  _peerAddrType = peerAddrType;
+
+  _connecting = true;
+
+  if(_scanning) {
+    stopScan();
+  } else {
+    PRINTF("Calling createConnection from connect()\n\r");
+    return createConnection();
+  }
+
+  return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Set the advertising policy filter mode that will be used in
+            the next call to startAdvertising().
+
+    @returns    \ref ble_errror_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly.
+
+                BLE_ERROR_NOT_IMPLEMENTED
+                This feature is currently note implemented.
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode)
+{
+   advertisingPolicyMode = mode;
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Set the scanning policy filter mode that will be used in
+            the next call to startAdvertising().
+
+    @returns    \ref ble_errror_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly.
+
+                BLE_ERROR_NOT_IMPLEMENTED
+                This feature is currently note implemented.
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode)
+{
+    scanningPolicyMode = mode;
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Get the current advertising policy filter mode.
+
+    @returns    The advertising policy filter mode.
+*/
+/**************************************************************************/
+Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const
+{
+    return advertisingPolicyMode;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Get the current scanning policy filter mode.
+
+    @returns    The scanning policy filter mode.
+
+*/
+/**************************************************************************/
+Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const
+{
+    return scanningPolicyMode;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Clear BlueNRGGap's state.
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::reset(void)
+{
+    PRINTF("BlueNRGGap::reset\n");
+
+    /* Clear all state that is from the parent, including private members */
+    if (Gap::reset() != BLE_ERROR_NONE) {
+        return BLE_ERROR_INVALID_STATE;
+    }
+
+    AdvToFlag = false;
+    ScanToFlag = false;
+
+    /* Clear derived class members */
+    m_connectionHandle = BLE_CONN_HANDLE_INVALID;
+
+    /* Set the whitelist policy filter modes to IGNORE_WHITELIST */
+    advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST;
+    scanningPolicyMode    = Gap::SCAN_POLICY_IGNORE_WHITELIST;
+
+    return BLE_ERROR_NONE;
+}
+
+void BlueNRGGap::setConnectionInterval(uint16_t interval) {
+    conn_min_interval = interval;
+    conn_max_interval = interval;
+}
+
+Gap::Role_t BlueNRGGap::getGapRole(void)
+{
+    return (gapRole);
+}
+
+void BlueNRGGap::setGapRole(Gap::Role_t role)
+{
+    gapRole = role;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,403 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/**
+  ******************************************************************************
+  * @file    BlueNRGGattServer.cpp
+  * @author  STMicroelectronics
+  * @brief   Implementation of BlueNRG BLE_API GattServer Class
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */
+
+/** @defgroup BlueNRGGATTClient
+ *  @brief BlueNRG BLE_API GattClient Adaptation
+ *  @{
+ */
+
+#include "BlueNRGGattClient.h"
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif 
+#include "BlueNRGGap.h"
+#include "ble_utils.h"
+#include "ble_debug.h"
+
+#include <new>
+#include <assert.h>
+
+ble_error_t BlueNRGGattClient::createGattConnectionClient(Gap::Handle_t connectionHandle)
+{
+  if(MAX_ACTIVE_CONNECTIONS <= _numConnections) {
+    return BLE_ERROR_OPERATION_NOT_PERMITTED;
+  }
+
+  for(uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) {
+
+    if(_connectionPool[i] == NULL) {
+      BlueNRGGattConnectionClient *gattConnectionClient = new(std::nothrow) BlueNRGGattConnectionClient(this, connectionHandle);
+
+      if (gattConnectionClient == NULL) {
+        return BLE_ERROR_NO_MEM;
+      }
+
+      _connectionPool[i] = gattConnectionClient;
+      _connectionPool[i]->onServiceDiscoveryTermination(terminationCallback);
+      _numConnections++;
+
+      PRINTF("createGattConnectionClient: _connectionPool index=%d\r\n", i);
+      PRINTF("createGattConnectionClient: succesfully added new gattConnectionClient (_numConnections=%d)\r\n", _numConnections);
+      break;
+    }
+  }
+
+  return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattClient::removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason)
+{
+
+  PRINTF("removeGattConnectionClient: connectionHandle=%d reason=0x%x\r\n", connectionHandle, reason);
+
+  for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) {
+    PRINTF("removeGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle);
+
+    if(_connectionPool[i]->_connectionHandle == connectionHandle) {
+      PRINTF("removeGattConnectionClient: Found gattConnectionClient\r\n");
+      delete _connectionPool[i];
+      _connectionPool[i] = NULL;
+
+      _numConnections--;
+      PRINTF("removeGattConnectionClient: succesfully removed gattConnectionClient (_numConnections=%d)\r\n", _numConnections);
+
+      break;
+
+    } else {
+      return BLE_ERROR_INTERNAL_STACK_FAILURE;
+    }
+  }
+
+  return BLE_ERROR_NONE;
+}
+
+BlueNRGGattConnectionClient * BlueNRGGattClient::getGattConnectionClient(Gap::Handle_t connectionHandle) {
+  PRINTF("getGattConnectionClient\r\n");
+
+  for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) {
+    PRINTF("getGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle);
+
+    if(_connectionPool[i]->_connectionHandle == connectionHandle) {
+      PRINTF("getGattConnectionClient: Found gattConnectionClient\r\n");
+      return _connectionPool[i];
+    }
+  }
+
+  return NULL;
+}
+
+void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code) {
+
+  if(error_code != BLE_STATUS_SUCCESS) {
+    return;
+  }
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->gattProcedureCompleteCB(error_code);
+}
+
+void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle,
+                                          uint8_t event_data_length,
+                                          uint8_t attribute_data_length,
+                                          uint8_t *attribute_data_list) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->primaryServicesCB(event_data_length,
+                                          attribute_data_length,
+                                          attribute_data_list);
+}
+    
+void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle,
+                                         uint8_t event_data_length,
+                                         uint8_t *handles_info_list) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->primaryServiceCB(event_data_length,
+                                         handles_info_list);
+}
+    
+ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  if(gattConnectionClient != NULL) {
+    return gattConnectionClient->findServiceChars();
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+    
+void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle,
+                                       uint8_t event_data_length,
+                                       uint8_t handle_value_pair_length,
+                                       uint8_t *handle_value_pair) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->serviceCharsCB(event_data_length,
+                                       handle_value_pair_length,
+                                       handle_value_pair);
+}
+    
+void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle,
+                                            uint8_t event_data_length,
+                                            uint16_t attr_handle,
+                                            uint8_t *attr_value) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->serviceCharByUUIDCB(event_data_length,
+                                            attr_handle,
+                                            attr_value);
+}
+
+void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle,
+                                            uint8_t event_data_length,
+                                            uint8_t format,
+                                            uint8_t *handle_uuid_pair) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->discAllCharacDescCB(event_data_length,
+                                            format,
+                                            handle_uuid_pair);
+}
+
+void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle,
+                                   uint8_t event_data_length,
+                                   uint8_t* attribute_value) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->charReadCB(event_data_length,
+                                   attribute_value);
+}
+
+void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle,
+                                           uint8_t event_data_length,
+                                           uint16_t attribute_handle,
+                                           uint16_t offset,
+                                           uint8_t *part_attr_value) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->charWritePrepareCB(event_data_length,
+                                           attribute_handle,
+                                           offset,
+                                           part_attr_value);
+}
+    
+void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle,
+                                        uint8_t event_data_length) {
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle);
+
+  assert(gattConnectionClient != NULL);
+
+  gattConnectionClient->charWriteExecCB(event_data_length);
+}
+
+ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t                               connectionHandle,
+                                                      ServiceDiscovery::ServiceCallback_t         sc,
+                                                      ServiceDiscovery::CharacteristicCallback_t  cc,
+                                                      const UUID                                 &matchingServiceUUID,
+                                                      const UUID                                 &matchingCharacteristicUUIDIn)
+{
+  PRINTF("BlueNRGGattClient launchServiceDiscovery\n\r");
+
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  if(gattConnectionClient != NULL) {
+    return gattConnectionClient->launchServiceDiscovery(sc, cc, matchingServiceUUID, matchingCharacteristicUUIDIn);
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+
+ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t                        connectionHandle,
+                                                ServiceDiscovery::ServiceCallback_t  callback,
+                                                const UUID                          &matchingServiceUUID)
+{
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  if(gattConnectionClient != NULL) {
+
+    return gattConnectionClient->discoverServices(callback, matchingServiceUUID);
+
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+
+ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t                        connectionHandle,
+                                                ServiceDiscovery::ServiceCallback_t  callback,
+                                                GattAttribute::Handle_t              startHandle,
+                                                GattAttribute::Handle_t              endHandle)
+{
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle);
+
+  if(gattConnectionClient != NULL) {
+
+    return gattConnectionClient->discoverServices(callback, startHandle, endHandle);
+
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+
+bool BlueNRGGattClient::isServiceDiscoveryActive(void) const
+{
+  bool isSDActive = false;
+
+  for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) {
+    if (_connectionPool[i]) { 
+      isSDActive |= _connectionPool[i]->isServiceDiscoveryActive();
+    }
+  }
+
+  return isSDActive;
+}
+
+void BlueNRGGattClient::terminateServiceDiscovery(void)
+{
+  for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) {
+    if (_connectionPool[i]) { 
+      _connectionPool[i]->terminateServiceDiscovery();
+    }
+  }
+}
+
+void BlueNRGGattClient::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) {
+  terminationCallback = callback;
+  for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; ++i) {
+    if (_connectionPool[i]) { 
+      _connectionPool[i]->onServiceDiscoveryTermination(callback);
+    }
+  }
+}
+
+ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const
+{
+  BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle);
+
+  if(gattConnectionClient != NULL) {
+
+    return gattConnectionClient->read(attributeHandle, offset);
+
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+
+ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t    cmd,
+                                     Gap::Handle_t            connHandle,
+                                     GattAttribute::Handle_t  attributeHandle,
+                                     size_t                   length,
+                                     const uint8_t           *value) const
+{
+  BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle);
+
+  if(gattConnectionClient != NULL) {
+
+    return gattConnectionClient->write(cmd, attributeHandle, length, value);
+
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+
+ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors(
+        const DiscoveredCharacteristic& characteristic,
+        const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
+        const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback)
+{
+  BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(characteristic.getConnectionHandle());
+
+  if(gattConnectionClient != NULL) {
+
+    return gattConnectionClient->discoverCharacteristicDescriptors(characteristic, discoveryCallback, terminationCallback);
+
+  } else {
+    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Clear BlueNRGGattClient's state.
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattClient::reset(void)
+{
+  PRINTF("BlueNRGGattClient::reset\n");
+
+  for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) {
+    if(_connectionPool[i] != NULL) {
+      _connectionPool[i]->reset();
+
+      delete _connectionPool[i];
+      _connectionPool[i] = NULL;
+
+      _numConnections--;
+    }
+  }
+
+  return BLE_ERROR_NONE;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,816 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/**
+  ******************************************************************************
+  * @file    BlueNRGGattServer.cpp
+  * @author  STMicroelectronics
+  * @brief   Implementation of BlueNRG BLE_API GattServer Class
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */
+
+/** @defgroup BlueNRGGattConnectionClient
+ *  @brief BlueNRG GattConnectionClient Adaptation
+ *  @{
+ */
+
+#include "BlueNRGGattConnectionClient.h"
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif 
+#include "BlueNRGGap.h" 
+#include "BlueNRGGattClient.h"
+#include "ble_utils.h"
+#include "ble_debug.h"
+
+// #define PRINTF printf
+
+static uint8_t props_mask[] = {
+  0x01,
+  0x02,
+  0x04,
+  0x08,
+  0x10,
+  0x20,
+  0x40,
+  0x80
+  };
+
+void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code)
+{
+  if(error_code != BLE_STATUS_SUCCESS) {
+    _currentState = GATT_IDLE;
+    return;
+  }
+
+  // Service Discovery complete
+/*
+  if(_currentState != GATT_IDLE &&
+     _currentState != GATT_DISCOVERY_TERMINATED &&
+     _currentState != GATT_WRITE_CHAR &&
+     _currentState != GATT_READ_CHAR) {
+*/
+  if(_currentState == GATT_SERVICE_DISCOVERY) {
+    findServiceChars();
+    return;
+  }
+
+  if(_currentState == GATT_CHAR_DESC_DISCOVERY) {
+      _currentState = GATT_IDLE;
+      if(charDescTerminationCallback != NULL) {
+         CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = {
+                                   _characteristic,
+                                   BLE_ERROR_NONE
+         };
+         charDescTerminationCallback(&params);
+       }
+      return;
+  }
+
+  // Read complete
+  if(_currentState == GATT_READ_CHAR) {
+    _currentState = GATT_IDLE;
+    BlueNRGGattClient::getInstance().processReadResponse(&readCBParams);
+    free((void*)(readCBParams.data));
+    readCBParams.data = NULL;
+    return;
+  }
+
+  // Write complete
+  if(_currentState == GATT_WRITE_CHAR) {
+    _currentState = GATT_IDLE;
+    BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
+    return;
+  }
+}
+
+void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length,
+                                                    uint8_t attribute_data_length,
+                                                    uint8_t *attribute_data_list)
+{
+  GattAttribute::Handle_t startHandle, endHandle;
+  UUID uuid;
+  uint8_t i, offset, numAttr;
+
+  numAttr = (event_data_length - 1) / attribute_data_length;
+
+  offset = 0;
+  for (i=0; i<numAttr; i++) {
+    startHandle = attribute_data_list[offset];
+    endHandle = attribute_data_list[offset+2];
+
+    // UUID Type
+    if (attribute_data_length == 6) {
+
+      PRINTF("UUID_TYPE_16\n\r");
+      uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4];
+      PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle);
+
+    } else {
+
+      PRINTF("UUID_TYPE_128\n\r");
+      uuid.setupLong(attribute_data_list+offset+4, UUID::LSB);
+
+#ifdef DEBUG
+      PRINTF("S UUID-");
+      const uint8_t *longUUIDBytes = uuid.getBaseUUID();
+      for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) {
+        PRINTF("%02x", longUUIDBytes[j]);
+      }
+#endif
+      PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle);
+
+    }
+
+    PRINTF("Setup serviceIndex = %d\n\r", _numServices);
+    discoveredService[_numServices].setup(uuid, startHandle, endHandle);
+
+    _numServices++;
+
+    offset += attribute_data_length;
+  }
+
+  PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr);
+
+}
+
+void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list)
+{
+  GattAttribute::Handle_t startHandle, endHandle;
+  UUID uuid;
+  uint8_t i, offset, numHandlePairs;
+
+  numHandlePairs = (event_data_length - 1) / 2;
+
+  offset = 0;
+  for (i=0; i<numHandlePairs; i++) {
+    startHandle = handles_info_list[offset];
+    endHandle = handles_info_list[offset+2];
+
+    PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle);
+
+
+    if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) {
+        PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle);
+        uuid = _matchingServiceUUID.getShortUUID();
+    } else {
+#ifdef DEBUG
+        PRINTF("S UUID-");
+        const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID();
+        for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+            PRINTF("%02x", longUUIDBytes[i]);
+        }
+#endif
+        PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle);
+        uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB);
+    }
+
+    discoveredService[i].setup(uuid, startHandle, endHandle);
+
+    _numServices++;
+
+    offset += 4;
+  }
+}
+
+void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length,
+                                                 uint8_t handle_value_pair_length,
+                                                 uint8_t *handle_value_pair)
+{
+  // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16)
+
+  GattAttribute::Handle_t declHandle, valueHandle, lastHandle;
+  UUID uuid;
+  uint8_t i, numChar, offset;
+
+  numChar = (event_data_length - 1) / handle_value_pair_length;
+
+  PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar);
+
+  offset = 0;
+  for (i=0; i<numChar; i++) {
+    // UUID Type
+    if (handle_value_pair_length == 7) {
+      PRINTF("Char UUID_TYPE_16\n\r");
+      uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5];
+      PRINTF("C UUID-%X\r\n", uuid.getShortUUID());
+    } else {
+      PRINTF("Char UUID_TYPE_128\n\r");
+      uuid.setupLong(handle_value_pair+offset+5, UUID::LSB);
+#ifdef DEBUG
+      PRINTF("C UUID-");
+      const uint8_t *longUUIDBytes = uuid.getBaseUUID();
+      for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+        PRINTF("%02X", longUUIDBytes[i]);
+      }
+      PRINTF("\r\n");
+#endif
+    }
+
+    // Properties
+    DiscoveredCharacteristic::Properties_t p;
+
+    p._broadcast = (props_mask[0] & handle_value_pair[offset+2]);
+    p._read = (props_mask[1] & handle_value_pair[offset+2])>>1;
+    p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2;
+    p._write = (props_mask[3] & handle_value_pair[offset+2])>>3;
+    p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4;
+    p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5;
+    p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6;
+    PRINTF("p._broadcast=%d\n\r", p._broadcast);
+    PRINTF("p._read=%d\n\r", p._read);
+    PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp);
+    PRINTF("p._write=%d\n\r", p._write);
+    PRINTF("p._notify=%d\n\r", p._notify);
+    PRINTF("p._indicate=%d\n\r", p._indicate);
+    PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite);
+
+    /*
+    uint8_t props = handle_value_pair[offset+2];
+    PRINTF("CHAR PROPS: %d\n\r", props);
+    */
+
+    // Handles
+    declHandle = handle_value_pair[offset];
+    valueHandle = handle_value_pair[offset+3];
+    lastHandle = valueHandle+1;
+    PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle);
+
+    discoveredChar[_numChars].setup(_gattClient,
+                                    _connectionHandle,
+                                    uuid,
+                                    p,
+                                    declHandle,
+                                    valueHandle,
+                                    lastHandle);
+
+    if (_numChars != 0) {
+        discoveredChar[_numChars - 1].setLastHandle(declHandle - 1);
+
+        if(characteristicDiscoveryCallback) {
+          characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]);
+        }
+    }
+
+    _numChars++;
+
+    offset += handle_value_pair_length;
+  }
+}
+
+void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length,
+                                                      uint16_t attr_handle,
+                                                      uint8_t *attr_value)
+{
+  // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16)
+  GattAttribute::Handle_t declHandle, valueHandle, lastHandle;
+  UUID uuid;
+
+  PRINTF("serviceCharByUUIDCB\n\r");
+
+  // UUID Type
+  if (event_data_length == 7) {
+    PRINTF("Char UUID_TYPE_16\n\r");
+    uuid = attr_value[4]<<8|attr_value[3];
+    PRINTF("C UUID-%X\r\n", uuid.getShortUUID());
+  } else {
+    PRINTF("Char UUID_TYPE_128\n\r");
+    uuid.setupLong(attr_value+3, UUID::LSB);
+#ifdef DEBUG
+    PRINTF("C UUID-");
+    const uint8_t *longUUIDBytes = uuid.getBaseUUID();
+    for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+      PRINTF("%02X", longUUIDBytes[i]);
+    }
+    PRINTF("\r\n");
+#endif
+  }
+
+  // Properties
+  DiscoveredCharacteristic::Properties_t p;
+
+  p._broadcast = (props_mask[0] & attr_value[0]);
+  p._read = (props_mask[1] & attr_value[0])>>1;
+  p._writeWoResp = (props_mask[2] & attr_value[0])>>2;
+  p._write = (props_mask[3] & attr_value[0])>>3;
+  p._notify = (props_mask[4] & attr_value[0])>>4;
+  p._indicate = (props_mask[5] & attr_value[0])>>5;
+  p._authSignedWrite = (props_mask[6] & attr_value[0])>>6;
+  PRINTF("p._broadcast=%d\n\r", p._broadcast);
+  PRINTF("p._read=%d\n\r", p._read);
+  PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp);
+  PRINTF("p._write=%d\n\r", p._write);
+  PRINTF("p._notify=%d\n\r", p._notify);
+  PRINTF("p._indicate=%d\n\r", p._indicate);
+  PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite);
+
+  /*
+  uint8_t props = attr_value[0];
+  PRINTF("CHAR PROPS: %d\n\r", props);
+  */
+
+  // Handles
+  declHandle = attr_handle;
+  valueHandle = attr_value[1];
+  lastHandle = valueHandle+1;
+
+  discoveredChar[_numChars].setup(_gattClient,
+                                  _connectionHandle,
+                                  uuid,
+                                  p,
+                                  declHandle,
+                                  valueHandle,
+                                  lastHandle);
+
+  // update the last handle and call the characteristic discovery callback for previous char
+  if (_numChars != 0) {
+    discoveredChar[_numChars - 1].setLastHandle(declHandle - 1);
+
+    if(characteristicDiscoveryCallback) {
+      characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]);
+    }
+  }
+
+  _numChars++;
+}
+
+ble_error_t BlueNRGGattConnectionClient::findServiceChars(void)
+{
+  PRINTF("findServiceChars\n\r");
+
+  tBleStatus ret;
+  uint8_t uuid_type = UUID_TYPE_16;
+  uint8_t short_uuid[2];
+  uint8_t *uuid = NULL;
+
+  DiscoveredService *service;
+
+  // complete the discovery of the last characteristic of the previous service.
+  // Its last handle wasn't known before this point
+  // update the handle and call the characteristic discovery callback.
+  if (_servIndex != 0 && _numChars != 0) {
+      discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle());
+
+      if(characteristicDiscoveryCallback) {
+        characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]);
+      }
+  }
+
+  _numChars = 0;
+
+  // We finished chars discovery for all services
+  if(_servIndex >= _numServices) {
+    PRINTF("!!!We finished chars discovery for all services!!!\n\r");
+    //_currentState = GATT_CHARS_DISCOVERY_COMPLETE;
+
+    terminateServiceDiscovery();
+
+    return BLE_ERROR_NONE;
+  }
+
+  service = &discoveredService[_servIndex];
+  /*
+  if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
+    PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID());
+  } else {
+    PRINTF("S UUID-");
+    const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
+    for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+      PRINTF("%02X", longUUIDBytes[i]);
+    }
+    PRINTF("\r\n");
+  }
+  */
+
+  if(serviceDiscoveryCallback) {
+    serviceDiscoveryCallback(service);
+  }
+
+  PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex);
+  //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
+
+    if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) {
+        PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r");
+        ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle());
+    } else {
+
+        uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong();
+
+        if(type == UUID::UUID_TYPE_SHORT) {
+            STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID());
+
+            uuid_type = UUID_TYPE_16;
+            uuid = short_uuid;
+#ifdef DEBUG
+            PRINTF("findServiceChars C UUID-");
+            for(unsigned i = 0; i < 2; i++) {
+                PRINTF("%02X", short_uuid[i]);
+            }
+            PRINTF("\n\r");
+#endif
+        } else if(type==UUID::UUID_TYPE_LONG) {
+
+            uuid_type = UUID_TYPE_128;
+            uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID();
+#ifdef DEBUG
+            PRINTF("(findServiceChars) C UUID-");
+            for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+                PRINTF("%02X", uuid[i]);
+            }
+            PRINTF("\r\n");
+#endif
+        }
+
+        ret = aci_gatt_disc_charac_by_uuid(_connectionHandle,
+                                           service->getStartHandle(),
+                                           service->getEndHandle(),
+                                           uuid_type,
+                                           uuid);
+    }
+
+  if(ret == BLE_STATUS_SUCCESS) {
+    _servIndex++;
+  }
+
+  PRINTF("findServiceChars ret=%d\n\r", ret);
+
+  return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t         sc,
+                                                                ServiceDiscovery::CharacteristicCallback_t  cc,
+                                                                const UUID                                 &matchingServiceUUID,
+                                                                const UUID                                 &matchingCharacteristicUUIDIn)
+{
+  PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r");
+
+  tBleStatus ret;
+  uint8_t uuid_type = UUID_TYPE_16;
+  uint8_t short_uuid[2];
+  uint8_t *uuid = NULL;
+  unsigned j;
+
+  if(isServiceDiscoveryActive()) {
+    return BLE_ERROR_OPERATION_NOT_PERMITTED;
+  }
+
+  if(!sc && !cc) {
+    // nothing to do
+    PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r");
+    return BLE_ERROR_NONE;
+  }
+
+  serviceDiscoveryCallback = sc;
+  characteristicDiscoveryCallback = cc;
+  _matchingServiceUUID = matchingServiceUUID;
+  _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn;
+
+  //reset services
+  _numServices = 0;
+  _numChars = 0;
+  _servIndex = 0;
+  for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) {
+    discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE);
+  }
+
+  if(matchingServiceUUID == BLE_UUID_UNKNOWN) {
+
+    // Wildcard: search for all services
+    PRINTF("Wildcard: search for all services\r\n");
+    ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle);
+
+  } else {
+    PRINTF("search for specific services\r\n");
+
+    uint8_t type = matchingServiceUUID.shortOrLong();
+
+    if(type == UUID::UUID_TYPE_SHORT) {
+      STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID());
+#ifdef DEBUG
+      PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x");
+      for(j = 0; j < 2; j++) {
+        PRINTF("%02X", short_uuid[j]);
+      }
+      PRINTF("\n\r");
+#endif
+
+      uuid_type = UUID_TYPE_16;
+      uuid = short_uuid;
+
+    } else if(type==UUID::UUID_TYPE_LONG) {
+
+      uuid_type = UUID_TYPE_128;
+      uuid = (unsigned char*)matchingServiceUUID.getBaseUUID();
+
+#ifdef DEBUG
+      PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x");
+      for(j = 0; j < 16; j++) {
+        PRINTF("%02X", uuid[j]);
+      }
+      PRINTF("\n\r");
+#endif
+    }
+
+    // search for specific service by UUID
+    ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid);
+  }
+
+  if(ret == BLE_STATUS_SUCCESS) {
+    _currentState = GATT_SERVICE_DISCOVERY;
+  }
+
+  PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret);
+
+  return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t  callback,
+                                                          const UUID                          &matchingServiceUUID)
+{
+  /* avoid compiler warnings about unused variables */
+  (void)callback;
+  (void)matchingServiceUUID;
+
+  return BLE_ERROR_NOT_IMPLEMENTED;
+}
+
+ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t  callback,
+                                                          GattAttribute::Handle_t              startHandle,
+                                                          GattAttribute::Handle_t              endHandle)
+{
+  /* avoid compiler warnings about unused variables */
+  (void)callback;
+  (void)startHandle;
+  (void)endHandle;
+
+  return BLE_ERROR_NOT_IMPLEMENTED;
+}
+
+bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const
+{
+  if(_currentState == GATT_SERVICE_DISCOVERY) {
+    return true;
+  }
+
+  return false;
+}
+
+void BlueNRGGattConnectionClient::terminateServiceDiscovery(void)
+{
+  _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED;
+
+  if (terminationCallback) {
+    terminationCallback(_connectionHandle);
+  }
+}
+
+void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value)
+{
+  // copy the data read, they will be forwarded to the user once the procedure
+  // has completed
+  readCBParams.connHandle = _connectionHandle;
+  readCBParams.offset = 0;
+  readCBParams.len = event_data_length;
+  readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length));
+  memcpy((void*)(readCBParams.data), attribute_value, event_data_length);
+}
+
+ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const
+{
+  /* avoid compiler warnings about unused variables */
+  (void)offset;
+
+  tBleStatus ret;
+
+  BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this);
+
+  // Save the attribute_handle not provided by evt_att_read_resp
+  gattc->readCBParams.handle = attributeHandle;
+
+  ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle);
+
+  if(ret == BLE_STATUS_SUCCESS) {
+    gattc->_currentState = GATT_READ_CHAR;
+    return BLE_ERROR_NONE;
+  }
+  switch (ret) {
+  case ERR_CONTROLLER_BUSY:
+    return BLE_STACK_BUSY;
+  default:
+    return BLE_ERROR_INVALID_STATE;
+  }
+}
+
+void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length,
+                                                     uint16_t attribute_handle,
+                                                     uint16_t offset,
+                                                     uint8_t *part_attr_value)
+{
+  // Update the write response params
+  writeCBParams.handle = attribute_handle;
+  writeCBParams.offset = offset;
+  writeCBParams.len = event_data_length-4; //(?)
+  writeCBParams.data = part_attr_value;
+
+  BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
+}
+
+void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length)
+{
+  /* avoid compiler warnings about unused variables */
+  (void)event_data_length;
+
+  writeCBParams.connHandle = _connectionHandle;
+
+  BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
+}
+
+ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t    cmd,
+                                     GattAttribute::Handle_t  attributeHandle,
+                                     size_t                   length,
+                                     const uint8_t           *value) const
+{
+  /* avoid compiler warnings about unused variables */
+  (void)cmd;
+
+  tBleStatus ret;
+
+  BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this);
+
+  // We save the write response params (used by the callback) because
+  // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE
+  gattc->writeCBParams.connHandle = _connectionHandle;
+  gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD;
+  gattc->writeCBParams.handle = attributeHandle;
+  gattc->writeCBParams.offset = 0;
+  gattc->writeCBParams.len = length;
+  gattc->writeCBParams.data = value;
+
+  ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value));
+
+  if (ret == BLE_STATUS_SUCCESS) {
+    gattc->_currentState = GATT_WRITE_CHAR;
+    return BLE_ERROR_NONE;
+  }
+  switch (ret) {
+  case ERR_CONTROLLER_BUSY:
+    return BLE_STACK_BUSY;
+  default:
+    return BLE_ERROR_INVALID_STATE;
+  }
+
+}
+
+void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length,
+                                                      uint8_t format,
+                                                      uint8_t *handle_uuid_pair) {
+  GattAttribute::Handle_t attHandle;
+  UUID uuid;
+  uint8_t i, numCharacDesc, offset, handle_uuid_length;
+
+  handle_uuid_length = 4; //Handle + UUID_16
+  if (format == 2)
+    handle_uuid_length = 18; //Handle + UUID_128
+
+  numCharacDesc = (event_data_length - 1) / handle_uuid_length;
+
+  offset = 0;
+
+  PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n",
+    event_data_length, format);
+
+
+  for (i=0; i<numCharacDesc; i++) {
+    memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle));
+
+    // UUID Type
+    if (handle_uuid_length == 4) {
+
+      PRINTF("UUID_TYPE_16\n\r");
+      uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2];
+      PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle);
+
+    } else {
+
+      PRINTF("UUID_TYPE_128\n\r");
+      uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB);
+#ifdef DEBUG
+      PRINTF("D UUID-");
+      const uint8_t *longUUIDBytes = uuid.getBaseUUID();
+      for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) {
+        PRINTF("%02x", longUUIDBytes[j]);
+      }
+#endif
+     }
+
+     if(charDescDiscoveryCallback != NULL) {
+       CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = {
+                                 _characteristic,
+                                 DiscoveredCharacteristicDescriptor(
+                                   _characteristic.getGattClient(),
+                                   _connectionHandle,
+                                   attHandle,
+                                   uuid
+                                 )
+       };
+       charDescDiscoveryCallback(&params);
+     }
+
+    _numCharDesc++;
+
+    offset += handle_uuid_length;
+  }
+}
+
+ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors(
+        const DiscoveredCharacteristic& characteristic,
+        const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
+        const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) {
+
+  tBleStatus ret;
+
+  if(_currentState != GATT_IDLE) {
+    return BLE_ERROR_OPERATION_NOT_PERMITTED;
+  }
+
+  charDescDiscoveryCallback = discoveryCallback;
+  charDescTerminationCallback = terminationCallback;
+
+  GattAttribute::Handle_t valueHandle = characteristic.getValueHandle();
+  GattAttribute::Handle_t lastHandle = characteristic.getLastHandle();
+
+  PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle);
+  ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle);
+
+  if (ret == BLE_STATUS_SUCCESS) {
+    _currentState = GATT_CHAR_DESC_DISCOVERY;
+    _characteristic = characteristic;
+    return BLE_ERROR_NONE;
+  }
+  switch (ret) {
+  case BLE_STATUS_INVALID_PARAMS:
+    return BLE_ERROR_INVALID_PARAM;
+  default:
+    return BLE_ERROR_OPERATION_NOT_PERMITTED;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Clear BlueNRGGattServer's state.
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattConnectionClient::reset(void) {
+  PRINTF("BlueNRGGattConnectionClient::reset\n");
+
+  /* Clear all state, including private members */
+
+  _currentState = GATT_IDLE;
+  _matchingServiceUUID = BLE_UUID_UNKNOWN;
+  _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN;
+
+  _numServices = 0;
+  _servIndex = 0;
+  _numChars = 0;
+  _numCharDesc = 0;
+
+  /* Clear class members */
+  memset(discoveredService, 0, sizeof(discoveredService));
+  memset(discoveredChar, 0, sizeof(discoveredChar));
+
+  // free response if allocated
+  if(readCBParams.data) {
+    free((void*)(readCBParams.data));
+  }
+
+  return BLE_ERROR_NONE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,755 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/**
+  ******************************************************************************
+  * @file    BlueNRGGattServer.cpp
+  * @author  STMicroelectronics
+  * @brief   Implementation of BlueNRG BLE_API GattServer Class
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */
+
+/** @defgroup BlueNRGGATTSERVER
+ *  @brief BlueNRG BLE_API GattServer Adaptation
+ *  @{
+ */
+
+#include "BlueNRGGattServer.h"
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif 
+#include "BlueNRGGap.h"
+#include "ble_utils.h"
+#include "ble_debug.h"
+
+/**************************************************************************/
+/*!
+    @brief  Adds a new service to the GATT table on the peripheral
+
+    @params[in] service
+                Pointer to instance of the Gatt Server to add
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattServer::addService(GattService &service)
+{
+    /* ToDo: Make sure we don't overflow the array, etc. */
+    /* ToDo: Make sure this service UUID doesn't already exist (?) */
+    /* ToDo: Basic validation */
+
+    tBleStatus ret;
+    uint8_t type;
+    uint16_t short_uuid;
+    uint8_t primary_short_uuid[2];
+    uint8_t primary_base_uuid[16];
+    uint8_t char_base_uuid[16];
+    const uint8_t *base_uuid;
+    const uint8_t *base_char_uuid;
+
+    uint8_t charsCount = service.getCharacteristicCount();
+    const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount;
+
+    // check that there is enough characteristics left in the
+    // characteristic array.
+    if (charsCount > available_characteristics) {
+        PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics);
+        return BLE_ERROR_NO_MEM;
+    }
+
+    const uint16_t maxAttrRecords = computeAttributesRecord(service);
+
+    type = (service.getUUID()).shortOrLong();
+    PRINTF("AddService(): Type:%d\n\r", type);
+
+    /* Add the service to the BlueNRG */
+    short_uuid = (service.getUUID()).getShortUUID();
+    STORE_LE_16(primary_short_uuid, short_uuid);
+
+    if(type==UUID::UUID_TYPE_LONG) {
+        base_uuid = (service.getUUID()).getBaseUUID();
+
+        COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]);
+    }
+
+    ret = BLE_STATUS_SUCCESS;
+
+    if(type==UUID::UUID_TYPE_SHORT) {
+        ret = aci_gatt_add_serv(UUID_TYPE_16,
+                                primary_short_uuid,
+                                PRIMARY_SERVICE,
+                                maxAttrRecords/*7*/,
+                                &servHandle);
+        PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret);
+
+    } else if(type==UUID::UUID_TYPE_LONG) {
+        ret = aci_gatt_add_serv(UUID_TYPE_128,
+                                primary_base_uuid,
+                                PRIMARY_SERVICE,
+                                maxAttrRecords/*7*/,
+                                &servHandle);
+        PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret);
+    }
+
+    switch (ret) {
+        case BLE_STATUS_SUCCESS:
+            break;
+
+        case BLE_STATUS_INVALID_PARAMETER:
+            return BLE_ERROR_INVALID_PARAM;
+
+        case BLE_STATUS_OUT_OF_HANDLE:
+        case BLE_STATUS_INSUFFICIENT_RESOURCES:
+        case ERR_UNSPECIFIED_ERROR:
+            return BLE_ERROR_NO_MEM;
+
+        case BLE_STATUS_ERROR:
+        default:
+            return BLE_ERROR_INTERNAL_STACK_FAILURE;
+    }
+
+
+
+    service.setHandle(servHandle);
+    //serviceHandleVector.push_back(servHandle);
+    PRINTF("added servHandle handle =%u\n\r", servHandle);
+    uint16_t bleCharacteristic;
+
+    //iterate to include all characteristics
+    for (uint8_t i = 0; i < charsCount; i++) {
+        GattCharacteristic *p_char = service.getCharacteristic(i);
+        uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID();
+
+        uint8_t int_8_uuid[2];
+        STORE_LE_16(int_8_uuid, char_uuid);
+
+        type = (p_char->getValueAttribute().getUUID()).shortOrLong();
+
+        if(type==UUID::UUID_TYPE_LONG) {
+            base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID();
+#ifdef DEBUG
+            for(uint8_t j=0; j<16; j++) {
+                PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]);
+            }
+            PRINTF("\n\r");
+#endif
+            COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]);
+        }
+
+        PRINTF("Char Properties 0x%x\n\r", p_char->getProperties());
+        /*
+        * Gatt_Evt_Mask -> HardCoded (0)
+        * Encryption_Key_Size -> Hardcoded (16)
+        * isVariable (variable length value field) -> Hardcoded (1)
+        */
+        uint8_t Gatt_Evt_Mask = 0x0;
+
+        if((p_char->getProperties() &
+                    (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE|
+                        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) {
+            PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r");
+            Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE  | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP;
+        }
+        if((p_char->getProperties() &
+                    (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ|
+                        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) {
+            PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r");
+            Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP;
+        }    //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check.
+
+        if(type==UUID::UUID_TYPE_SHORT) {
+            ret =  aci_gatt_add_char(service.getHandle(),
+                                     UUID_TYPE_16,
+                                     int_8_uuid,
+                                     p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/,
+                                     p_char->getProperties(),
+                                     ATTR_PERMISSION_NONE,
+                                     Gatt_Evt_Mask /*Gatt_Evt_Mask*/,
+                                     16 /*Encryption_Key_Size*/,
+                                     1 /*isVariable*/,
+                                     &bleCharacteristic);
+
+            PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r",
+                    p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
+
+        } else if(type==UUID::UUID_TYPE_LONG) {
+            ret =  aci_gatt_add_char(service.getHandle(),
+                                     UUID_TYPE_128,
+                                     char_base_uuid,
+                                     p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/,
+                                     p_char->getProperties(),
+                                     ATTR_PERMISSION_NONE,
+                                     Gatt_Evt_Mask /*Gatt_Evt_Mask*/,
+                                     16 /*Encryption_Key_Size*/,
+                                     1 /*isVariable*/,
+                                     &bleCharacteristic);
+
+            PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r",
+                    p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
+        }
+
+        switch (ret) {
+            case BLE_STATUS_SUCCESS:
+                break;
+
+            case ERR_UNSPECIFIED_ERROR:
+            case BLE_STATUS_INSUFFICIENT_RESOURCES:
+            case BLE_STATUS_OUT_OF_HANDLE:
+                // TODO remove characteristics and the service previously added.
+                // remove service in the stack by using: Aci_Gatt_Del_Service
+                // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+                // update service counter
+                // destroy registered characteristic and updat echaracteristic counter
+                return BLE_ERROR_NO_MEM;
+
+            case BLE_STATUS_INVALID_HANDLE:
+            case BLE_STATUS_INVALID_PARAMETER:
+            case BLE_STATUS_CHARAC_ALREADY_EXISTS:
+            // TODO remove characteristics and the service previously added.
+            // remove service in the stack by using: Aci_Gatt_Del_Service
+            // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+            // update service counter
+            // destroy registered characteristic and updat echaracteristic counter
+                return BLE_ERROR_INVALID_PARAM;
+
+            case BLE_STATUS_ERROR:
+            default:
+            // TODO remove characteristics and the service previously added.
+            // remove service in the stack by using: Aci_Gatt_Del_Service
+            // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+            // update service counter
+            // destroy registered characteristic and updat echaracteristic counter
+                return BLE_ERROR_INTERNAL_STACK_FAILURE;
+        }
+
+        bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle));
+
+        p_characteristics[characteristicCount++] = p_char;
+        /* Set the characteristic value handle */
+        p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE);
+        PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle());
+
+        if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) {
+            ble_error_t err = write(p_char->getValueAttribute().getHandle(),
+                  p_char->getValueAttribute().getValuePtr(),
+                  p_char->getValueAttribute().getLength(), false /* localOnly */);
+            if (err) {
+                PRINTF("ERROR HERE !!!!\r\n");
+                return err;
+            }
+        }
+
+        // add descriptors now
+        uint16_t descHandle = 0;
+        PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount());
+
+        for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) {
+            GattAttribute *descriptor = p_char->getDescriptor(descIndex);
+            uint8_t desc_uuid[16] = { 0 };
+
+
+            uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT;
+            STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID());
+
+            if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) {
+                desc_uuid_type = CHAR_DESC_TYPE_128_BIT;
+                const uint8_t* base_desc_uuid  = descriptor->getUUID().getBaseUUID();
+
+                COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]);
+            }
+
+            ret = aci_gatt_add_char_desc(service.getHandle(),
+                                         bleCharacteristic,
+                                         desc_uuid_type,
+                                         desc_uuid,
+                                         descriptor->getMaxLength(),
+                                         descriptor->getLength(),
+                                         descriptor->getValuePtr(),
+                                         CHAR_DESC_SECURITY_PERMISSION,
+                                         CHAR_DESC_ACCESS_PERMISSION,
+                                         GATT_NOTIFY_ATTRIBUTE_WRITE,
+                                         MIN_ENCRY_KEY_SIZE,
+                                         CHAR_ATTRIBUTE_LEN_IS_FIXED,
+                                         &descHandle);
+            PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret);
+
+            switch (ret) {
+                case BLE_STATUS_SUCCESS:
+                    PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle);
+                    descriptor->setHandle(descHandle);
+                    break;
+
+                case ERR_UNSPECIFIED_ERROR:
+                case BLE_STATUS_INSUFFICIENT_RESOURCES:
+                case BLE_STATUS_OUT_OF_HANDLE:
+                    // TODO remove characteristics and the service previously added.
+                    // remove service in the stack by using: Aci_Gatt_Del_Service
+                    // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+                    // update service counter
+                    // destroy registered characteristic and updat echaracteristic counter
+                    return BLE_ERROR_NO_MEM;
+
+                case BLE_STATUS_INVALID_HANDLE:
+                case BLE_STATUS_INVALID_PARAMETER:
+                // TODO remove characteristics and the service previously added.
+                // remove service in the stack by using: Aci_Gatt_Del_Service
+                // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+                // update service counter
+                // destroy registered characteristic and updat echaracteristic counter
+                    return BLE_ERROR_INVALID_PARAM;
+
+                case BLE_STATUS_INVALID_OPERATION:
+                    return BLE_ERROR_OPERATION_NOT_PERMITTED;
+
+                case BLE_STATUS_ERROR:
+                default:
+                // TODO remove characteristics and the service previously added.
+                // remove service in the stack by using: Aci_Gatt_Del_Service
+                // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+                // update service counter
+                // destroy registered characteristic and updat echaracteristic counter
+                    return BLE_ERROR_INTERNAL_STACK_FAILURE;
+            }
+        }
+    }
+
+    serviceCount++;
+
+    //FIXME: There is no GattService pointer array in GattServer.
+    //        There should be one? (Only the user is aware of GattServices!) Report to forum.
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the value of a characteristic, based on char handle
+
+    @param[in]  attributeHandle
+                The handle of the GattCharacteristic to read from
+    @param[in]  buffer
+                Buffer to hold the the characteristic's value
+                (raw byte array in LSB format)
+    @param[in]  lengthP
+                The number of bytes read into the buffer
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
+{
+  tBleStatus ret;
+  uint16_t charHandle = attributeHandle;
+
+  ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer);
+
+  if(ret == BLE_STATUS_SUCCESS) {
+    return BLE_ERROR_NONE;
+  }
+  switch (ret) {
+  case ERR_INVALID_HCI_CMD_PARAMS:
+    return BLE_ERROR_INVALID_PARAM;
+  default:
+    return BLE_ERROR_UNSPECIFIED;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the value of a characteristic, based on the connection
+            and char handle
+
+    @param[in]  connectionHandle
+                The handle of the connection
+    @param[in]  attributeHandle
+                The handle of the GattCharacteristic to write to
+    @param[in]  buffer
+                Data to use when updating the characteristic's value
+                (raw byte array in LSB format)
+    @param[in]  lengthP
+                The number of bytes in buffer
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle,
+                                    GattAttribute::Handle_t attributeHandle,
+                                    uint8_t buffer[],
+                                    uint16_t *lengthP) {
+
+  /* avoid compiler warnings about unused variables */
+  (void)connectionHandle;
+  (void)attributeHandle;
+  (void)buffer;
+  (void)lengthP;
+
+  return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle,
+                                     GattAttribute::Handle_t,
+                                     const uint8_t[],
+                                     uint16_t, bool localOnly) {
+  /* avoid compiler warnings about unused variables */
+  (void)connectionHandle;
+  (void)localOnly;
+
+  return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
+{
+    /* avoid compiler warnings about unused variables */
+    (void)localOnly;
+
+    // check that the len of the data to write are compatible with the characteristic
+    GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle);
+    if (!characteristic) {
+        PRINTF("characteristic not found\r\n");
+        return BLE_ERROR_INVALID_PARAM;
+    }
+
+    // if the attribute handle is the attribute handle of the characteristic value then
+    // write the value
+    if (attributeHandle == characteristic->getValueHandle()) {
+        // assert the len in input is correct for this characteristic
+        const GattAttribute& value_attribute = characteristic->getValueAttribute();
+
+        // reject write if the lenght exceed the maximum lenght of this attribute
+        if (value_attribute.getMaxLength() < len) {
+            PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength());
+            return BLE_ERROR_INVALID_PARAM;
+        }
+
+        // reject write if the attribute size is fixed and the lenght in input is different than the
+        // length of the attribute.
+        if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) {
+            PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength());
+            return BLE_ERROR_INVALID_PARAM;
+        }
+
+        tBleStatus ret;
+
+        uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE;
+
+        PRINTF("updating bleCharacteristic valueHandle=%u,\
+                corresponding serviceHandle=%u len=%d\n\r",
+                attributeHandle, bleCharHandleMap.find(charHandle)->second, len);
+
+        /*
+         * If notifications (or indications) are enabled on that characteristic, a notification (or indication)
+         * will be sent to the client after sending this command to the BlueNRG.
+         */
+        ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer);
+
+        if (ret != BLE_STATUS_SUCCESS){
+          PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret);
+          switch (ret) {
+            case BLE_STATUS_INVALID_HANDLE:
+            case BLE_STATUS_INVALID_PARAMETER:
+              return BLE_ERROR_INVALID_PARAM;
+            default:
+              return BLE_STACK_BUSY;
+          }
+        }
+
+        return BLE_ERROR_NONE;
+    } else {
+        // write this handle has a descriptor handle
+        uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE;
+        uint16_t service_handle = bleCharHandleMap.find(charHandle)->second;
+
+        tBleStatus ret = aci_gatt_set_desc_value(
+            service_handle,
+            charHandle,
+            attributeHandle,
+            0,
+        	len,
+        	buffer
+        );
+
+        if (ret != BLE_STATUS_SUCCESS){
+          PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret);
+          switch (ret) {
+            case BLE_STATUS_INVALID_HANDLE:
+            case BLE_STATUS_INVALID_PARAMETER:
+              return BLE_ERROR_INVALID_PARAM;
+            default:
+              return BLE_STACK_BUSY;
+          }
+        }
+
+        return BLE_ERROR_NONE;
+    }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a value according to the handle provided
+
+    @param[in]  attributeHandle
+                The handle of the attribute to read from
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle)
+{
+    uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle();
+
+    GattReadCallbackParams readParams;
+    readParams.handle = attributeHandle;
+
+    //PRINTF("readParams.handle = %d\n\r", readParams.handle);
+    HCIDataReadEvent(&readParams);
+
+    //EXIT:
+    if(gapConnectionHandle != 0){
+        //PRINTF("Calling aci_gatt_allow_read\n\r");
+        aci_gatt_allow_read(gapConnectionHandle);
+    }
+
+    return BLE_ERROR_NONE;
+}
+
+// ask if the write request should be accepted of rejected
+// return 0 in case of success or an ATT error response in
+// case of faillure
+uint8_t BlueNRGGattServer::Write_Request_CB(
+    uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length,
+    const uint8_t* data) {
+
+    GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle);
+    if(!characteristic) {
+        return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF;
+    }
+
+    // check if the data length is in range
+    if (characteristic->getValueAttribute().getMaxLength() < data_length) {
+        return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF;
+    }
+
+    // if the length of the characteristic value is fixed
+    // then the data in input should be of that length
+    if (characteristic->getValueAttribute().hasVariableLength() == false &&
+        characteristic->getValueAttribute().getMaxLength() != data_length) {
+        return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF;
+    }
+
+    GattWriteAuthCallbackParams params = {
+        connection_handle,
+        attr_handle,
+        /* offset */ 0,
+        data_length,
+        data,
+        /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED
+    };
+
+    return characteristic->authorizeWrite(&params) & 0xFF;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Returns the GattCharacteristic according to the handle provided
+
+    @param[in]  attrHandle
+                The handle of the attribute
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle)
+{
+    GattCharacteristic *p_char = NULL;
+    int i;
+    uint16_t handle, handle_1;
+
+    PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle);
+    for(i=0; i<characteristicCount; i++)
+    {
+        handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
+        PRINTF("handle(%d)=%d\n\r", i, handle);
+        if(i==characteristicCount-1)//Last Characteristic check
+        {
+            if(attrHandle>=handle)
+            {
+                p_char = p_characteristics[i];
+                PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle);
+                break;
+            }
+        }
+        else {
+            handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
+            //Testing if attribute handle is between two Characteristic Handles
+            if(attrHandle>=handle && attrHandle<handle_1)
+            {
+                p_char = p_characteristics[i];
+                PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1);
+                break;
+            } else continue;
+        }
+    }
+
+    return p_char;
+}
+
+void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) {
+    this->handleDataWrittenEvent(params);
+}
+
+void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) {
+    PRINTF("Called HCIDataReadEvent\n\r");
+    this->handleDataReadEvent(params);
+}
+
+void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) {
+    this->handleEvent(type, charHandle);
+}
+
+void BlueNRGGattServer::HCIDataSentEvent(unsigned count) {
+    this->handleDataSentEvent(count);
+}
+
+
+ble_error_t BlueNRGGattServer::initializeGATTDatabase(void)   {
+    // <TODO>
+    return (ble_error_t)0;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Clear BlueNRGGattServer's state.
+
+    @returns    ble_error_t
+
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattServer::reset(void)
+{
+    PRINTF("BlueNRGGattServer::reset\n");
+
+    /* Clear all state that is from the parent, including private members */
+    if (GattServer::reset() != BLE_ERROR_NONE) {
+        return BLE_ERROR_INVALID_STATE;
+    }
+
+    /* Clear class members */
+    memset(p_characteristics,        0, sizeof(p_characteristics));
+    memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles));
+    serviceCount = 0;
+    characteristicCount = 0;
+
+    return BLE_ERROR_NONE;
+}
+
+
+/// compute the number of attributes needed by this service.
+uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) {
+    uint16_t attribute_records = 1;
+
+    for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) {
+        // add two attributes, one for the characteristic declaration
+        // and the other for the characteristic value.
+        attribute_records += 2;
+
+        const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index);
+        const uint8_t properties = characteristic->getProperties();
+        // if notify or indicate are present, two attributes are
+        // needed
+        if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ||
+            (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) {
+            attribute_records += 2;
+        }
+
+        // if broadcast is set, two attributes are needed
+        if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) {
+            attribute_records += 2;
+        }
+
+        // if extended properties flag is set, two attributes are needed
+        if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) {
+            attribute_records += 2;
+        }
+
+        attribute_records += characteristic->getDescriptorCount();
+    }
+
+    // for some reason, if there is just a service, this value should
+    // be equal to 5
+    if (attribute_records == 1) {
+        attribute_records = 5;
+    }
+
+    return attribute_records;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,421 @@
+/**
+  ******************************************************************************
+  * @file    ble_hci.c 
+  * @author  AMS/HESA Application Team
+  * @brief   Function for managing HCI interface.
+  ******************************************************************************
+  *
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */ 
+
+#include "ble_hal_types.h"
+#include "ble_osal.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_hci_const.h"
+#include "ble_gp_timer.h"
+#include "ble_debug.h"
+
+#include "stm32_bluenrg_ble.h"
+
+#if BLE_CONFIG_DBG_ENABLE
+#undef PRINTF
+#endif
+
+#define HCI_LOG_ON 0
+
+#define HCI_READ_PACKET_NUM_MAX 		 (0x40)
+
+#define MIN(a,b)            ((a) < (b) )? (a) : (b)
+#define MAX(a,b)            ((a) > (b) )? (a) : (b)
+
+tListNode hciReadPktPool;
+tListNode hciReadPktRxQueue;
+
+// betzw - DEBUG:
+//#define POOL_CNT
+#ifdef POOL_CNT
+#include <stdio.h>
+static unsigned int nr_hciReadPktPool;
+static unsigned int lowest_nr_hciReadPktPool;
+#endif // POOL_CNT
+
+/* pool of hci read packets */
+static tHciDataPacket   hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX];
+
+static volatile uint8_t hci_timer_id;
+static volatile uint8_t hci_timeout;
+
+void hci_timeout_callback(void)
+{
+  hci_timeout = 1;
+  return;
+}
+
+void HCI_Init(void)
+{
+  uint8_t index;
+  
+#ifdef POOL_CNT
+  nr_hciReadPktPool = 0;
+#endif // POOL_CNT
+
+  /* Initialize list heads of ready and free hci data packet queues */
+  list_init_head (&hciReadPktPool);
+  list_init_head (&hciReadPktRxQueue);
+  
+  /* Initialize the queue of free hci data packets */
+  for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++)
+  {
+    list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]);
+#ifdef POOL_CNT
+    nr_hciReadPktPool++;
+#endif // POOL_CNT
+  }
+
+#ifdef POOL_CNT
+  lowest_nr_hciReadPktPool = nr_hciReadPktPool;
+#endif // POOL_CNT
+}
+
+#define HCI_PCK_TYPE_OFFSET                 0
+#define  EVENT_PARAMETER_TOT_LEN_OFFSET     2
+
+/**
+ * Verify if HCI packet is correctly formatted.
+ *
+ * @param[in] hciReadPacket    The packet that is received from HCI interface.
+ * @return 0 if HCI packet is as expected
+ */
+int HCI_verify(const tHciDataPacket * hciReadPacket)
+{
+  const uint8_t *hci_pckt = hciReadPacket->dataBuff;
+  
+  if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT)
+    return 1;  /* Incorrect type. */
+  
+  if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE))
+    return 2; /* Wrong length (packet truncated or too long). */
+  
+  return 0;      
+}
+
+void HCI_Process(void)
+{
+  tHciDataPacket * hciReadPacket = NULL;
+  
+#ifdef POOL_CNT
+  printf("betzw(%s, %d): nr_hciReadPktPool = %u (lowest = %u)\r\n", __func__, __LINE__, 
+	 nr_hciReadPktPool, lowest_nr_hciReadPktPool);
+#endif // POOL_CNT
+
+  Disable_SPI_IRQ();
+  uint8_t list_empty = list_is_empty(&hciReadPktRxQueue);        
+  /* process any pending events read */
+  while(list_empty == FALSE)
+  {
+    list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
+    Enable_SPI_IRQ();
+    HCI_Event_CB(hciReadPacket->dataBuff);
+    Disable_SPI_IRQ();
+    list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
+#ifdef POOL_CNT
+    nr_hciReadPktPool++;
+#endif
+    list_empty = list_is_empty(&hciReadPktRxQueue);
+  }
+  /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by
+  BlueNRG. */
+  HCI_HandleSPI();
+  Enable_SPI_IRQ();    
+}
+
+BOOL HCI_Queue_Empty(void)
+{
+  return list_is_empty(&hciReadPktRxQueue);
+}
+
+/**
+ * When an interrupt is raised by BlueNRG,
+ * just signal that a new event (availability of SPI data to be read)
+ * needs to be processed.
+ */
+void HCI_Isr(void)
+{
+  signalEventsToProcess();
+}
+
+/**
+ * Now, SPI Data are handled in user space.
+ * In case it has to be called in ISR, take care to
+ * call Disable_SPI_IRQ/Enable_SPI_IRQ in a proper way.
+ * The calls Disable_SPI_IRQ/Enable_SPI_IRQ have not been removed
+ * from this code for backward compatibility.
+ */
+void HCI_HandleSPI(void)
+{
+  tHciDataPacket * hciReadPacket = NULL;
+  uint8_t data_len;
+  
+  Clear_SPI_EXTI_Flag();
+  while(BlueNRG_DataPresent()){
+    if (list_is_empty (&hciReadPktPool) == FALSE){
+      
+      /* enqueueing a packet for read */
+      list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket);
+#ifdef POOL_CNT
+      nr_hciReadPktPool--;
+      if(nr_hciReadPktPool < lowest_nr_hciReadPktPool)
+	      lowest_nr_hciReadPktPool = nr_hciReadPktPool;
+#endif
+
+      data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE);
+      if(data_len > 0){                    
+        hciReadPacket->data_len = data_len;
+        if(HCI_verify(hciReadPacket) == 0) {
+          list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket);
+        } else {
+          list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket);
+#ifdef POOL_CNT
+	  nr_hciReadPktPool++;
+#endif
+	}
+      }
+      else {
+        // Insert the packet back into the pool.
+        list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket);
+#ifdef POOL_CNT
+	nr_hciReadPktPool++;
+#endif
+      }
+    }
+    else{
+      // HCI Read Packet Pool is empty, wait for a free packet.
+      Clear_SPI_EXTI_Flag();
+      return;
+    }
+    
+    Clear_SPI_EXTI_Flag();
+  }
+}
+
+void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){
+#if  HCI_LOG_ON
+  PRINTF("HCI <- ");
+  for(int i=0; i < n_bytes1; i++)
+    PRINTF("%02X ", *((uint8_t*)data1 + i));
+  for(int i=0; i < n_bytes2; i++)
+    PRINTF("%02X ", *((uint8_t*)data2 + i));
+  PRINTF("\n");    
+#endif
+  
+  Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2);
+}
+
+void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param)
+{
+  hci_command_hdr hc;
+  
+  hc.opcode = htobs(cmd_opcode_pack(ogf, ocf));
+  hc.plen= plen;
+  
+  uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE];
+  header[0] = HCI_COMMAND_PKT;
+  Osal_MemCpy(header+1, &hc, sizeof(hc));
+  
+  hci_write(header, param, sizeof(header), plen);
+}
+
+static void move_list(tListNode * dest_list, tListNode * src_list)
+{
+  pListNode tmp_node;
+  
+  while(!list_is_empty(src_list)){
+    list_remove_tail(src_list, &tmp_node);
+    list_insert_head(dest_list, tmp_node);
+  }
+}
+
+ /* It ensures that we have at least half of the free buffers in the pool. */
+static void free_event_list(void)
+{
+  tHciDataPacket * pckt;
+    
+  Disable_SPI_IRQ();
+  
+  while(list_get_size(&hciReadPktPool) < HCI_READ_PACKET_NUM_MAX/2){
+    list_remove_head(&hciReadPktRxQueue, (tListNode **)&pckt);    
+    list_insert_tail(&hciReadPktPool, (tListNode *)pckt);
+    /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by
+    BlueNRG */
+    HCI_HandleSPI();
+  }
+  
+  Enable_SPI_IRQ();
+}
+
+int hci_send_req(struct hci_request *r, BOOL async)
+{
+  uint8_t *ptr;
+  uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf));
+  hci_event_pckt *event_pckt;
+  hci_uart_pckt *hci_hdr;
+  int to = DEFAULT_TIMEOUT;
+  struct timer t;
+  tHciDataPacket * hciReadPacket = NULL;
+  tListNode hciTempQueue;
+  
+  list_init_head(&hciTempQueue);
+
+  free_event_list();
+  
+  hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam);
+
+  if(async){
+    return 0;
+  }
+  
+  /* Minimum timeout is 1. */
+  if(to == 0)
+    to = 1;
+  
+  Timer_Set(&t, to);
+  
+  while(1) {
+    evt_cmd_complete *cc;
+    evt_cmd_status *cs;
+    evt_le_meta_event *me;
+    int len;
+      
+    while(1){
+
+      Disable_SPI_IRQ();
+      HCI_HandleSPI();
+      Enable_SPI_IRQ();
+
+      if(Timer_Expired(&t)){
+        goto failed;
+      }
+      if(!HCI_Queue_Empty()){
+        break;
+      }
+    }
+    
+    /* Extract packet from HCI event queue. */
+    Disable_SPI_IRQ();
+    list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket);    
+    
+    hci_hdr = (void *)hciReadPacket->dataBuff;
+
+    if(hci_hdr->type == HCI_EVENT_PKT){
+
+    event_pckt = (void *) (hci_hdr->data);
+    
+    ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE);
+    len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE);
+    
+    switch (event_pckt->evt) {
+      
+    case EVT_CMD_STATUS:
+      cs = (void *) ptr;
+      
+      if (cs->opcode != opcode)
+        goto failed;
+      
+      if (r->event != EVT_CMD_STATUS) {
+        if (cs->status) {
+          goto failed;
+        }
+        break;
+      }
+      
+      r->rlen = MIN(len, r->rlen);
+      Osal_MemCpy(r->rparam, ptr, r->rlen);
+      goto done;
+      
+    case EVT_CMD_COMPLETE:
+      cc = (void *) ptr;
+      
+      if (cc->opcode != opcode)
+        goto failed;
+      
+      ptr += EVT_CMD_COMPLETE_SIZE;
+      len -= EVT_CMD_COMPLETE_SIZE;
+      
+      r->rlen = MIN(len, r->rlen);
+      Osal_MemCpy(r->rparam, ptr, r->rlen);
+      goto done;
+      
+    case EVT_LE_META_EVENT:
+      me = (void *) ptr;
+      
+      if (me->subevent != r->event)
+        break;
+      
+      len -= 1;
+      r->rlen = MIN(len, r->rlen);
+      Osal_MemCpy(r->rparam, me->data, r->rlen);
+      goto done;
+      
+    case EVT_HARDWARE_ERROR:            
+      goto failed;
+      
+    default:      
+      break;
+      }
+    }
+    
+    /* If there are no more packets to be processed, be sure there is at list one
+       packet in the pool to process the expected event.
+       If no free packets are available, discard the processed event and insert it
+       into the pool. */
+    if(list_is_empty(&hciReadPktPool) && list_is_empty(&hciReadPktRxQueue)){
+      list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
+      hciReadPacket=NULL;
+    }
+    else {
+      /* Insert the packet in a different queue. These packets will be
+      inserted back in the main queue just before exiting from send_req(), so that
+      these events can be processed by the application.
+    */
+	    list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket);
+	    hciReadPacket = NULL;
+    }
+
+    HCI_HandleSPI();
+    
+    Enable_SPI_IRQ();
+    
+  }
+  
+failed: 
+  if(hciReadPacket != NULL) {
+	  list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); 
+#ifdef POOL_CNT
+	  nr_hciReadPktPool++;
+#endif
+  }
+  move_list(&hciReadPktRxQueue, &hciTempQueue);  
+  Enable_SPI_IRQ();
+  return -1;
+  
+done:
+  // Insert the packet back into the pool.
+  list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); 
+#ifdef POOL_CNT
+  nr_hciReadPktPool++;
+#endif
+  move_list(&hciReadPktRxQueue, &hciTempQueue);
+  
+  Enable_SPI_IRQ();
+  return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,837 @@
+/**
+  ******************************************************************************
+  * @file    ble_hci_le.c 
+  * @author  AMG RF  Application Team
+  * @brief   Function for managing HCI interface.
+  ******************************************************************************
+  *
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */ 
+
+#include "ble_hal_types.h"
+#include "ble_osal.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_hci_const.h"
+
+#define MIN(a,b)            ((a) < (b) )? (a) : (b)
+#define MAX(a,b)            ((a) > (b) )? (a) : (b)
+
+int hci_reset(void)
+{
+  struct hci_request rq;
+  uint8_t status;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_HOST_CTL;
+  rq.ocf = OCF_RESET;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;  
+}
+
+int hci_disconnect(uint16_t handle, uint8_t reason)
+{
+  struct hci_request rq;
+  disconnect_cp cp;
+  uint8_t status;
+  
+  cp.handle = handle;
+  cp.reason = reason;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LINK_CTL;
+  rq.ocf = OCF_DISCONNECT;
+  rq.cparam = &cp;
+  rq.clen = DISCONNECT_CP_SIZE;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;  
+}
+
+int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, 
+                              uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion)
+{
+  struct hci_request rq;
+  read_local_version_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_INFO_PARAM;
+  rq.ocf = OCF_READ_LOCAL_VERSION;
+  rq.cparam = NULL;
+  rq.clen = 0;
+  rq.rparam = &resp;
+  rq.rlen = READ_LOCAL_VERSION_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  
+  *hci_version = resp.hci_version;
+  *hci_revision =  btohs(resp.hci_revision);
+  *lmp_pal_version = resp.lmp_pal_version;
+  *manufacturer_name = btohs(resp.manufacturer_name);
+  *lmp_pal_subversion = btohs(resp.lmp_pal_subversion);
+  
+  return 0;
+}
+
+int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt)
+{
+  struct hci_request rq;
+  le_read_buffer_size_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_READ_BUFFER_SIZE;
+  rq.cparam = NULL;
+  rq.clen = 0;
+  rq.rparam = &resp;
+  rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  *pkt_len = resp.pkt_len;
+  *max_pkt = resp.max_pkt;
+  
+  return 0;
+}
+
+int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype,
+                                      uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map,
+                                      uint8_t filter)
+{
+  struct hci_request rq;
+  le_set_adv_parameters_cp adv_cp;
+  uint8_t status;
+  
+  Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
+  adv_cp.min_interval = min_interval;
+  adv_cp.max_interval = max_interval;
+  adv_cp.advtype = advtype;
+  adv_cp.own_bdaddr_type = own_bdaddr_type;
+  adv_cp.direct_bdaddr_type = direct_bdaddr_type;
+  if(direct_bdaddr != NULL)
+    Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr));
+  adv_cp.chan_map = chan_map;
+  adv_cp.filter = filter;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_SET_ADV_PARAMETERS;
+  rq.cparam = &adv_cp;
+  rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+int hci_le_set_advertising_data(uint8_t length, const uint8_t data[])
+{
+  struct hci_request rq;
+  le_set_adv_data_cp adv_cp;
+  uint8_t status;
+  
+  Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
+  adv_cp.length = length;
+  Osal_MemCpy(adv_cp.data, data, MIN(31,length));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_SET_ADV_DATA;
+  rq.cparam = &adv_cp;
+  rq.clen = LE_SET_ADV_DATA_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+int hci_le_set_advertise_enable(uint8_t enable)
+{
+  struct hci_request rq;
+  le_set_advertise_enable_cp adv_cp;
+  uint8_t status;
+  
+  Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
+  adv_cp.enable = enable?1:0;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE;
+  rq.cparam = &adv_cp;
+  rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+int hci_le_set_scan_parameters(uint8_t	type, uint16_t interval,
+                               uint16_t window, uint8_t own_bdaddr_type,
+                               uint8_t	filter)
+{
+  struct hci_request rq;
+  le_set_scan_parameters_cp scan_cp;
+  uint8_t status;
+  
+  Osal_MemSet(&scan_cp, 0, sizeof(scan_cp));
+  scan_cp.type = type;
+  scan_cp.interval = interval;
+  scan_cp.window = window;
+  scan_cp.own_bdaddr_type = own_bdaddr_type;
+  scan_cp.filter = filter;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_SET_SCAN_PARAMETERS;
+  rq.cparam = &scan_cp;
+  rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup)
+{
+  struct hci_request rq;
+  le_set_scan_enable_cp scan_cp;
+  uint8_t status;
+  
+  Osal_MemSet(&scan_cp, 0, sizeof(scan_cp));
+  scan_cp.enable = enable?1:0;
+  scan_cp.filter_dup = filter_dup;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_SET_SCAN_ENABLE;
+  rq.cparam = &scan_cp;
+  rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+int hci_le_rand(uint8_t random_number[8])
+{
+  struct hci_request rq;
+  le_rand_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_RAND;
+  rq.cparam = NULL;
+  rq.clen = 0;
+  rq.rparam = &resp;
+  rq.rlen = LE_RAND_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  Osal_MemCpy(random_number, resp.random, 8);
+  
+  return 0;
+}
+
+int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[])
+{
+  struct hci_request rq;
+  le_set_scan_response_data_cp scan_resp_cp;
+  uint8_t status;
+  
+  Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp));
+  scan_resp_cp.length = length;
+  Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA;
+  rq.cparam = &scan_resp_cp;
+  rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level)
+{
+  struct hci_request rq;
+  le_read_adv_channel_tx_power_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER;
+  rq.cparam = NULL;
+  rq.clen = 0;
+  rq.rparam = &resp;
+  rq.rlen = LE_RAND_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  *tx_power_level = resp.level;
+  
+  return 0;
+}
+
+int hci_le_set_random_address(tBDAddr bdaddr)
+{
+  struct hci_request rq;
+  le_set_random_address_cp set_rand_addr_cp;
+  uint8_t status;
+  
+  Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp));
+  Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_SET_RANDOM_ADDRESS;
+  rq.cparam = &set_rand_addr_cp;
+  rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+int hci_read_bd_addr(tBDAddr bdaddr)
+{
+  struct hci_request rq;
+  read_bd_addr_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_INFO_PARAM;
+  rq.ocf = OCF_READ_BD_ADDR;
+  rq.cparam = NULL;
+  rq.clen = 0;
+  rq.rparam = &resp;
+  rq.rlen = READ_BD_ADDR_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr));
+  
+  return 0;
+}
+
+int hci_le_create_connection(uint16_t interval,	uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type,
+                             const tBDAddr peer_bdaddr,	uint8_t	own_bdaddr_type, uint16_t min_interval,	uint16_t max_interval,
+                             uint16_t latency,	uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length)
+{
+  struct hci_request rq;
+  le_create_connection_cp create_cp;
+  uint8_t status;
+  
+  Osal_MemSet(&create_cp, 0, sizeof(create_cp));
+  create_cp.interval = interval;
+  create_cp.window =  window;
+  create_cp.initiator_filter = initiator_filter;
+  create_cp.peer_bdaddr_type = peer_bdaddr_type;
+  Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr));
+  create_cp.own_bdaddr_type = own_bdaddr_type;
+  create_cp.min_interval=min_interval;
+  create_cp.max_interval=max_interval;
+  create_cp.latency = latency;
+  create_cp.supervision_timeout=supervision_timeout;
+  create_cp.min_ce_length=min_ce_length;
+  create_cp.max_ce_length=max_ce_length;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_CREATE_CONN;
+  rq.cparam = &create_cp;
+  rq.clen = LE_CREATE_CONN_CP_SIZE;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+int hci_le_create_connection_cancel(void)
+{
+  struct hci_request rq;
+  uint8_t status;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_CREATE_CONN_CANCEL;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;  
+}
+
+int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16])
+{
+  struct hci_request rq;
+  le_encrypt_cp params;
+  le_encrypt_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemCpy(params.key, key, 16);
+  Osal_MemCpy(params.plaintext, plaintextData, 16);
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_ENCRYPT;
+  rq.cparam = &params;
+  rq.clen = LE_ENCRYPT_CP_SIZE;
+  rq.rparam = &resp;
+  rq.rlen = LE_ENCRYPT_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  Osal_MemCpy(encryptedData, resp.encdata, 16);
+  
+  return 0;
+}
+
+int hci_le_ltk_request_reply(uint8_t key[16])
+{
+  struct hci_request rq;
+  le_ltk_reply_cp params;
+  le_ltk_reply_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  params.handle = 1;
+  Osal_MemCpy(params.key, key, 16);
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_LTK_REPLY;
+  rq.cparam = &params;
+  rq.clen = LE_LTK_REPLY_CP_SIZE;
+  rq.rparam = &resp;
+  rq.rlen = LE_LTK_REPLY_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return resp.status;
+}
+
+int hci_le_ltk_request_neg_reply(void)
+{
+  struct hci_request rq;
+  le_ltk_neg_reply_cp params;
+  le_ltk_neg_reply_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  params.handle = 1;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_LTK_NEG_REPLY;
+  rq.cparam = &params;
+  rq.clen = LE_LTK_NEG_REPLY_CP_SIZE;
+  rq.rparam = &resp;
+  rq.rlen = LE_LTK_NEG_REPLY_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return resp.status;
+}
+
+int hci_le_read_white_list_size(uint8_t *size)
+{
+  struct hci_request rq;
+  le_read_white_list_size_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE;
+  rq.rparam = &resp;
+  rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  *size = resp.size;
+  
+  return 0;
+}
+
+int hci_le_clear_white_list(void)
+{
+  struct hci_request rq;
+  uint8_t status;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_CLEAR_WHITE_LIST;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  return status;
+}
+
+int hci_le_add_device_to_white_list(uint8_t	bdaddr_type, tBDAddr bdaddr)
+{
+  struct hci_request rq;
+  le_add_device_to_white_list_cp params;
+  uint8_t status;
+  
+  params.bdaddr_type = bdaddr_type;
+  Osal_MemCpy(params.bdaddr, bdaddr, 6);
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST;
+  rq.cparam = &params;
+  rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  return status;
+}
+
+int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr)
+{
+  struct hci_request rq;
+  le_remove_device_from_white_list_cp params;
+  uint8_t status;
+  
+  params.bdaddr_type = bdaddr_type;
+  Osal_MemCpy(params.bdaddr, bdaddr, 6);
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST;
+  rq.cparam = &params;
+  rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  return status;
+}
+
+int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level)
+{
+  struct hci_request rq;
+  read_transmit_power_level_cp params;
+  read_transmit_power_level_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  params.handle = *conn_handle;
+  params.type = type;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_HOST_CTL;
+  rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL;
+  rq.cparam = &params;
+  rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE;
+  rq.rparam = &resp;
+  rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  *conn_handle = resp.handle;
+  *tx_level = resp.level;
+  
+  return 0;
+}
+
+int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi)
+{
+  struct hci_request rq;
+  read_rssi_cp params;
+  read_rssi_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  params.handle = *conn_handle;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_STATUS_PARAM;
+  rq.ocf = OCF_READ_RSSI;
+  rq.cparam = &params;
+  rq.clen = READ_RSSI_CP_SIZE;
+  rq.rparam = &resp;
+  rq.rlen = READ_RSSI_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  *conn_handle = resp.handle;
+  *rssi = resp.rssi;
+  
+  return 0;
+}
+
+int hci_le_read_local_supported_features(uint8_t *features)
+{
+  struct hci_request rq;
+  le_read_local_supported_features_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_READ_LOCAL_SUPPORTED_FEATURES;
+  rq.rparam = &resp;
+  rq.rlen = LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  Osal_MemCpy(features, resp.features, sizeof(resp.features));
+  
+  return 0;
+}
+
+int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5])
+{
+  struct hci_request rq;
+  le_read_channel_map_cp params;
+  le_read_channel_map_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  params.handle = conn_handle;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_READ_CHANNEL_MAP;
+  rq.cparam = &params;
+  rq.clen = LE_READ_CHANNEL_MAP_CP_SIZE;
+  rq.rparam = &resp;
+  rq.rlen = LE_READ_CHANNEL_MAP_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  Osal_MemCpy(ch_map, resp.map, 5);
+  
+  return 0;
+}
+
+int hci_le_read_supported_states(uint8_t states[8])
+{
+  struct hci_request rq;
+  le_read_supported_states_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_READ_SUPPORTED_STATES;
+  rq.rparam = &resp;
+  rq.rlen = LE_READ_SUPPORTED_STATES_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  Osal_MemCpy(states, resp.states, 8);
+  
+  return 0;
+}
+
+int hci_le_receiver_test(uint8_t frequency)
+{
+  struct hci_request rq;
+  le_receiver_test_cp params;
+  uint8_t status;
+  
+  params.frequency = frequency;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_RECEIVER_TEST;
+  rq.cparam = &params;
+  rq.clen = LE_RECEIVER_TEST_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  return status;
+}
+
+int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload)
+{
+  struct hci_request rq;
+  le_transmitter_test_cp params;
+  uint8_t status;
+  
+  params.frequency = frequency;
+  params.length = length;
+  params.payload = payload;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_TRANSMITTER_TEST;
+  rq.cparam = &params;
+  rq.clen = LE_TRANSMITTER_TEST_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  return status;
+}
+
+int hci_le_test_end(uint16_t *num_pkts)
+{
+  struct hci_request rq;
+  le_test_end_rp resp;
+  
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_LE_CTL;
+  rq.ocf = OCF_LE_TEST_END;
+  rq.rparam = &resp;
+  rq.rlen = LE_TEST_END_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0){
+    return BLE_STATUS_TIMEOUT;
+  }
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  *num_pkts = resp.num_pkts;
+  
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,1309 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name          : bluenrg_hci.c
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 4-Oct-2013
+* Description        : File with HCI commands for BlueNRG FW6.0 and above.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#include "ble_hal_types.h"
+#include "ble_osal.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_hci_const.h"
+#include "bluenrg_aci_const.h"
+#include "bluenrg_gap_aci.h"
+#include "bluenrg_gatt_server.h"
+#include "bluenrg_gap.h"
+
+#define MIN(a,b)            ((a) < (b) )? (a) : (b)
+#define MAX(a,b)            ((a) > (b) )? (a) : (b)
+
+tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle)
+{
+  struct hci_request rq;
+  gap_init_cp_IDB05A1 cp;
+  gap_init_rp resp;
+ 
+  cp.role = role;
+  cp.privacy_enabled = privacy_enabled;
+  cp.device_name_char_len = device_name_char_len;
+    
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_INIT;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &resp;
+  rq.rlen = GAP_INIT_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  *service_handle = btohs(resp.service_handle);
+  *dev_name_char_handle = btohs(resp.dev_name_char_handle);
+  *appearance_char_handle = btohs(resp.appearance_char_handle);
+  
+  return 0;
+}
+tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle)
+{
+  struct hci_request rq;
+  gap_init_cp_IDB04A1 cp;
+  gap_init_rp resp;
+
+  cp.role = role;
+    
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_INIT;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &resp;
+  rq.rlen = GAP_INIT_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  *service_handle = btohs(resp.service_handle);
+  *dev_name_char_handle = btohs(resp.dev_name_char_handle);
+  *appearance_char_handle = btohs(resp.appearance_char_handle);
+  
+  return 0;
+}
+
+tBleStatus aci_gap_set_non_discoverable(void)
+{
+  struct hci_request rq;
+  uint8_t status;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;  
+}
+
+tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax,
+					    uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen,
+					    const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList,
+					    uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax)
+{
+  struct hci_request rq;
+  uint8_t status;    
+  uint8_t buffer[40];
+  uint8_t indx = 0;
+    
+  if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  buffer[indx] = AdvType;
+  indx++;
+    
+  AdvIntervMin = htobs(AdvIntervMin);
+  Osal_MemCpy(buffer + indx, &AdvIntervMin, 2);
+  indx +=  2;
+    
+  AdvIntervMax = htobs(AdvIntervMax);
+  Osal_MemCpy(buffer + indx, &AdvIntervMax, 2);
+  indx +=  2;
+    
+  buffer[indx] = OwnAddrType;
+  indx++;
+    
+  buffer[indx] = AdvFilterPolicy;
+  indx++;
+    
+  buffer[indx] = LocalNameLen;
+  indx++;
+    
+  Osal_MemCpy(buffer + indx, LocalName, LocalNameLen);
+  indx +=  LocalNameLen;
+
+  buffer[indx] = ServiceUUIDLen;
+  indx++;
+
+  Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen);
+  indx +=  ServiceUUIDLen;
+
+  Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2);
+  indx +=  2;
+
+  Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2);
+  indx +=  2;    
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax,
+                             uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen,
+                             const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList,
+                             uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax)
+{
+  struct hci_request rq;
+  uint8_t status;    
+  uint8_t buffer[40];
+  uint8_t indx = 0;
+  
+  if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  buffer[indx] = AdvType;
+  indx++;
+  
+  AdvIntervMin = htobs(AdvIntervMin);
+  Osal_MemCpy(buffer + indx, &AdvIntervMin, 2);
+  indx +=  2;
+    
+  AdvIntervMax = htobs(AdvIntervMax);
+  Osal_MemCpy(buffer + indx, &AdvIntervMax, 2);
+  indx +=  2;
+    
+  buffer[indx] = OwnAddrType;
+  indx++;
+    
+  buffer[indx] = AdvFilterPolicy;
+  indx++;
+    
+  buffer[indx] = LocalNameLen;
+  indx++;
+    
+  Osal_MemCpy(buffer + indx, LocalName, LocalNameLen);
+  indx +=  LocalNameLen;
+  
+  buffer[indx] = ServiceUUIDLen;
+  indx++;
+
+  Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen);
+  indx +=  ServiceUUIDLen;  
+
+  SlaveConnIntervMin = htobs(SlaveConnIntervMin);
+  Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2);
+  indx +=  2;
+  
+  SlaveConnIntervMax = htobs(SlaveConnIntervMax);
+  Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2);
+  indx +=  2;    
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SET_DISCOVERABLE;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  if (status) {
+    return status;
+  }
+
+  return 0;
+}
+
+tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type,
+                                                  const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max)
+{
+  struct hci_request rq;
+  gap_set_direct_conectable_cp_IDB05A1 cp;
+  uint8_t status;    
+
+  cp.own_bdaddr_type = own_addr_type;
+  cp.directed_adv_type = directed_adv_type;
+  cp.adv_interv_min = adv_interv_min;
+  cp.adv_interv_max = adv_interv_max;
+  cp.direct_bdaddr_type = initiator_addr_type;
+  Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+    
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+    
+  return status;
+}
+
+tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr)
+{
+  struct hci_request rq;
+  gap_set_direct_conectable_cp_IDB04A1 cp;
+  uint8_t status;    
+
+  cp.own_bdaddr_type = own_addr_type; 
+  cp.direct_bdaddr_type = initiator_addr_type;
+  Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+    
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+    
+  return status;
+}
+
+tBleStatus aci_gap_set_io_capability(uint8_t io_capability)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gap_set_io_capability_cp cp;
+    
+  cp.io_capability = io_capability;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SET_IO_CAPABILITY;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+    
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+    
+  return status;
+}
+
+tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode,
+                                        uint8_t oob_enable,
+                                        uint8_t oob_data[16],
+                                        uint8_t min_encryption_key_size,
+                                        uint8_t max_encryption_key_size,
+                                        uint8_t use_fixed_pin,
+                                        uint32_t fixed_pin,
+                                        uint8_t bonding_mode)
+{
+  struct hci_request rq;
+  gap_set_auth_requirement_cp cp;    
+  uint8_t status;
+    
+  cp.mitm_mode = mitm_mode;
+  cp.oob_enable = oob_enable;
+  Osal_MemCpy(cp.oob_data, oob_data, 16);
+  cp.min_encryption_key_size = min_encryption_key_size;
+  cp.max_encryption_key_size = max_encryption_key_size;
+  cp.use_fixed_pin = use_fixed_pin;
+  cp.fixed_pin = htobl(fixed_pin);
+  cp.bonding_mode = bonding_mode;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  if (status) {
+    return status;
+  }
+    
+  return 0;
+}
+
+tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable)
+{
+  struct hci_request rq;
+  gap_set_author_requirement_cp cp;    
+  uint8_t status;
+    
+  cp.conn_handle = htobs(conn_handle);
+  cp.authorization_enable = authorization_enable;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey)
+{
+  struct hci_request rq;
+  gap_passkey_response_cp cp;    
+  uint8_t status;
+    
+  cp.conn_handle = htobs(conn_handle);
+  cp.passkey = htobl(passkey);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_PASSKEY_RESPONSE;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize)
+{
+  struct hci_request rq;
+  gap_authorization_response_cp cp;    
+  uint8_t status;
+    
+  cp.conn_handle = htobs(conn_handle);
+  cp.authorize = authorize;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type)
+{
+  struct hci_request rq;
+  gap_set_non_connectable_cp_IDB05A1 cp;    
+  uint8_t status;
+    
+  cp.advertising_event_type = adv_type;  
+  cp.own_address_type = own_address_type;
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SET_NON_CONNECTABLE;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type)
+{
+  struct hci_request rq;
+  gap_set_non_connectable_cp_IDB04A1 cp;    
+  uint8_t status;
+    
+  cp.advertising_event_type = adv_type;  
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SET_NON_CONNECTABLE;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy)
+{
+  struct hci_request rq;
+  gap_set_undirected_connectable_cp cp;    
+  uint8_t status;
+    
+  cp.own_addr_type = own_addr_type;
+  cp.adv_filter_policy = adv_filter_policy;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection)
+{
+  struct hci_request rq;
+  gap_slave_security_request_cp cp;
+  uint8_t status;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.bonding = bonding;
+  cp.mitm_protection = mitm_protection;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+
+}
+
+tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData)
+{
+  struct hci_request rq;
+  uint8_t status;
+  uint8_t buffer[32];
+  uint8_t indx = 0;
+    
+  if (AdvLen > (sizeof(buffer)-1))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  buffer[indx] = AdvLen;
+  indx++;
+    
+  Osal_MemCpy(buffer + indx, AdvData, AdvLen);
+  indx +=  AdvLen;
+    
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_UPDATE_ADV_DATA;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.rparam = &status;
+  rq.rlen = 1;
+    
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+    
+  return status;
+}
+
+tBleStatus aci_gap_delete_ad_type(uint8_t ad_type)
+{
+  struct hci_request rq;
+  gap_delete_ad_type_cp cp;
+  uint8_t status;
+
+  cp.ad_type = ad_type;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_DELETE_AD_TYPE;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding,
+                                      uint8_t* oob_data, uint8_t* passkey_required)
+{
+  struct hci_request rq;
+  gap_get_security_level_rp resp;
+    
+  Osal_MemSet(&resp, 0, sizeof(resp));
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_GET_SECURITY_LEVEL;
+  rq.rparam = &resp;
+  rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  *mitm_protection = resp.mitm_protection;
+  *bonding = resp.bonding;
+  *oob_data = resp.oob_data;
+  *passkey_required = resp.passkey_required;
+
+  return resp.status;
+}
+
+tBleStatus aci_gap_configure_whitelist(void)
+{
+  struct hci_request rq;
+  uint8_t status;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_CONFIGURE_WHITELIST;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason)
+{
+  struct hci_request rq;
+  gap_terminate_cp cp;
+  uint8_t status;  
+
+  cp.handle = htobs(conn_handle);
+  cp.reason = reason;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_TERMINATE;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status; 
+}
+
+tBleStatus aci_gap_clear_security_database(void)
+{
+  struct hci_request rq;
+  uint8_t status;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_CLEAR_SECURITY_DB;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle)
+{
+  struct hci_request rq;
+  gap_allow_rebond_cp_IDB05A1 cp;
+  uint8_t status;
+  
+  cp.conn_handle = conn_handle;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_ALLOW_REBOND_DB;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+tBleStatus aci_gap_allow_rebond_IDB04A1(void)
+{
+  struct hci_request rq;
+  uint8_t status;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_ALLOW_REBOND_DB;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
+						uint8_t own_address_type, uint8_t filterDuplicates)
+{
+  struct hci_request rq;
+  gap_start_limited_discovery_proc_cp cp;
+  uint8_t status;  
+
+  cp.scanInterval = htobs(scanInterval);
+  cp.scanWindow = htobs(scanWindow);
+  cp.own_address_type = own_address_type;
+  cp.filterDuplicates = filterDuplicates;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
+						uint8_t own_address_type, uint8_t filterDuplicates)
+{
+  struct hci_request rq;
+  gap_start_general_discovery_proc_cp cp;
+  uint8_t status;  
+
+  cp.scanInterval = htobs(scanInterval);
+  cp.scanWindow = htobs(scanWindow);
+  cp.own_address_type = own_address_type;
+  cp.filterDuplicates = filterDuplicates;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+
+tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
+				     uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr,	
+				     uint8_t own_bdaddr_type, uint16_t conn_min_interval,	
+				     uint16_t conn_max_interval, uint16_t conn_latency,	
+				     uint16_t supervision_timeout, uint16_t min_conn_length, 
+				     uint16_t max_conn_length)
+{
+  struct hci_request rq;
+  gap_start_name_discovery_proc_cp cp;
+  uint8_t status;  
+
+  cp.scanInterval = htobs(scanInterval);
+  cp.scanWindow = htobs(scanWindow);
+  cp.peer_bdaddr_type = peer_bdaddr_type;
+  Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6);
+  cp.own_bdaddr_type = own_bdaddr_type;
+  cp.conn_min_interval = htobs(conn_min_interval);
+  cp.conn_max_interval = htobs(conn_max_interval);
+  cp.conn_latency = htobs(conn_latency);
+  cp.supervision_timeout = htobs(supervision_timeout);
+  cp.min_conn_length = htobs(min_conn_length);
+  cp.max_conn_length = htobs(max_conn_length);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow,
+						 uint8_t own_bdaddr_type, uint16_t conn_min_interval,	
+						 uint16_t conn_max_interval, uint16_t conn_latency,	
+						 uint16_t supervision_timeout, uint16_t min_conn_length, 
+						 uint16_t max_conn_length,
+                         uint8_t num_whitelist_entries,
+                         const uint8_t *addr_array)
+{
+  struct hci_request rq;
+  uint8_t status;
+  uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+  uint8_t indx = 0;
+    
+  if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE)
+    return BLE_STATUS_INVALID_PARAMS;
+
+  scanInterval = htobs(scanInterval);
+  Osal_MemCpy(buffer + indx, &scanInterval, 2);
+  indx += 2;
+    
+  scanWindow = htobs(scanWindow);
+  Osal_MemCpy(buffer + indx, &scanWindow, 2);
+  indx += 2;
+
+  buffer[indx] = own_bdaddr_type;
+  indx++;
+  
+  conn_min_interval = htobs(conn_min_interval);
+  Osal_MemCpy(buffer + indx, &conn_min_interval, 2);
+  indx +=  2;
+
+  conn_max_interval = htobs(conn_max_interval);
+  Osal_MemCpy(buffer + indx, &conn_max_interval, 2);
+  indx +=  2;
+
+  conn_latency = htobs(conn_latency);
+  Osal_MemCpy(buffer + indx, &conn_latency, 2);
+  indx +=  2;
+
+  supervision_timeout = htobs(supervision_timeout);
+  Osal_MemCpy(buffer + indx, &supervision_timeout, 2);
+  indx +=  2;
+
+  min_conn_length = htobs(min_conn_length);
+  Osal_MemCpy(buffer + indx, &min_conn_length, 2);
+  indx +=  2;
+
+  max_conn_length = htobs(max_conn_length);
+  Osal_MemCpy(buffer + indx, &max_conn_length, 2);
+  indx +=  2;
+
+  buffer[indx] = num_whitelist_entries;
+  indx++;
+
+  Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7));
+  indx +=  num_whitelist_entries * 7;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;  
+}
+
+tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow,
+						 uint8_t own_bdaddr_type, uint16_t conn_min_interval,	
+						 uint16_t conn_max_interval, uint16_t conn_latency,	
+						 uint16_t supervision_timeout, uint16_t min_conn_length, 
+						 uint16_t max_conn_length,
+                         uint8_t use_reconn_addr,
+                         const tBDAddr reconn_addr,
+                         uint8_t num_whitelist_entries,
+                         const uint8_t *addr_array)
+{
+  struct hci_request rq;
+  uint8_t status;
+  uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+  uint8_t indx = 0;
+    
+  if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE)
+    return BLE_STATUS_INVALID_PARAMS;
+
+  scanInterval = htobs(scanInterval);
+  Osal_MemCpy(buffer + indx, &scanInterval, 2);
+  indx += 2;
+    
+  scanWindow = htobs(scanWindow);
+  Osal_MemCpy(buffer + indx, &scanWindow, 2);
+  indx += 2;
+
+  buffer[indx] = own_bdaddr_type;
+  indx++;
+  
+  conn_min_interval = htobs(conn_min_interval);
+  Osal_MemCpy(buffer + indx, &conn_min_interval, 2);
+  indx +=  2;
+
+  conn_max_interval = htobs(conn_max_interval);
+  Osal_MemCpy(buffer + indx, &conn_max_interval, 2);
+  indx +=  2;
+
+  conn_latency = htobs(conn_latency);
+  Osal_MemCpy(buffer + indx, &conn_latency, 2);
+  indx +=  2;
+
+  supervision_timeout = htobs(supervision_timeout);
+  Osal_MemCpy(buffer + indx, &supervision_timeout, 2);
+  indx +=  2;
+
+  min_conn_length = htobs(min_conn_length);
+  Osal_MemCpy(buffer + indx, &min_conn_length, 2);
+  indx +=  2;
+
+  max_conn_length = htobs(max_conn_length);
+  Osal_MemCpy(buffer + indx, &max_conn_length, 2);
+  indx +=  2;
+  
+  buffer[indx] = use_reconn_addr;
+  indx++;
+
+  Osal_MemCpy(buffer + indx, reconn_addr, 6);
+  indx += 6;
+
+  buffer[indx] = num_whitelist_entries;
+  indx++;
+
+  Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7));
+  indx +=  num_whitelist_entries * 7;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;  
+}
+
+tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window,
+						 uint8_t own_address_type, uint8_t filter_duplicates)
+{
+  struct hci_request rq;
+  gap_start_general_conn_establish_proc_cp_IDB05A1 cp;
+  uint8_t status;  
+
+  cp.scan_type = scan_type;
+  cp.scan_interval = htobs(scan_interval);
+  cp.scan_window = htobs(scan_window);
+  cp.own_address_type = own_address_type;
+  cp.filter_duplicates = filter_duplicates;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window,
+						 uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr)
+{
+  struct hci_request rq;
+  gap_start_general_conn_establish_proc_cp_IDB04A1 cp;
+  uint8_t status;  
+
+  cp.scan_type = scan_type;
+  cp.scan_interval = htobs(scan_interval);
+  cp.scan_window = htobs(scan_window);
+  cp.own_address_type = own_address_type;
+  cp.filter_duplicates = filter_duplicates;
+  cp.use_reconn_addr = use_reconn_addr;
+  Osal_MemCpy(cp.reconn_addr, reconn_addr, 6);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window,
+						 uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries,
+                         const uint8_t *addr_array)
+{
+  struct hci_request rq;
+  gap_start_selective_conn_establish_proc_cp cp;
+  uint8_t status;
+  
+  if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE)
+    return BLE_STATUS_INVALID_PARAMS;
+  
+  cp.scan_type = scan_type;
+  cp.scan_interval = htobs(scan_interval);
+  cp.scan_window = htobs(scan_window);
+  cp.own_address_type = own_address_type;
+  cp.filter_duplicates = filter_duplicates;
+  cp.num_whitelist_entries = num_whitelist_entries;  
+  
+  Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7));
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC;
+  rq.cparam = &cp;
+  rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow,
+				     uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr,	
+				     uint8_t own_bdaddr_type, uint16_t conn_min_interval,	
+				     uint16_t conn_max_interval, uint16_t conn_latency,	
+				     uint16_t supervision_timeout, uint16_t min_conn_length, 
+				     uint16_t max_conn_length)
+{
+  struct hci_request rq;
+  gap_create_connection_cp cp;
+  uint8_t status;  
+
+  cp.scanInterval = htobs(scanInterval);
+  cp.scanWindow = htobs(scanWindow);
+  cp.peer_bdaddr_type = peer_bdaddr_type;
+  Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6);
+  cp.own_bdaddr_type = own_bdaddr_type;
+  cp.conn_min_interval = htobs(conn_min_interval);
+  cp.conn_max_interval = htobs(conn_max_interval);
+  cp.conn_latency = htobs(conn_latency);
+  cp.supervision_timeout = htobs(supervision_timeout);
+  cp.min_conn_length = htobs(min_conn_length);
+  cp.max_conn_length = htobs(max_conn_length);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_CREATE_CONNECTION;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code)
+{
+  struct hci_request rq;
+  uint8_t status;  
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE;
+  rq.cparam = &procedure_code;
+  rq.clen = 1;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+
+}
+
+tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval,	
+                                           uint16_t conn_max_interval, uint16_t conn_latency,	
+                                           uint16_t supervision_timeout, uint16_t min_conn_length, 
+                                           uint16_t max_conn_length)
+{
+  struct hci_request rq;
+  gap_start_connection_update_cp cp;
+  uint8_t status;  
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.conn_min_interval = htobs(conn_min_interval);
+  cp.conn_max_interval = htobs(conn_max_interval);
+  cp.conn_latency = htobs(conn_latency);
+  cp.supervision_timeout = htobs(supervision_timeout);
+  cp.min_conn_length = htobs(min_conn_length);
+  cp.max_conn_length = htobs(max_conn_length);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_START_CONNECTION_UPDATE;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond)
+{
+  struct hci_request rq;
+  gap_send_pairing_request_cp cp;
+  uint8_t status;  
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.force_rebond = force_rebond;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address)
+{
+  struct hci_request rq;
+  gap_resolve_private_address_cp cp;
+  gap_resolve_private_address_rp rp;
+
+  Osal_MemCpy(cp.address, private_address, 6);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &rp;
+  rq.rlen = sizeof(rp);
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if(rp.status)
+    return rp.status;
+  
+  Osal_MemCpy(actual_address, rp.address, sizeof(actual_address));  
+
+  return 0;
+}
+tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address)
+{
+  struct hci_request rq;
+  gap_resolve_private_address_cp cp;
+  uint8_t status;
+
+  Osal_MemCpy(cp.address, address, 6);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+  
+tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type,
+				  uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data,  uint8_t num_whitelist_entries,
+                                  const uint8_t *addr_array)
+{
+  struct hci_request rq;
+  gap_set_broadcast_mode_cp cp;
+  uint8_t status;
+  uint8_t indx = 0;  
+  uint8_t variable_size =  1 + adv_data_length + 1 + num_whitelist_entries*7;
+  
+  if (variable_size > sizeof(cp.var_len_data) )
+    return BLE_STATUS_INVALID_PARAMS;
+  
+  cp.adv_interv_min = htobs(adv_interv_min);
+  cp.adv_interv_max = htobs(adv_interv_max);
+  cp.adv_type = adv_type;
+  cp.own_addr_type = own_addr_type;
+  
+  cp.var_len_data[indx] = adv_data_length;
+  indx++;
+  Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length);
+  indx += adv_data_length;
+  cp.var_len_data[indx] = num_whitelist_entries;
+  indx ++;
+  Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_SET_BROADCAST_MODE;
+  rq.cparam = &cp;
+  rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type,
+						 uint8_t own_address_type, uint8_t filter_duplicates)
+{
+  struct hci_request rq;
+  gap_start_observation_proc_cp cp;
+  uint8_t status;
+  
+  cp.scan_interval = scan_interval;
+  cp.scan_window = scan_window;
+  cp.scan_type = scan_type;
+  cp.own_address_type = own_address_type;
+  cp.filter_duplicates = filter_duplicates;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_START_OBSERVATION_PROC;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address)
+{
+  struct hci_request rq;
+  gap_is_device_bonded_cp cp;
+  uint8_t status;
+  
+  cp.peer_address_type = peer_address_type;
+  Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address));
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_IS_DEVICE_BONDED;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size)
+{
+  struct hci_request rq;
+  gap_get_bonded_devices_rp rp;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GAP_GET_BONDED_DEVICES;
+  rq.rparam = &rp;
+  rq.rlen = sizeof(rp);
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if (rp.status) {
+    return rp.status;
+  }
+  
+  *num_devices = rp.num_addr;
+  if(device_list != NULL)
+    Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7));
+  
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,1505 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name          : bluenrg_gatt_aci.c
+* Author             : AMS - AAS
+* Version            : V1.0.0
+* Date               : 26-Jun-2014
+* Description        : File with GATT commands for BlueNRG FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#include "ble_hal_types.h"
+#include "ble_osal.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_hci_const.h"
+#include "bluenrg_aci_const.h"
+#include "bluenrg_gatt_aci.h"
+#include "bluenrg_gatt_server.h"
+#include "bluenrg_gap.h"
+
+#define MIN(a,b)            ((a) < (b) )? (a) : (b)
+#define MAX(a,b)            ((a) > (b) )? (a) : (b)
+
+
+tBleStatus aci_gatt_init(void)
+{
+  struct hci_request rq;
+  uint8_t status;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_INIT;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle)
+{
+  struct hci_request rq;
+  gatt_add_serv_rp resp;    
+  uint8_t buffer[19];
+  uint8_t uuid_len;
+  uint8_t indx = 0;
+    
+  buffer[indx] = service_uuid_type;
+  indx++;
+    
+  if(service_uuid_type == UUID_TYPE_16){
+    uuid_len = 2;
+  }
+  else {
+    uuid_len = 16;
+  }        
+  Osal_MemCpy(buffer + indx, service_uuid, uuid_len);
+  indx +=  uuid_len;
+    
+  buffer[indx] = service_type;
+  indx++;
+    
+  buffer[indx] = max_attr_records;
+  indx++;
+    
+    
+  Osal_MemSet(&resp, 0, sizeof(resp));
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_ADD_SERV;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.rparam = &resp;
+  rq.rlen = GATT_ADD_SERV_RP_SIZE;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  if (resp.status) {
+    return resp.status;
+  }
+    
+  *serviceHandle = btohs(resp.handle);
+
+  return 0;
+}
+
+tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle,
+				    uint16_t included_end_handle, uint8_t included_uuid_type,
+				    const uint8_t* included_uuid, uint16_t *included_handle)
+{
+  struct hci_request rq;
+  gatt_include_serv_rp resp;    
+  uint8_t buffer[23];
+  uint8_t uuid_len;
+  uint8_t indx = 0;
+
+  service_handle = htobs(service_handle);
+  Osal_MemCpy(buffer, &service_handle, 2);
+  indx += 2;
+    
+  included_start_handle = htobs(included_start_handle);
+  Osal_MemCpy(buffer+indx, &included_start_handle, 2);
+  indx += 2;
+
+  included_end_handle = htobs(included_end_handle);
+  Osal_MemCpy(buffer+indx, &included_end_handle, 2);
+  indx += 2;
+
+  if(included_uuid_type == UUID_TYPE_16){
+    uuid_len = 2;
+  } else {
+    uuid_len = 16;
+  }        
+
+  buffer[indx] = included_uuid_type;
+  indx++;
+
+  Osal_MemCpy(buffer + indx, included_uuid, uuid_len);
+  indx += uuid_len;
+    
+  Osal_MemSet(&resp, 0, sizeof(resp));
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_INCLUDE_SERV;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.rparam = &resp;
+  rq.rlen = GATT_INCLUDE_SERV_RP_SIZE;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  if (resp.status) {
+    return resp.status;
+  }
+    
+  *included_handle = btohs(resp.handle);
+
+  return 0;
+}
+
+tBleStatus aci_gatt_add_char(uint16_t serviceHandle,
+			     uint8_t charUuidType,
+			     const uint8_t* charUuid, 
+			     uint8_t charValueLen, 
+			     uint8_t charProperties,
+			     uint8_t secPermissions,
+			     uint8_t gattEvtMask,
+			     uint8_t encryKeySize,
+			     uint8_t isVariable,
+			     uint16_t* charHandle)                     
+{
+  struct hci_request rq;
+  gatt_add_serv_rp resp;
+  uint8_t buffer[25];
+  uint8_t uuid_len;
+  uint8_t indx = 0;
+    
+  serviceHandle = htobs(serviceHandle);
+  Osal_MemCpy(buffer + indx, &serviceHandle, 2);
+  indx += 2;
+    
+  buffer[indx] = charUuidType;
+  indx++;
+    
+  if(charUuidType == UUID_TYPE_16){
+    uuid_len = 2;
+  }
+  else {
+    uuid_len = 16;
+  }        
+  Osal_MemCpy(buffer + indx, charUuid, uuid_len);
+  indx +=  uuid_len;
+    
+  buffer[indx] = charValueLen;
+  indx++;
+    
+  buffer[indx] = charProperties;
+  indx++;
+    
+  buffer[indx] = secPermissions;
+  indx++;
+    
+  buffer[indx] = gattEvtMask;
+  indx++;
+    
+  buffer[indx] = encryKeySize;
+  indx++;
+    
+  buffer[indx] = isVariable;
+  indx++;
+    
+  Osal_MemSet(&resp, 0, sizeof(resp));
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_ADD_CHAR;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.rparam = &resp;
+  rq.rlen = GATT_ADD_CHAR_RP_SIZE;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  if (resp.status) {
+    return resp.status;
+  }
+    
+  *charHandle = btohs(resp.handle);
+
+  return 0;
+}
+
+tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle,
+                                  uint16_t charHandle,
+                                  uint8_t descUuidType,
+                                  const uint8_t* uuid, 
+                                  uint8_t descValueMaxLen,
+                                  uint8_t descValueLen,
+                                  const void* descValue, 
+                                  uint8_t secPermissions,
+                                  uint8_t accPermissions,
+                                  uint8_t gattEvtMask,
+                                  uint8_t encryKeySize,
+                                  uint8_t isVariable,
+                                  uint16_t* descHandle)                     
+{
+  struct hci_request rq;
+  gatt_add_char_desc_rp resp;
+  uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+  uint8_t uuid_len;
+  uint8_t indx = 0;
+    
+  serviceHandle = htobs(serviceHandle);
+  Osal_MemCpy(buffer + indx, &serviceHandle, 2);
+  indx += 2;
+    
+  charHandle = htobs(charHandle);
+  Osal_MemCpy(buffer + indx, &charHandle, 2);
+  indx += 2;
+    
+  buffer[indx] = descUuidType;
+  indx++;
+    
+  if(descUuidType == UUID_TYPE_16){
+    uuid_len = 2;
+  }
+  else {
+    uuid_len = 16;
+  }        
+  Osal_MemCpy(buffer + indx, uuid, uuid_len);
+  indx +=  uuid_len;
+    
+  buffer[indx] = descValueMaxLen;
+  indx++;
+    
+  buffer[indx] = descValueLen;
+  indx++;
+
+  if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE)
+    return BLE_STATUS_INVALID_PARAMS;
+  
+  Osal_MemCpy(buffer + indx, descValue, descValueLen);
+  indx += descValueLen;
+    
+  buffer[indx] = secPermissions;
+  indx++;
+    
+  buffer[indx] = accPermissions;
+  indx++;
+    
+  buffer[indx] = gattEvtMask;
+  indx++;
+    
+  buffer[indx] = encryKeySize;
+  indx++;
+    
+  buffer[indx] = isVariable;
+  indx++;
+    
+  Osal_MemSet(&resp, 0, sizeof(resp));
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_ADD_CHAR_DESC;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.rparam = &resp;
+  rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  if (resp.status) {
+    return resp.status;
+  }
+    
+  *descHandle = btohs(resp.handle);
+
+  return 0;
+}
+
+
+tBleStatus aci_gatt_update_char_value(uint16_t servHandle, 
+				      uint16_t charHandle,
+				      uint8_t charValOffset,
+				      uint8_t charValueLen,   
+				      const void *charValue)
+{
+  struct hci_request rq;
+  uint8_t status;
+  uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+  uint8_t indx = 0;
+    
+  if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE)
+    return BLE_STATUS_INVALID_PARAMS;
+
+  servHandle = htobs(servHandle);
+  Osal_MemCpy(buffer + indx, &servHandle, 2);
+  indx += 2;
+    
+  charHandle = htobs(charHandle);
+  Osal_MemCpy(buffer + indx, &charHandle, 2);
+  indx += 2;
+    
+  buffer[indx] = charValOffset;
+  indx++;
+    
+  buffer[indx] = charValueLen;
+  indx++;
+        
+  Osal_MemCpy(buffer + indx, charValue, charValueLen);
+  indx +=  charValueLen;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_UPD_CHAR_VAL;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  if (status) {
+    return status;
+  }
+
+  return 0;
+}
+
+tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_del_char_cp cp;
+
+  cp.service_handle = htobs(servHandle);
+  cp.char_handle = htobs(charHandle);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_DEL_CHAR;
+  rq.cparam = &cp;
+  rq.clen = GATT_DEL_CHAR_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+                                      
+tBleStatus aci_gatt_del_service(uint16_t servHandle)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_del_serv_cp cp;
+
+  cp.service_handle = htobs(servHandle);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_DEL_SERV;
+  rq.cparam = &cp;
+  rq.clen = GATT_DEL_SERV_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_del_inc_serv_cp cp;
+
+  cp.service_handle = htobs(servHandle);
+  cp.inc_serv_handle = htobs(includeServHandle);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_DEL_INC_SERV;
+  rq.cparam = &cp;
+  rq.clen = GATT_DEL_INC_SERV_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_set_event_mask(uint32_t event_mask)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_set_evt_mask_cp cp;
+
+  cp.evt_mask = htobs(event_mask);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_SET_EVT_MASK;
+  rq.cparam = &cp;
+  rq.clen = GATT_SET_EVT_MASK_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+  
+tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_exchange_config_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_EXCHANGE_CONFIG;
+  rq.cparam = &cp;
+  rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE;
+  rq.event = EVT_CMD_STATUS; 
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+  
+tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle)
+{
+  struct hci_request rq;
+  uint8_t status;
+  att_find_info_req_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.start_handle = htobs(start_handle);
+  cp.end_handle = htobs(end_handle);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_ATT_FIND_INFO_REQ;
+  rq.cparam = &cp;
+  rq.clen = ATT_FIND_INFO_REQ_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+                                          uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val)
+{
+  struct hci_request rq;
+  uint8_t status;
+  att_find_by_type_value_req_cp cp;
+  
+  if(attr_val_len > sizeof(cp.attr_val))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.start_handle = htobs(start_handle);
+  cp.end_handle = htobs(end_handle);
+  Osal_MemCpy(cp.uuid, uuid, 2);
+  cp.attr_val_len = attr_val_len;
+  Osal_MemCpy(cp.attr_val, attr_val, attr_val_len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ;
+  rq.cparam = &cp;
+  rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+                                    uint8_t  uuid_type, uint8_t* uuid)
+{
+  struct hci_request rq;
+  uint8_t status;
+  att_read_by_type_req_cp cp;
+  uint8_t uuid_len;
+  
+  if(uuid_type == UUID_TYPE_16){
+    uuid_len = 2;
+  }
+  else{
+    uuid_len = 16;
+  }
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.start_handle = htobs(start_handle);
+  cp.end_handle = htobs(end_handle);
+  cp.uuid_type = uuid_type;
+  Osal_MemCpy(cp.uuid, uuid, uuid_len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_ATT_READ_BY_TYPE_REQ;
+  rq.cparam = &cp;
+  rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+                                    uint8_t  uuid_type, uint8_t* uuid)
+{
+  struct hci_request rq;
+  uint8_t status;
+  att_read_by_group_type_req_cp cp;
+  uint8_t uuid_len;
+  
+  if(uuid_type == UUID_TYPE_16){
+    uuid_len = 2;
+  }
+  else{
+    uuid_len = 16;
+  }
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.start_handle = htobs(start_handle);
+  cp.end_handle = htobs(end_handle);
+  cp.uuid_type = uuid_type;
+  Osal_MemCpy(cp.uuid, uuid, uuid_len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ;
+  rq.cparam = &cp;
+  rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset,
+                                    uint8_t  attr_val_len, uint8_t* attr_val)
+{
+  struct hci_request rq;
+  uint8_t status;
+  att_prepare_write_req_cp cp;
+  
+  if(attr_val_len > sizeof(cp.attr_val))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.attr_handle = htobs(attr_handle);
+  cp.value_offset = htobs(value_offset);
+  cp.attr_val_len = attr_val_len;
+  Osal_MemCpy(cp.attr_val, attr_val, attr_val_len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_ATT_PREPARE_WRITE_REQ;
+  rq.cparam = &cp;
+  rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute)
+{
+  struct hci_request rq;
+  uint8_t status;
+  att_execute_write_req_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.execute = execute;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ;
+  rq.cparam = &cp;
+  rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_disc_all_prim_services_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES;
+  rq.cparam = &cp;
+  rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_disc_prim_service_by_uuid_cp cp;
+  uint8_t uuid_len;
+  
+  if(uuid_type == UUID_TYPE_16){
+    uuid_len = 2;
+  }
+  else{
+    uuid_len = 16;
+  }
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.uuid_type = uuid_type;
+  Osal_MemCpy(cp.uuid, uuid, uuid_len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID;
+  rq.cparam = &cp;
+  rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, 
+					   uint16_t end_service_handle)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_find_included_services_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.start_handle = htobs(start_service_handle);
+  cp.end_handle = htobs(end_service_handle);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES;
+  rq.cparam = &cp;
+  rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, 
+					    uint16_t end_attr_handle)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_disc_all_charac_of_serv_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.start_attr_handle = htobs(start_attr_handle);
+  cp.end_attr_handle = htobs(end_attr_handle);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV;
+  rq.cparam = &cp;
+  rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle,
+				                     uint16_t end_handle, uint8_t charUuidType,
+                                                     const uint8_t* charUuid)
+{
+  struct hci_request rq;
+  uint8_t status;
+  
+  uint8_t buffer[23];
+  uint8_t uuid_len;
+  uint8_t indx = 0;
+    
+  conn_handle = htobs(conn_handle);
+  Osal_MemCpy(buffer + indx, &conn_handle, 2);
+  indx += 2;
+    
+  start_handle = htobs(start_handle);
+  Osal_MemCpy(buffer + indx, &start_handle, 2);
+  indx += 2;
+  
+  end_handle = htobs(end_handle);
+  Osal_MemCpy(buffer + indx, &end_handle, 2);
+  indx += 2;
+  
+  buffer[indx] = charUuidType;
+  indx++;
+    
+  if(charUuidType == 0x01){
+    uuid_len = 2;
+  }
+  else {
+    uuid_len = 16;
+  }        
+  Osal_MemCpy(buffer + indx, charUuid, uuid_len);
+  indx +=  uuid_len;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, 
+						uint16_t char_end_handle)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_disc_all_charac_descriptors_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.char_val_handle = htobs(char_val_handle);
+  cp.char_end_handle = htobs(char_end_handle);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS;
+  rq.cparam = &cp;
+  rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_read_charac_val_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.attr_handle = htobs(attr_handle);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_READ_CHARAC_VAL;
+  rq.cparam = &cp;
+  rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+                                    uint8_t  uuid_type, uint8_t* uuid)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_read_using_charac_uuid_cp cp;
+  uint8_t uuid_len;
+  
+  if(uuid_type == UUID_TYPE_16){
+    uuid_len = 2;
+  }
+  else{
+    uuid_len = 16;
+  }
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.start_handle = htobs(start_handle);
+  cp.end_handle = htobs(end_handle);
+  cp.uuid_type = uuid_type;
+  Osal_MemCpy(cp.uuid, uuid, uuid_len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID;
+  rq.cparam = &cp;
+  rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, 
+					 uint16_t val_offset)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_read_long_charac_val_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.attr_handle = htobs(attr_handle);
+  cp.val_offset = htobs(val_offset);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL;
+  rq.cparam = &cp;
+  rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, 
+                                             uint8_t* set_of_handles)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_read_multiple_charac_val_cp cp;
+  
+  if(num_handles*2 > sizeof(cp.set_of_handles))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.num_handles = htobs(num_handles);
+  Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL;
+  rq.cparam = &cp;
+  rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+
+
+tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, 
+				       uint8_t value_len, uint8_t *attr_value)
+{
+  struct hci_request rq;
+  uint8_t status;
+  uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+  uint8_t indx = 0;
+    
+  if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE)
+    return BLE_STATUS_INVALID_PARAMS;
+
+  conn_handle = htobs(conn_handle);
+  Osal_MemCpy(buffer + indx, &conn_handle, 2);
+  indx += 2;
+    
+  attr_handle = htobs(attr_handle);
+  Osal_MemCpy(buffer + indx, &attr_handle, 2);
+  indx += 2;
+
+  buffer[indx] = value_len;
+  indx++;
+        
+  Osal_MemCpy(buffer + indx, attr_value, value_len);
+  indx +=  value_len;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_WRITE_CHAR_VALUE;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle,
+                                          uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_write_long_charac_val_cp cp;
+  
+  if(val_len > sizeof(cp.attr_val))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.attr_handle = htobs(attr_handle);
+  cp.val_offset = htobs(val_offset);
+  cp.val_len = val_len;
+  Osal_MemCpy(cp.attr_val, attr_val, val_len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL;
+  rq.cparam = &cp;
+  rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle,
+                                          uint16_t val_offset, uint8_t val_len, uint8_t* attr_val)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_write_charac_reliable_cp cp;
+  
+  if(val_len > sizeof(cp.attr_val))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.attr_handle = htobs(attr_handle);
+  cp.val_offset = htobs(val_offset);
+  cp.val_len = val_len;
+  Osal_MemCpy(cp.attr_val, attr_val, val_len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE;
+  rq.cparam = &cp;
+  rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle,
+                                          uint16_t val_offset, uint8_t val_len, uint8_t* attr_val)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_write_charac_reliable_cp cp;
+  
+  if(val_len > sizeof(cp.attr_val))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.attr_handle = htobs(attr_handle);
+  cp.val_offset = htobs(val_offset);
+  cp.val_len = val_len;
+  Osal_MemCpy(cp.attr_val, attr_val, val_len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC;
+  rq.cparam = &cp;
+  rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle,
+                                          uint16_t val_offset)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_read_long_charac_desc_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.attr_handle = htobs(attr_handle);
+  cp.val_offset = htobs(val_offset);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC;
+  rq.cparam = &cp;
+  rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, 
+					   uint8_t value_len, uint8_t *attr_value)
+{
+  struct hci_request rq;
+  uint8_t status;
+  uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+  uint8_t indx = 0;
+    
+  if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE)
+    return BLE_STATUS_INVALID_PARAMS;
+
+  conn_handle = htobs(conn_handle);
+  Osal_MemCpy(buffer + indx, &conn_handle, 2);
+  indx += 2;
+    
+  attr_handle = htobs(attr_handle);
+  Osal_MemCpy(buffer + indx, &attr_handle, 2);
+  indx += 2;
+
+  buffer[indx] = value_len;
+  indx++;
+        
+  Osal_MemCpy(buffer + indx, attr_value, value_len);
+  indx +=  value_len;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.event = EVT_CMD_STATUS; 
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_read_long_charac_desc_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.attr_handle = htobs(attr_handle);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR;
+  rq.cparam = &cp;
+  rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle,
+                                              uint8_t val_len, const uint8_t* attr_val)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_write_without_resp_cp cp;
+  
+  if(val_len > sizeof(cp.attr_val))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.attr_handle = htobs(attr_handle);
+  cp.val_len = val_len;
+  Osal_MemCpy(cp.attr_val, attr_val, val_len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE;
+  rq.cparam = &cp;
+  rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; 
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle,
+                                              uint8_t val_len, uint8_t* attr_val)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_signed_write_without_resp_cp cp;
+  
+  if(val_len > sizeof(cp.attr_val))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.attr_handle = htobs(attr_handle);
+  cp.val_len = val_len;
+  Osal_MemCpy(cp.attr_val, attr_val, val_len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE;
+  rq.cparam = &cp;
+  rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_confirm_indication_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_CONFIRM_INDICATION;
+  rq.cparam = &cp;
+  rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
+
+tBleStatus aci_gatt_write_response(uint16_t conn_handle,
+                                   uint16_t attr_handle,
+                                   uint8_t write_status,
+                                   uint8_t err_code,
+                                   uint8_t att_val_len,
+                                   uint8_t *att_val)
+{
+  struct hci_request rq;
+  uint8_t status;
+  uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+  uint8_t indx = 0;
+  
+  if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE)
+    return BLE_STATUS_INVALID_PARAMS;
+
+  conn_handle = htobs(conn_handle);  
+  Osal_MemCpy(buffer + indx, &conn_handle, 2);
+  indx += 2;
+    
+  attr_handle = htobs(attr_handle);
+  Osal_MemCpy(buffer + indx, &attr_handle, 2);
+  indx += 2;
+    
+  buffer[indx] = write_status;
+  indx += 1;
+    
+  buffer[indx] = err_code;
+  indx += 1;
+    
+  buffer[indx] = att_val_len;
+  indx += 1;
+    
+  Osal_MemCpy(buffer + indx, att_val, att_val_len);
+  indx += att_val_len;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_WRITE_RESPONSE;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  if (status) {
+    return status;
+  }
+
+  return 0;
+}
+
+tBleStatus aci_gatt_allow_read(uint16_t conn_handle)
+{
+    struct hci_request rq;
+    gatt_allow_read_cp cp;
+    uint8_t status;
+    
+    cp.conn_handle = htobs(conn_handle);
+
+    Osal_MemSet(&rq, 0, sizeof(rq));
+    rq.ogf = OGF_VENDOR_CMD;
+    rq.ocf = OCF_GATT_ALLOW_READ;
+    rq.cparam = &cp;
+    rq.clen = GATT_ALLOW_READ_CP_SIZE;
+    rq.rparam = &status;
+    rq.rlen = 1;
+
+    if (hci_send_req(&rq, FALSE) < 0)
+      return BLE_STATUS_TIMEOUT;
+
+    return status;
+}
+
+tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle,
+                                            uint8_t security_permission)
+{
+    struct hci_request rq;
+    gatt_set_security_permission_cp cp;
+    uint8_t status;
+    
+    cp.service_handle = htobs(service_handle);
+    cp.attr_handle = htobs(attr_handle);
+    cp.security_permission = security_permission;
+
+    Osal_MemSet(&rq, 0, sizeof(rq));
+    rq.ogf = OGF_VENDOR_CMD;
+    rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION;
+    rq.cparam = &cp;
+    rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE;
+    rq.rparam = &status;
+    rq.rlen = 1;
+
+    if (hci_send_req(&rq, FALSE) < 0)
+      return BLE_STATUS_TIMEOUT;
+
+    return status;
+}
+
+tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, 
+				   uint16_t charHandle,
+				   uint16_t charDescHandle,
+				   uint16_t charDescValOffset,
+				   uint8_t charDescValueLen,   
+				   const void *charDescValue)
+{
+  struct hci_request rq;
+  uint8_t status;
+  uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+  uint8_t indx = 0;
+    
+  if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE)
+    return BLE_STATUS_INVALID_PARAMS;
+
+  servHandle = htobs(servHandle);
+  Osal_MemCpy(buffer + indx, &servHandle, 2);
+  indx += 2;
+    
+  charHandle = htobs(charHandle);
+  Osal_MemCpy(buffer + indx, &charHandle, 2);
+  indx += 2;
+    
+  charDescHandle = htobs(charDescHandle);
+  Osal_MemCpy(buffer + indx, &charDescHandle, 2);
+  indx += 2;
+    
+  Osal_MemCpy(buffer + indx, &charDescValOffset, 2);
+  indx += 2;
+    
+  buffer[indx] = charDescValueLen;
+  indx++;
+        
+  Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen);
+  indx +=  charDescValueLen;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_SET_DESC_VAL;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data)
+{
+  struct hci_request rq;
+  gatt_read_handle_val_cp cp;
+  gatt_read_handle_val_rp rp;
+ 
+  if(data_len > sizeof(rp.value))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  cp.attr_handle = htobs(attr_handle);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_READ_HANDLE_VALUE;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &rp;
+  rq.rlen = sizeof(rp);
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if(rp.status)
+    return rp.status;
+
+  *data_len_out_p = btohs(rp.value_len);
+
+  Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p));
+
+  return 0;
+}
+
+tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data)
+{
+  struct hci_request rq;
+  gatt_read_handle_val_offset_cp cp;
+  gatt_read_handle_val_offset_rp rp;
+  
+  if(data_len > sizeof(rp.value))
+    return BLE_STATUS_INVALID_PARAMS;
+
+  cp.attr_handle = htobs(attr_handle);
+  cp.offset = offset;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &rp;
+  rq.rlen = sizeof(rp);
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if(rp.status)
+    return rp.status;
+
+  *data_len_out_p = rp.value_len;
+
+  Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p));
+
+  return 0; 
+}
+
+tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle,
+                                                  uint8_t update_type, uint16_t char_length,
+                                                  uint16_t value_offset, uint8_t value_length,
+                                                  const uint8_t* value)
+{
+  struct hci_request rq;
+  uint8_t status;
+  gatt_upd_char_val_ext_cp cp;
+  
+  if(value_length > sizeof(cp.value))
+    return BLE_STATUS_INVALID_PARAMS;
+  
+  cp.service_handle = htobs(service_handle);
+  cp.char_handle = htobs(char_handle);
+  cp.update_type = update_type;
+  cp.char_length = htobs(char_length);
+  cp.value_offset = htobs(value_offset);
+  cp.value_length = value_length;
+  Osal_MemCpy(cp.value, value, value_length);
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GATT_UPD_CHAR_VAL_EXT;
+  rq.cparam = &cp;
+  rq.clen = GATT_UPD_CHAR_VAL_EXT_CP_SIZE + value_length;
+  rq.rparam = &status;
+  rq.rlen = 1;
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,266 @@
+/******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
+* File Name          : bluenrg_hci.c
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 4-Oct-2013
+* Description        : File with HCI commands for BlueNRG FW6.0 and above.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#include "ble_hal_types.h"
+#include "ble_osal.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_hci_const.h"
+#include "bluenrg_aci_const.h"
+#include "bluenrg_hal_aci.h"
+#include "bluenrg_gatt_server.h"
+#include "bluenrg_gap.h"
+
+#define MIN(a,b)            ((a) < (b) )? (a) : (b)
+#define MAX(a,b)            ((a) > (b) )? (a) : (b)
+
+tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number)
+{
+  struct hci_request rq;
+  hal_get_fw_build_number_rp rp;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_HAL_GET_FW_BUILD_NUMBER;
+  rq.rparam = &rp;
+  rq.rlen = sizeof(rp);
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if(rp.status)
+    return rp.status;
+  
+  *build_number = rp.build_number;
+  
+  return 0;
+}
+
+tBleStatus aci_hal_write_config_data(uint8_t offset, 
+                                    uint8_t len,
+                                    const uint8_t *val)
+{
+  struct hci_request rq;
+  uint8_t status;
+  uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+  uint8_t indx = 0;
+    
+  if ((len+2) > HCI_MAX_PAYLOAD_SIZE)
+    return BLE_STATUS_INVALID_PARAMS;
+
+  buffer[indx] = offset;
+  indx++;
+    
+  buffer[indx] = len;
+  indx++;
+        
+  Osal_MemCpy(buffer + indx, val, len);
+  indx +=  len;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_HAL_WRITE_CONFIG_DATA;
+  rq.cparam = (void *)buffer;
+  rq.clen = indx;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+
+tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data)
+{
+  struct hci_request rq;
+  hal_read_config_data_cp cp;
+  hal_read_config_data_rp rp;
+
+  cp.offset = offset;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_HAL_READ_CONFIG_DATA;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &rp;
+  rq.rlen = sizeof(rp);
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  if(rp.status)
+    return rp.status;
+
+  *data_len_out_p = rq.rlen-1;
+
+  Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p));
+
+  return 0;
+}
+
+tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level)
+{
+  struct hci_request rq;
+  hal_set_tx_power_level_cp cp;    
+  uint8_t status;
+    
+  cp.en_high_power = en_high_power;
+  cp.pa_level = pa_level;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL;
+  rq.cparam = &cp;
+  rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+    return status;
+}
+
+tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets)
+{
+  struct hci_request rq;
+  hal_le_tx_test_packet_number_rp resp;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_HAL_LE_TX_TEST_PACKET_NUMBER;
+  rq.rparam = &resp;
+  rq.rlen = sizeof(resp);
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if (resp.status) {
+    return resp.status;
+  }
+  
+  *number_of_packets = btohl(resp.number_of_packets);
+
+  return 0;
+}
+
+tBleStatus aci_hal_device_standby(void)
+{
+  struct hci_request rq;
+  uint8_t status;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_HAL_DEVICE_STANDBY;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_hal_tone_start(uint8_t rf_channel)
+{
+  struct hci_request rq;
+  hal_tone_start_cp cp;    
+  uint8_t status;
+    
+  cp.rf_channel = rf_channel;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_HAL_TONE_START;
+  rq.cparam = &cp;
+  rq.clen = HAL_TONE_START_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+    
+  return status;
+}
+
+tBleStatus aci_hal_tone_stop(void)
+{
+  struct hci_request rq;
+  uint8_t status;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_HAL_TONE_STOP;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8])
+{
+  struct hci_request rq;
+  hal_get_link_status_rp rp;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_HAL_GET_LINK_STATUS;
+  rq.rparam = &rp;
+  rq.rlen = sizeof(rp);
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if(rp.status)
+    return rp.status;
+  
+  Osal_MemCpy(link_status,rp.link_status,sizeof(link_status));
+  for(int i = 0; i < 8; i++)  
+    conn_handle[i] = btohs(rp.conn_handle[i]);
+  
+  return 0;
+}
+
+tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot)
+{
+  struct hci_request rq;
+  hal_get_anchor_period_rp rp;
+  
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_HAL_GET_ANCHOR_PERIOD;
+  rq.rparam = &rp;
+  rq.rlen = sizeof(rp);
+  
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  if(rp.status)
+    return rp.status;
+  
+  *anchor_period = btohl(rp.anchor_period);
+  *max_free_slot = btohl(rp.max_free_slot);
+  
+  return 0;
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,117 @@
+/******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
+* File Name          : bluenrg_hci.c
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 4-Oct-2013
+* Description        : File with HCI commands for BlueNRG FW6.0 and above.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#include "ble_hal_types.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_osal.h"
+#include "ble_hci_const.h"
+#include "bluenrg_aci_const.h"
+#include "bluenrg_hal_aci.h"
+#include "bluenrg_gap.h"
+
+#define MIN(a,b)            ((a) < (b) )? (a) : (b)
+#define MAX(a,b)            ((a) > (b) )? (a) : (b)
+
+tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min,
+							 uint16_t interval_max, uint16_t slave_latency,
+							 uint16_t timeout_multiplier)
+{
+  struct hci_request rq;
+  uint8_t status;
+  l2cap_conn_param_update_req_cp cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.interval_min = htobs(interval_min);
+  cp.interval_max = htobs(interval_max);
+  cp.slave_latency = htobs(slave_latency);
+  cp.timeout_multiplier = htobs(timeout_multiplier);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ;
+  rq.cparam = &cp;
+  rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE;
+  rq.event = EVT_CMD_STATUS;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+  
+  return status;  
+}
+
+tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min,
+							 uint16_t interval_max, uint16_t slave_latency,
+							 uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length,
+                             uint8_t id, uint8_t accept)
+{
+  struct hci_request rq;
+  uint8_t status;
+  l2cap_conn_param_update_resp_cp_IDB05A1 cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.interval_min = htobs(interval_min);
+  cp.interval_max = htobs(interval_max);
+  cp.slave_latency = htobs(slave_latency);
+  cp.timeout_multiplier = htobs(timeout_multiplier);
+  cp.min_ce_length = htobs(min_ce_length);
+  cp.max_ce_length = htobs(max_ce_length);
+  cp.id = id;
+  cp.accept = accept;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min,
+							 uint16_t interval_max, uint16_t slave_latency,
+							 uint16_t timeout_multiplier, uint8_t id, uint8_t accept)
+{
+  struct hci_request rq;
+  uint8_t status;
+  l2cap_conn_param_update_resp_cp_IDB04A1 cp;
+
+  cp.conn_handle = htobs(conn_handle);
+  cp.interval_min = htobs(interval_min);
+  cp.interval_max = htobs(interval_max);
+  cp.slave_latency = htobs(slave_latency);
+  cp.timeout_multiplier = htobs(timeout_multiplier);
+  cp.id = id;
+  cp.accept = accept;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP;
+  rq.cparam = &cp;
+  rq.clen = sizeof(cp);
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,269 @@
+/******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
+* File Name          : bluenrg_hci.c
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 4-Oct-2013
+* Description        : File with HCI commands for BlueNRG FW6.0 and above.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#include "ble_hal_types.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_osal.h"
+#include "ble_hci_const.h"
+#include "bluenrg_aci_const.h"
+#include "bluenrg_updater_aci.h"
+
+#define MIN(a,b)            ((a) < (b) )? (a) : (b)
+#define MAX(a,b)            ((a) > (b) )? (a) : (b)
+
+tBleStatus aci_updater_start(void)
+{
+  struct hci_request rq;
+  uint8_t status = 0;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_UPDATER_START;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  hci_send_req(&rq, FALSE); // No command complete is sent.
+
+  return status;  
+}
+
+tBleStatus aci_updater_reboot(void)
+{
+  struct hci_request rq;
+  uint8_t status = 0;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_UPDATER_REBOOT;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  hci_send_req(&rq, FALSE); // No command complete is sent.
+
+  return status;
+}
+
+tBleStatus aci_get_updater_version(uint8_t *version)
+{
+  struct hci_request rq;
+  get_updater_version_rp resp;
+
+  Osal_MemSet(&resp, 0, sizeof(resp));
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GET_UPDATER_VERSION;
+  rq.rparam = &resp;
+  rq.rlen = GET_UPDATER_VERSION_RP_SIZE;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+    
+  *version = resp.version;
+
+  return resp.status;
+}
+
+tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size)
+{
+  struct hci_request rq;
+  get_updater_bufsize_rp resp;
+
+  Osal_MemSet(&resp, 0, sizeof(resp));
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_GET_UPDATER_BUFSIZE;
+  rq.rparam = &resp;
+  rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+    
+  *buffer_size = resp.buffer_size;
+
+  return resp.status;
+}
+
+tBleStatus aci_erase_blue_flag(void)
+{
+  struct hci_request rq;
+  uint8_t status;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;  
+}
+
+tBleStatus aci_reset_blue_flag(void)
+{
+  struct hci_request rq;
+  uint8_t status;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;  
+}
+
+tBleStatus aci_updater_erase_sector(uint32_t address)
+{
+  struct hci_request rq;
+  updater_erase_sector_cp cp;    
+  uint8_t status;
+    
+  cp.address = htobl(address);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_UPDATER_ERASE_SECTOR;
+  rq.cparam = &cp;
+  rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+
+  return status;
+}
+
+tBleStatus aci_updater_program_data_block(uint32_t address, 
+				   uint16_t len,
+				   const uint8_t *data)
+{
+  struct hci_request rq;
+  uint8_t status;
+  updater_prog_data_block_cp cp;
+    
+  if( len > sizeof(cp.data))
+    return BLE_STATUS_INVALID_PARAMS;
+  
+  cp.address = htobl(address);
+  cp.data_len = htobs(len);        
+  Osal_MemCpy(cp.data, data, len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK;
+  rq.cparam = &cp;
+  rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len;
+  rq.rparam = &status;
+  rq.rlen = 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+    
+  return status;
+}
+
+tBleStatus aci_updater_read_data_block(uint32_t address,
+				uint16_t data_len,
+				uint8_t *data)
+{
+  struct hci_request rq;
+  updater_read_data_block_cp cp;
+  uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+    
+  if((data_len+1) > HCI_MAX_PAYLOAD_SIZE)
+    return BLE_STATUS_INVALID_PARAMS;
+    
+  cp.address = htobl(address);
+  cp.data_len = htobs(data_len);
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_UPDATER_READ_DATA_BLOCK;
+  rq.cparam = &cp;
+  rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE;
+  rq.rparam = buffer;
+  rq.rlen = data_len + 1;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+    
+  // First byte is status
+  Osal_MemCpy(data, buffer+1, data_len);
+
+  return buffer[0];
+}
+
+tBleStatus aci_updater_calc_crc(uint32_t address,
+                         uint8_t num_sectors,
+                         uint32_t *crc)
+{
+  struct hci_request rq;
+  updater_calc_crc_cp cp;
+  updater_calc_crc_rp resp;
+    
+  Osal_MemSet(&resp, 0, sizeof(resp));
+    
+  cp.address = htobl(address);
+  cp.num_sectors = num_sectors;
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_UPDATER_CALC_CRC;
+  rq.cparam = &cp;
+  rq.clen = UPDATER_CALC_CRC_CP_SIZE;
+  rq.rparam = &resp;
+  rq.rlen = UPDATER_CALC_CRC_RP_SIZE;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+    
+  *crc = btohl(resp.crc);
+    
+  return resp.status;
+}
+
+tBleStatus aci_updater_hw_version(uint8_t *version)
+{
+  struct hci_request rq;
+  updater_hw_version_rp resp;
+
+  Osal_MemSet(&resp, 0, sizeof(resp));
+
+  Osal_MemSet(&rq, 0, sizeof(rq));
+  rq.ogf = OGF_VENDOR_CMD;
+  rq.ocf = OCF_UPDATER_HW_VERSION;
+  rq.rparam = &resp;
+  rq.rlen = UPDATER_HW_VERSION_RP_SIZE;
+
+  if (hci_send_req(&rq, FALSE) < 0)
+    return BLE_STATUS_TIMEOUT;
+    
+  *version = resp.version;
+
+  return resp.status;
+}
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,423 @@
+
+#include "ble_hal.h"
+#include "ble_hal_types.h"
+#include "ble_status.h"
+#include "bluenrg_aci.h"
+#include "bluenrg_utils.h"
+#include "ble_hci.h"
+#include "ble_hci_le.h"
+#include "ble_osal.h"
+#include "string.h"
+#include "stm32_bluenrg_ble.h"
+
+#define SUPPORTED_BOOTLOADER_VERSION_MIN  3
+#define SUPPORTED_BOOTLOADER_VERSION_MAX  5
+
+#define BASE_ADDRESS 0x10010000
+
+#define FW_OFFSET       (2*1024)  // 2 KB
+#define FW_OFFSET_MS    0
+#define FULL_STACK_SIZE (66*1024) // 66 KB
+#define BOOTLOADER_SIZE (2*1024)  // 2 kB
+#define SECTOR_SIZE     (2*1024)  // 2 KB
+
+// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 +
+// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0
+#define CRC_POLY        0x04C11DB7      // the poly without the x**32
+
+#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC
+
+#define IFR_SIZE 192
+#define IFR_BASE_ADDRESS 0x10020000
+#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE)  // Offset in IFR sector containing configuration data
+
+#if BLUENRG_MS
+#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET
+#else
+#define IFR_WRITE_OFFSET_BEGIN 0
+#endif
+
+
+#define BLUE_FLAG_OFFSET 0x8C0
+#define MAX_ERASE_RETRIES 2
+#define MAX_WRITE_RETRIES 2
+#define MIN_WRITE_BLOCK_SIZE 4
+#define MAX_WRITE_BLOCK_SIZE    64        // 64 bytes
+#define READ_BLOCK_SIZE         64        // 64 bytes
+
+#define RETRY_COMMAND(func, num_ret, error)  \
+{					\
+  uint8_t num_retries;                  \
+  num_retries = 0;			\
+  error = 0;				\
+  while (num_retries++ < num_ret)  {	\
+    if (func == BLE_STATUS_SUCCESS)	\
+      break;				\
+    if (num_retries == num_ret)		\
+      error = BLE_UTIL_ACI_ERROR;	\
+  }					\
+}
+
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, 
+   they are extended with 0xFF until sector size is reached
+*/
+static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes)
+{
+    uint32_t i, j, a1;
+    uint32_t crc, value;
+
+    crc = 0;
+    for (i = 0; i < SECTOR_SIZE; i += 4) {
+      uint8_t *dataw = (uint8_t *) &value;
+     
+      dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF;
+      dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF;
+      dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF;
+      dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF;
+
+      crc = crc ^ value;
+      for (j = 0; j < 32; j ++) {
+	a1 = (crc >> 31) & 0x1;
+	crc = (crc << 1) ^ (a1 * CRC_POLY);
+      }
+    }
+
+    return crc;
+}
+
+int program_device(const uint8_t *fw_image, uint32_t fw_size)
+{
+  uint8_t version, num_erase_retries, status, write_block_size;
+  uint32_t address;
+  uint32_t crc, crc2, crc_size;
+  uint32_t fw_offset = FW_OFFSET;
+  
+  BlueNRG_HW_Bootloader();
+  HCI_Process(); // To receive the EVT_INITIALIZED
+
+  if(aci_get_updater_version(&version))
+    return BLE_UTIL_ACI_ERROR;
+  
+  if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX)
+    return BLE_UTIL_UNSUPPORTED_VERSION;
+  
+  if(aci_updater_hw_version(&version))
+    return BLE_UTIL_ACI_ERROR;
+  
+  if(version==0x31){
+    // It does not contain bootloader inside first sector. It may contain code.
+    fw_offset = FW_OFFSET_MS;
+  }
+  
+  if (fw_size != FULL_STACK_SIZE)
+    return BLE_UTIL_WRONG_IMAGE_SIZE;
+
+  if (fw_size % MIN_WRITE_BLOCK_SIZE)
+    return BLE_UTIL_WRONG_IMAGE_SIZE;
+
+
+  /***********************************************************************
+  * Erase BLUE flag
+  ************************************************************************/
+  RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status);
+  if (status != BLE_STATUS_SUCCESS)
+    return status;
+
+  /***********************************************************************
+  * Erase and Program sectors
+  ************************************************************************/  
+  for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE) {
+    num_erase_retries = 0;
+    while (num_erase_retries++ < MAX_ERASE_RETRIES) {
+      aci_updater_erase_sector(BASE_ADDRESS + i);
+      for (int j=i; ((j<i+SECTOR_SIZE)&&(j<fw_size)); j += write_block_size) {
+        
+        write_block_size = MIN(fw_size-j, MAX_WRITE_BLOCK_SIZE);	
+        
+        RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, write_block_size, fw_image+j), MAX_WRITE_RETRIES, status);
+	if (status != BLE_STATUS_SUCCESS)
+	  break;
+      }
+      if (status == BLE_STATUS_SUCCESS)
+	break;
+    }
+    if (num_erase_retries == MAX_ERASE_RETRIES)
+      return BLE_UTIL_ACI_ERROR;
+  }
+  
+  /***********************************************************************
+  * Verify firmware
+  ************************************************************************/
+  for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE){
+    address = BASE_ADDRESS + i;
+    if(aci_updater_calc_crc(address, 1, &crc))
+      return BLE_UTIL_ACI_ERROR;
+    
+    crc_size = MIN(fw_size-i,SECTOR_SIZE);
+
+    crc2 = updater_calc_crc(fw_image+i,crc_size);
+    if(crc!=crc2)
+      return BLE_UTIL_CRC_ERROR;
+  }
+
+  /***********************************************************************
+  * Write BLUE flag
+  ************************************************************************/
+  RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status);
+  if (status != BLE_STATUS_SUCCESS)
+    return status;
+  
+  BlueNRG_RST();
+  HCI_Process(); // To receive the EVT_INITIALIZED
+  
+  return BLE_STATUS_SUCCESS;
+}
+
+int read_IFR(uint8_t *data)
+{
+  uint8_t version, offset;
+  tBleStatus ret;
+  
+  offset = 0;
+  aci_updater_start();
+  if(aci_get_updater_version(&version))
+    return BLE_UTIL_ACI_ERROR;
+  
+  if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX)
+    return BLE_UTIL_UNSUPPORTED_VERSION;
+  
+  /***********************************************************************
+  * Reading last 3 IFR 64-byte blocks
+  ************************************************************************/
+  for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += READ_BLOCK_SIZE){
+    ret = aci_updater_read_data_block(BASE_ADDRESS+i, READ_BLOCK_SIZE, (data+offset));
+    offset += READ_BLOCK_SIZE;
+    if(ret) return BLE_UTIL_ACI_ERROR;
+  }
+  
+  BlueNRG_RST();
+  HCI_Process(); // To receive the EVT_INITIALIZED
+
+  return BLE_STATUS_SUCCESS;
+  
+}
+
+void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config)
+{
+  IFR_config->stack_mode = data[0];
+  IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28);
+  IFR_config->master_sca = data[30];
+  IFR_config->hs_startup_time = LE_TO_HOST_16(data+32);
+  IFR_config->year = BCD_TO_INT(data[41]);
+  IFR_config->month = BCD_TO_INT(data[42]);
+  IFR_config->day = BCD_TO_INT(data[43]);    
+}
+
+int IFR_validate(IFR_config2_TypeDef *IFR_config)
+{
+#if BLUENRG_MS
+  if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4)
+#else
+    if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3)
+#endif
+      return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode
+  if(IFR_config->master_sca > 7)
+    return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA
+  if(IFR_config->month > 12 || IFR_config->month < 1)
+    return BLE_UTIL_PARSE_ERROR; // Invalid date
+  if(IFR_config->day > 31 || IFR_config->day < 1)
+    return BLE_UTIL_PARSE_ERROR; // Invalid date
+  if(IFR_config->month > 12 || IFR_config->month < 1)
+    return BLE_UTIL_PARSE_ERROR; // Invalid date
+  
+  return BLE_STATUS_SUCCESS;
+}
+
+/* TODO: Function to generate data from given options. */
+
+void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64])
+{
+  data[0] = IFR_config->stack_mode;
+  HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm);
+  data[30] = IFR_config->master_sca;
+  HOST_TO_LE_16(data+32, IFR_config->hs_startup_time);  
+  data[41] = INT_TO_BCD(IFR_config->year);
+  data[42] = INT_TO_BCD(IFR_config->month);
+  data[43] = INT_TO_BCD(IFR_config->day);
+}
+
+
+int program_IFR(const IFR_config_TypeDef *ifr_image)
+{
+  uint8_t version, num_erase_retries;
+  tBleStatus ret;
+#if BLUENRG_MS
+  const uint8_t *ifr_data = (uint8_t *)ifr_image;
+#else
+  uint8_t ifr_data[SECTOR_SIZE];
+#endif
+  uint8_t hwVersion;
+  uint16_t fwVersion;
+    
+  if(getBlueNRGVersion(&hwVersion, &fwVersion))
+    return BLE_UTIL_ACI_ERROR;
+  
+  BlueNRG_HW_Bootloader();
+  HCI_Process(); // To receive the EVT_INITIALIZED
+  
+  if(aci_get_updater_version(&version))
+    return BLE_UTIL_ACI_ERROR;
+  
+  if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX)
+    return BLE_UTIL_UNSUPPORTED_VERSION;
+  
+#ifndef BLUENRG_MS
+    /***********************************************************************
+   * READ IFR data
+   ************************************************************************/  
+  for(int i = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE){
+    ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_data+i);
+    if(ret != BLE_STATUS_SUCCESS){
+      return ret;
+    }
+  }
+#endif
+  
+  /***********************************************************************
+  * Erase & Flashing IFR sectors
+  ************************************************************************/
+#ifndef BLUENRG_MS  
+  Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE);
+#endif
+  num_erase_retries = 0;
+  while (num_erase_retries++ < MAX_ERASE_RETRIES) {
+    aci_updater_erase_sector(IFR_BASE_ADDRESS);
+    for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += MAX_WRITE_BLOCK_SIZE, j += MAX_WRITE_BLOCK_SIZE) {
+      RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, MAX_WRITE_BLOCK_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret);
+      if (ret != BLE_STATUS_SUCCESS)
+	break;
+    }
+    if (ret == BLE_STATUS_SUCCESS)
+      break;
+  }
+  if (num_erase_retries == MAX_ERASE_RETRIES)
+    return BLE_UTIL_ACI_ERROR;
+
+  /***********************************************************************
+  * Verify IFR
+  ************************************************************************/  
+  {
+    uint8_t ifr_updated[READ_BLOCK_SIZE];
+    for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE, j += READ_BLOCK_SIZE){
+      ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_updated);
+      if(ret != BLE_STATUS_SUCCESS){
+	return ret;
+      }
+      if (memcmp(ifr_updated, ifr_data+j, READ_BLOCK_SIZE) != 0)
+	return BLE_UTIL_WRONG_VERIFY;
+    }
+  }
+
+  BlueNRG_RST();
+  HCI_Process(); // To receive the EVT_INITIALIZED
+    
+  return BLE_STATUS_SUCCESS;
+}
+
+uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data)
+{
+  uint8_t ifr_updated[READ_BLOCK_SIZE];
+  uint8_t version, ret = BLE_STATUS_SUCCESS;
+    
+  aci_updater_start();
+  if(aci_get_updater_version(&version))
+    return BLE_UTIL_ACI_ERROR;
+  for(int i = 0; i < IFR_SIZE; i += READ_BLOCK_SIZE){
+    ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, READ_BLOCK_SIZE, ifr_updated);
+    if(ret != BLE_STATUS_SUCCESS){
+      return ret;
+    }
+    if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, READ_BLOCK_SIZE) != 0)
+    {
+      ret = BLE_UTIL_WRONG_VERIFY;
+      break;
+    }
+  }
+
+  BlueNRG_RST();
+  HCI_Process(); // To receive the EVT_INITIALIZED
+  
+  return ret;
+}
+
+uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion)
+{
+  uint8_t status;
+  uint8_t hci_version, lmp_pal_version;
+  uint16_t hci_revision, manufacturer_name, lmp_pal_subversion;
+
+  status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, 
+				     &manufacturer_name, &lmp_pal_subversion);
+
+  if (status == BLE_STATUS_SUCCESS) {
+    *hwVersion = hci_revision >> 8;
+    *fwVersion = (hci_revision & 0xFF) << 8;              // Major Version Number
+    *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number
+    *fwVersion |= lmp_pal_subversion & 0xF;               // Patch Version Number
+  }
+  
+  return status;
+}
+
+uint8_t getBlueNRGUpdaterVersion(uint8_t *version)
+{
+
+  BlueNRG_HW_Bootloader();
+  HCI_Process(); // To receive the EVT_INITIALIZED
+
+  if(aci_get_updater_version(version))
+    return BLE_UTIL_ACI_ERROR;
+  
+  if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX)
+    return BLE_UTIL_UNSUPPORTED_VERSION;
+
+  BlueNRG_RST();
+  HCI_Process(); // To receive the EVT_INITIALIZED
+
+  return BLE_STATUS_SUCCESS;
+}
+
+uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version)
+{
+
+  BlueNRG_HW_Bootloader();
+  HCI_Process(); // To receive the EVT_INITIALIZED
+
+  if(aci_updater_hw_version(version))
+    return BLE_UTIL_ACI_ERROR;
+  
+  BlueNRG_RST();
+  HCI_Process(); // To receive the EVT_INITIALIZED
+
+  return BLE_STATUS_SUCCESS;
+}
+
+uint8_t isHWBootloader_Patched(void)
+{
+  uint8_t status, version;
+  uint32_t crc, address = 0x10010000;
+
+  if(aci_get_updater_version(&version))
+    return BLE_UTIL_ACI_ERROR;
+
+  RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status);
+  if (status != BLE_STATUS_SUCCESS)
+    return 0;
+
+  if (crc == BOOTLOADER_CRC_NOT_PATCHED)
+    return 0;
+
+  return 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "ble_gp_timer.h"
+
+/*---------------------------------------------------------------------------*/
+/**
+ * Set a timer.
+ *
+ * This function sets a timer for a time sometime in the
+ * future. The function timer_expired() will evaluate to true after
+ * the timer has expired.
+ *
+ * @param[in] t         A pointer to the timer
+ * @param[in] interval  The interval before the timer expires.
+ *
+ */
+void
+Timer_Set(struct timer *t, tClockTime interval)
+{
+  t->interval = interval;
+  t->start = Clock_Time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Reset the timer with the same interval.
+ *
+ * This function resets the timer with the same interval that was
+ * given to the timer_set() function. The start point of the interval
+ * is the exact time that the timer last expired. Therefore, this
+ * function will cause the timer to be stable over time, unlike the
+ * timer_restart() function.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa timer_restart()
+ */
+void
+Timer_Reset(struct timer *t)
+{
+  t->start += t->interval;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Restart the timer from the current point in time
+ *
+ * This function restarts a timer with the same interval that was
+ * given to the timer_set() function. The timer will start at the
+ * current time.
+ *
+ * \note A periodic timer will drift if this function is used to reset
+ * it. For preioric timers, use the timer_reset() function instead.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa timer_reset()
+ */
+void
+Timer_Restart(struct timer *t)
+{
+  t->start = Clock_Time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Check if a timer has expired.
+ *
+ * This function tests if a timer has expired and returns true or
+ * false depending on its status.
+ *
+ * \param t A pointer to the timer
+ *
+ * \return Non-zero if the timer has expired, zero otherwise.
+ *
+ */
+int
+Timer_Expired(struct timer *t)
+{
+  /* Note: Can not return diff >= t->interval so we add 1 to diff and return
+     t->interval < diff - required to avoid an internal error in mspgcc. */
+  tClockTime diff = (Clock_Time() - t->start) + 1;
+  return t->interval < diff;
+
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * The time until the timer expires
+ *
+ * This function returns the time until the timer expires.
+ *
+ * \param t A pointer to the timer
+ *
+ * \return The time until the timer expires
+ *
+ */
+tClockTime
+Timer_Remaining(struct timer *t)
+{
+  return t->start + t->interval - Clock_Time();
+}
+/*---------------------------------------------------------------------------*/
+#ifdef __DMA_LP__
+
+tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime,
+                                    TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb,
+                                    uint8_t *timerID)
+{
+  TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot,
+               (pf_TIMER_TimerCallBack_t) timercb);
+  TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE);
+  
+  return (BLE_STATUS_SUCCESS);
+}
+
+/*---------------------------------------------------------------------------*/
+tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID)
+{
+  TIMER_Delete(timerID);
+  
+  return (BLE_STATUS_SUCCESS);
+}
+
+#endif /* __DMA_LP__ */
+/*---------------------------------------------------------------------------*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,119 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name          : ble_list.c
+* Author             : AMS - HEA&RF BU
+* Version            : V1.0.0
+* Date               : 19-July-2012
+* Description        : Circular Linked List Implementation.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/******************************************************************************
+ * Include Files
+******************************************************************************/
+#include <ble_hal_types.h>
+#include "ble_list.h"
+
+/******************************************************************************
+ * Function Definitions 
+******************************************************************************/
+void list_init_head (tListNode * listHead)
+{
+	listHead->next = listHead;
+	listHead->prev = listHead;	
+}
+
+uint8_t list_is_empty (tListNode * listHead)
+{
+	return ((listHead->next == listHead)? TRUE:FALSE);
+}
+
+void list_insert_head (tListNode * listHead, tListNode * node)
+{
+	node->next = listHead->next;
+	node->prev = listHead;
+	listHead->next = node;
+	(node->next)->prev = node;
+}
+
+
+void list_insert_tail (tListNode * listHead, tListNode * node)
+{
+	node->next = listHead;
+	node->prev = listHead->prev;
+	listHead->prev = node;
+	(node->prev)->next = node;
+}
+
+
+void list_remove_node (tListNode * node)
+{
+	(node->prev)->next = node->next;
+	(node->next)->prev = node->prev;
+}
+
+
+void list_remove_head (tListNode * listHead, tListNode ** node )
+{
+	*node = listHead->next;
+	list_remove_node (listHead->next);
+	(*node)->next = NULL;
+	(*node)->prev = NULL;
+}
+
+
+void list_remove_tail (tListNode * listHead, tListNode ** node )
+{
+	*node = listHead->prev;
+	list_remove_node (listHead->prev);
+	(*node)->next = NULL;
+	(*node)->prev = NULL;
+}
+
+
+void list_insert_node_after (tListNode * node, tListNode * ref_node)
+{
+	node->next = ref_node->next;
+	node->prev = ref_node;
+	ref_node->next = node;
+	(node->next)->prev = node;
+}
+
+
+void list_insert_node_before (tListNode * node, tListNode * ref_node)
+{
+	node->next = ref_node;
+	node->prev = ref_node->prev;
+	ref_node->prev = node;
+	(node->prev)->next = node;
+}
+
+
+int list_get_size (tListNode * listHead)
+{
+	int size = 0;
+	tListNode * temp = listHead->next;
+	while (temp != listHead)
+	{
+		size++;
+		temp = temp->next;		
+	}
+	return (size);
+}
+
+void list_get_next_node (tListNode * ref_node, tListNode ** node)
+{
+    *node = ref_node->next;
+}
+
+
+void list_get_prev_node (tListNode * ref_node, tListNode ** node)
+{
+    *node = ref_node->prev;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,72 @@
+/**
+******************************************************************************
+* @file    ble_osal.c 
+* @author  AMS - HEA&RF BU / CL
+* @version V1.0.0
+* @date    04-July-2014
+* @brief   Implementation of OS abstraction layer functions used by the
+*          library.
+******************************************************************************
+* @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+  
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include <ble_osal.h>
+ 
+ /**
+ * @brief  Osal_MemCpy
+ * @param  dest: Pointer to the destination buffer
+ * @param  src : Pointer to the source buffer
+ * @param  size: Number of bytes to copy from the source to the destination
+ *               buffer
+ * @retval Pointer to the destination buffer
+ */
+void* Osal_MemCpy(void *dest, const void *src, unsigned int size)
+{
+    return(memcpy(dest,src,size)); 
+}
+
+/**
+ * @brief  Osal_MemSet
+ * @param  ptr  : Pointer to block of memory to fill  
+ * @param  value: Value to assign to each byte of the memory block
+ * @param  size : Number of bytes to be set to "value"
+ * @retval Pointer to the filled block of memory
+ */
+void* Osal_MemSet(void *ptr, int value, unsigned int size)
+{
+    return(memset(ptr,value,size));
+}
+
+/******************************************************************************
+ * local Functions
+ *****************************************************************************/ 
+ 
+ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,36 @@
+
+#include "ble_clock.h"
+#ifdef YOTTA_CFG_MBED_OS
+	#include "mbed-drivers/wait_api.h"
+	#include "mbed-drivers/rtc_time.h"
+#else
+    #include "wait_api.h"
+	#include "rtc_time.h"
+#endif
+
+const uint32_t CLOCK_SECOND = 1000;
+
+/*---------------------------------------------------------------------------*/
+
+void Clock_Init(void)
+{
+  //Not Used
+}
+
+/*---------------------------------------------------------------------------*/
+
+tClockTime Clock_Time(void)
+{
+	return clock();
+}
+
+/*---------------------------------------------------------------------------*/
+/**
+ * Wait for a multiple of 1 ms.
+ *
+ */
+void Clock_Wait(uint32_t i)
+{
+	wait_ms(i);
+}
+/*---------------------------------------------------------------------------*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,736 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/**
+  ******************************************************************************
+  * @file    btle.cpp
+  * @author  STMicroelectronics
+  * @brief   Implementation BlueNRG Init and helper functions.
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */
+
+
+#include "btle.h"
+#include "ble/Gap.h"
+#include "ble/GapEvents.h"
+#include "BlueNRGGap.h"
+#include "BlueNRGGattServer.h"
+#include "BlueNRGGattClient.h"
+#include "ble_utils.h"
+
+#include "bluenrg_targets.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* C File Includes ------------------------------------------------------------------*/
+#include <stdio.h>
+#include <string.h>
+#include "ble_hci.h"
+#include "ble_hci_const.h"
+#include "bluenrg_aci.h"
+#include "bluenrg_hal_aci.h"
+#include "bluenrg_gap.h"
+#include "bluenrg_utils.h"
+
+#include "ble_hal_types.h"
+#include "ble_hal.h"
+#include "ble_gp_timer.h"
+#include "ble_osal.h"
+#include "ble_sm.h"
+#include "ble_debug.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#define IDB04A1 0
+#define IDB05A1 1
+
+/* See file 'bluenrg_targets.h' for details regarding the BLUENRG_STACK_MODE */
+#define STACK_MODE BLUENRG_STACK_MODE
+
+void HCI_Input(tHciDataPacket * hciReadPacket);
+
+uint16_t g_gap_service_handle = 0;
+uint16_t g_appearance_char_handle = 0;
+uint16_t g_device_name_char_handle = 0;
+uint16_t g_preferred_connection_parameters_char_handle = 0;
+
+/* Private variables ---------------------------------------------------------*/
+volatile uint8_t set_connectable = 1;
+
+static char versionString[32];
+uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */
+
+/**************************************************************************/
+/*!
+    @brief  Init the BTLE stack with the specified role
+    @returns void
+*/
+/**************************************************************************/
+void btleInit(void)
+{
+    PRINTF("btleInit>>\n\r");
+
+    int ret;
+    uint8_t  hwVersion;
+    uint16_t fwVersion;
+    uint16_t service_handle, dev_name_char_handle, appearance_char_handle;
+
+    /* Reset BlueNRG SPI interface */
+    BlueNRG_RST();
+
+    /* get the BlueNRG HW and FW versions */
+    getBlueNRGVersion(&hwVersion, &fwVersion);
+
+    /*
+     * Reset BlueNRG again otherwise we won't
+     * be able to change its MAC address.
+     * aci_hal_write_config_data() must be the first
+     * command after reset otherwise it will fail.
+     */
+    BlueNRG_RST();
+
+    if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */
+        bnrg_expansion_board = IDB05A1;
+    }
+
+    /* set BLE version string */
+    setVersionString(hwVersion, fwVersion);
+
+    if (bnrg_expansion_board == IDB05A1) {
+        uint8_t stackMode = STACK_MODE;
+        ret = aci_hal_write_config_data(CONFIG_DATA_MODE_OFFSET,
+                                        CONFIG_DATA_MODE_LEN,
+                                        &stackMode);
+    }
+
+    ret = aci_gatt_init();
+    if(ret != BLE_STATUS_SUCCESS){
+        PRINTF("GATT_Init failed.\n");
+    }
+    if (bnrg_expansion_board == IDB05A1) {
+        ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1,
+                                   0,
+                                   0x18,
+                                   &service_handle,
+                                   &dev_name_char_handle,
+                                   &appearance_char_handle);
+    } else {
+        // IDB04A1 is configured as peripheral by default
+        ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle);
+    }
+
+    // read the default static address and inject it into the GAP object
+    {
+        Gap::Address_t BLE_address_BE = { 0 };
+        uint8_t data_len_out;
+        aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS, BDADDR_SIZE, &data_len_out, BLE_address_BE);
+        // FIXME error handling of this function
+        BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE);
+    }
+
+    if(ret != BLE_STATUS_SUCCESS){
+        PRINTF("GAP_Init failed.\n");
+    }
+
+    //FIXME: Security and passkey set by default
+    ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED,
+                                       OOB_AUTH_DATA_ABSENT,
+                                       NULL,
+                                       7,
+                                       16,
+                                       USE_FIXED_PIN_FOR_PAIRING,
+                                       123456,
+                                       BONDING);
+    if (ret != BLE_STATUS_SUCCESS) {
+        PRINTF("Auth Req set failed.\n");
+    }
+
+    aci_hal_set_tx_power_level(1,4);
+
+    g_gap_service_handle = service_handle;
+    g_appearance_char_handle = appearance_char_handle;
+    g_device_name_char_handle = dev_name_char_handle;
+    //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API
+    /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0,
+                            strlen(name), (tHalUint8 *)name);*/
+
+    signalEventsToProcess();
+    // update the peripheral preferred conenction parameters handle
+    // This value is hardcoded at the moment.
+    g_preferred_connection_parameters_char_handle = 10;
+
+    return;
+}
+
+/**************************************************************************/
+/*!
+    @brief  mbedOS
+
+    @param[in]  void
+
+    @returns
+*/
+/**************************************************************************/
+int btle_handler_pending = 0;
+
+void btle_handler(void)
+{
+    btle_handler_pending = 0;
+    BlueNRGGap::getInstance().Process();
+    HCI_HandleSPI();
+    HCI_Process();
+}
+
+/* set BLE Version string */
+void setVersionString(uint8_t hwVersion, uint16_t fwVersion)
+{
+    if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) {
+        snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u",
+                                                        hwVersion>>4, (hwVersion&0x0F),
+                                                        fwVersion>>8, (fwVersion&0x00F0)>>4);
+    } else {
+        snprintf(versionString, sizeof(versionString), "ST (unknown spec)");
+    }
+}
+
+/* get BLE Version string */
+const char* getVersionString(void)
+{
+    return versionString;
+}
+
+tBleStatus btleStartRadioScan(uint8_t scan_type,
+                              uint16_t scan_interval,
+                              uint16_t scan_window,
+                              uint8_t own_address_type)
+{
+  tBleStatus ret;
+
+  // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED
+  if(bnrg_expansion_board == IDB05A1) {
+      PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window);
+      PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type);
+      ret = aci_gap_start_observation_procedure(scan_interval,
+                                                scan_window,
+                                                scan_type,
+                                                own_address_type,
+                                                0); // 1 to filter duplicates
+  } else {
+      ret = BLE_STATUS_INVALID_CID;
+  }
+
+  return ret;
+
+}
+
+/*!
+    @brief  Not Used
+
+    @param[in]  void
+
+    @returns
+*/
+void SPI_Poll(void)
+{
+    //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN);
+    return;
+}
+
+void Attribute_Modified_CB(evt_blue_aci *blue_evt)
+{
+    uint16_t conn_handle;
+    uint16_t attr_handle;
+    uint8_t data_length;
+    uint8_t *att_data;
+    uint8_t offset;
+
+    if (bnrg_expansion_board == IDB05A1) {
+        evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data;
+        conn_handle = evt->conn_handle;
+        attr_handle = evt->attr_handle;
+        data_length = evt->data_length;
+        att_data = evt->att_data;
+        offset = evt->offset;
+    } else {
+        evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data;
+        conn_handle = evt->conn_handle;
+        attr_handle = evt->attr_handle;
+        data_length = evt->data_length;
+        att_data = evt->att_data;
+        offset = 0;
+    }
+
+    //Extract the GattCharacteristic from p_characteristics[] and find the properties mask
+    GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle);
+    if(p_char!=NULL) {
+        GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
+        BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE;
+        PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]);
+        PRINTF("getProperties 0x%x\n\r",p_char->getProperties());
+
+        if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) {
+            currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE;
+        }
+
+        if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) {
+            currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE;
+        }
+        PRINTF("currentHandle %d\n\r", currentHandle);
+        if((p_char->getProperties() &
+            (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) &&
+            currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) {
+
+            GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1;
+
+            PRINTF("*****NOTIFICATION CASE\n\r");
+            //Now Check if data written in Enable or Disable
+            if((uint16_t)att_data[0]==1) {
+                //PRINTF("Notify ENABLED\n\r");
+                BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle);
+            } else {
+                //PRINTF("Notify DISABLED\n\r");
+                BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle);
+            }
+            return;
+        }
+
+        //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event
+        if((p_char->getProperties() &
+            (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) &&
+            currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) {
+
+            PRINTF("*****WRITE CASE\n\r");
+
+            GattWriteCallbackParams writeParams;
+            writeParams.connHandle = conn_handle;
+            writeParams.handle = p_char->getValueAttribute().getHandle();
+            writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG?
+            writeParams.len = data_length;
+            writeParams.data = att_data;
+            writeParams.offset = offset;
+
+            //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle);
+            //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data
+            if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) {
+                BlueNRGGattServer::getInstance().write(
+                    p_char->getValueAttribute().getHandle(),
+                    (uint8_t*)att_data,
+                    data_length,
+                    false
+                );
+            }
+
+            BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams);
+        } else {
+            PRINTF("*****WRITE DESCRIPTOR CASE\n\r");
+
+            GattWriteCallbackParams writeParams;
+            writeParams.connHandle = conn_handle;
+            writeParams.handle = attr_handle;
+            writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG?
+            writeParams.len = data_length;
+            writeParams.data = att_data;
+            writeParams.offset = offset;
+
+            BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams);
+        }
+    }
+
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    /**************************************************************************/
+    /*!
+    @brief      Handle HCI Stack Event
+
+    @param[in]  pckt
+                Event Packet sent by the stack to be decoded
+
+    @returns
+    */
+    /**************************************************************************/
+    extern void HCI_Event_CB(void *pckt) {
+        hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt;
+        hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data;
+
+        if(hci_pckt->type != HCI_EVENT_PKT)
+          return;
+
+        switch(event_pckt->evt){
+
+        case EVT_DISCONN_COMPLETE:
+            {
+                PRINTF("EVT_DISCONN_COMPLETE\n");
+
+                evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data;
+                BlueNRGGattClient::getInstance().removeGattConnectionClient(evt->handle, evt->reason);
+                BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason);
+            }
+            break;
+
+        case EVT_LE_META_EVENT:
+            {
+                PRINTF("EVT_LE_META_EVENT\n");
+
+                evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data;
+
+                switch(evt->subevent){
+
+                case EVT_LE_CONN_COMPLETE:
+                    {
+                        PRINTF("EVT_LE_CONN_COMPLETE\n");
+                        Gap::Address_t ownAddr;
+                        Gap::AddressType_t ownAddrType;
+                        BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr);
+
+                        Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC;
+                        Gap::Role_t role;
+
+                        evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data;
+
+                        BlueNRGGap::getInstance().setConnectionHandle(cc->handle);
+                        BlueNRGGap::ConnectionParams_t connectionParams = {
+                            /* minConnectionInterval = */ cc->interval,
+                            /* maxConnectionInterval = */ cc->interval,
+                            /* slaveLatency = */ cc->latency,
+                            /* connectionSupervisionTimeout = */ cc->supervision_timeout
+                        };
+
+                        BlueNRGGap::getInstance().setConnectionInterval(cc->interval);
+
+                        switch (cc->peer_bdaddr_type) {
+                            case PUBLIC_ADDR:
+                                peerAddrType = BLEProtocol::AddressType::PUBLIC;
+                                break;
+                            case STATIC_RANDOM_ADDR:
+                                peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC;
+                                break;
+                            case RESOLVABLE_PRIVATE_ADDR:
+                                peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE;
+                                break;
+                            case NON_RESOLVABLE_PRIVATE_ADDR:
+                                peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE;
+                                break;
+                        }
+                        //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role);
+                        switch (cc->role) {
+			                case 0: //master
+                                role = Gap::CENTRAL;
+                                break;
+			                case 1:
+                                role = Gap::PERIPHERAL;
+                                break;
+			                default:
+                                role = Gap::PERIPHERAL;
+				            break;
+                        }
+                        BlueNRGGattClient::getInstance().createGattConnectionClient(cc->handle);
+
+                        BlueNRGGap::getInstance().setGapRole(role);
+
+                        BlueNRGGap::getInstance().processConnectionEvent(cc->handle,
+                                                                         role,
+                                                                         peerAddrType,
+                                                                         cc->peer_bdaddr,
+                                                                         ownAddrType,
+                                                                         ownAddr,
+                                                                         &connectionParams);
+                    }
+                    break;
+
+        case EVT_LE_ADVERTISING_REPORT:
+          PRINTF("EVT_LE_ADVERTISING_REPORT\n\r");
+          /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */
+          // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT)
+          // Formally the structure related to both events are identical except that for the ADV REPORT
+          // there is one more field (number of reports) which is not forwarded to upper layer.
+          // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT.
+          le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1);
+          PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type);
+
+          BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND,
+                                                 pr->evt_type,
+                                                 pr->bdaddr_type,
+                                                 pr->bdaddr,
+                                                 &pr->data_length,
+                                                 &pr->data_RSSI[0],
+                                                 &pr->data_RSSI[pr->data_length]);
+                    break;
+                }
+            }
+            break;
+
+        case EVT_VENDOR:
+            {
+                evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data;
+                //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode);
+
+                switch(blue_evt->ecode){
+
+                case EVT_BLUE_GATT_WRITE_PERMIT_REQ:
+                    {
+                        PRINTF("EVT_BLUE_GATT_WRITE_PERMIT_REQ\r\n");
+                        evt_gatt_write_permit_req* write_req = (evt_gatt_write_permit_req*)blue_evt->data;
+
+                        // ask the local server if the write operation is authorized
+                        uint8_t err_code = BlueNRGGattServer::getInstance().Write_Request_CB(
+                            write_req->conn_handle,
+                            write_req->attr_handle,
+                            write_req->data_length,
+                            write_req->data
+                        );
+                        uint8_t write_status = err_code == 0 ? 0 : 1;
+
+                        // reply to the shield
+                        aci_gatt_write_response(
+                            write_req->conn_handle,
+                            write_req->attr_handle,
+                            write_status,
+                            err_code,
+                            write_req->data_length,
+                            write_req->data
+                        );
+                    }
+                    break;
+
+                case EVT_BLUE_GATT_READ_PERMIT_REQ:
+                    {
+                        PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r");
+                        evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data;
+                        PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle);
+                        BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle);
+                    }
+                    break;
+
+                case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED:
+                    {
+                        PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r");
+                        /* this callback is invoked when a GATT attribute is modified
+                            extract callback data and pass to suitable handler function */
+                        Attribute_Modified_CB(blue_evt);
+                    }
+                    break;
+
+                    //Any cases for Data Sent Notifications?
+                case EVT_BLUE_GATT_NOTIFICATION:
+                    {
+                        PRINTF("EVT_BLUE_GATT_NOTIFICATION");
+
+                        evt_gatt_attr_notification *notification = (evt_gatt_attr_notification*)blue_evt->data;
+
+                        GattHVXCallbackParams params;
+                        params.connHandle = notification->conn_handle;
+                        params.handle     = notification->attr_handle;
+                        params.type       = BLE_HVX_NOTIFICATION;
+                        params.len        = notification->event_data_length - 2;
+                        params.data       = notification->attr_value;
+
+                        BlueNRGGattClient::getInstance().processHVXEvent(&params);
+                    }
+                    break;
+
+                case EVT_BLUE_GATT_INDICATION:
+                    {
+                        PRINTF("EVT_BLUE_GATT_INDICATION");
+                        evt_gatt_indication *indication = (evt_gatt_indication*)blue_evt->data;
+
+                        GattHVXCallbackParams params;
+                        params.connHandle = indication->conn_handle;
+                        params.handle     = indication->attr_handle;
+                        params.type       = BLE_HVX_INDICATION;
+                        params.len        = indication->event_data_length - 2;
+                        params.data       = indication->attr_value;
+
+                        BlueNRGGattClient::getInstance().processHVXEvent(&params);
+                        aci_gatt_confirm_indication(params.connHandle);
+                    }
+                    break;
+
+        case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP:
+          {
+            PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r");
+            evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data;
+            BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle,
+                                                               pr->event_data_length,
+                                                               pr->attribute_data_length,
+                                                               pr->attribute_data_list);
+          }
+          break;
+        case EVT_BLUE_ATT_READ_BY_TYPE_RESP:
+          {
+            PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r");
+            evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data;
+            BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle,
+                                                            pr->event_data_length,
+                                                            pr->handle_value_pair_length,
+                                                            pr->handle_value_pair);
+          }
+          break;
+        case EVT_BLUE_ATT_READ_RESP:
+          {
+            PRINTF("EVT_BLUE_ATT_READ_RESP\n\r");
+            evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data;
+            BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle,
+                                                        pr->event_data_length,
+                                                        pr->attribute_value);
+          }
+          break;
+        case EVT_BLUE_ATT_EXEC_WRITE_RESP:
+          {
+            PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r");
+            evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data;
+            BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle,
+                                                             pr->event_data_length);
+          }
+          break;
+        case EVT_BLUE_ATT_PREPARE_WRITE_RESP:
+          {
+            PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r");
+            evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data;
+            BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle,
+                                                                pr->event_data_length,
+                                                                pr->attribute_handle,
+                                                                pr->offset,
+                                                                pr->part_attr_value);
+          }
+          break;
+        case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP:
+          {
+            PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r");
+            evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data;
+            BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle,
+                                                                 pr->event_data_length,
+                                                                 pr->attr_handle,
+                                                                 pr->attr_value);
+          }
+          break;
+        case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP:
+          {
+            PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r");
+            evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data;
+            BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle,
+                                                              pr->event_data_length,
+                                                              pr->handles_info_list);
+          }
+          break;
+        case EVT_BLUE_ATT_FIND_INFORMATION_RESP:
+          {
+            PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r");
+            evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data;
+            BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle,
+                                                                 pr->event_data_length,
+                                                                 pr->format,
+                                                                 pr->handle_uuid_pair);
+          }
+          break;
+        case EVT_BLUE_GATT_PROCEDURE_COMPLETE:
+          {
+            evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data;
+            PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code);
+            BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code);
+          }
+          break;
+
+        case EVT_BLUE_L2CAP_CONN_UPD_REQ:
+          {
+            PRINTF("EVT_BLUE_L2CAP_CONN_UPD_REQ\r\n");
+            evt_l2cap_conn_upd_req *evt = (evt_l2cap_conn_upd_req*)blue_evt->data;
+            if(bnrg_expansion_board == IDB05A1) {
+              // we assume the application accepts the request from the slave
+              aci_l2cap_connection_parameter_update_response_IDB05A1(evt->conn_handle,
+                                                                     evt->interval_min,
+                                                                     evt->interval_max,
+                                                                     evt->slave_latency,
+                                                                     evt->timeout_mult,
+                                                                     CONN_L1, CONN_L2,
+                                                                     evt->identifier,
+                                                                     0x0000);
+            }
+          }
+          break;
+
+        case EVT_BLUE_L2CAP_CONN_UPD_RESP:
+          {
+            evt_l2cap_conn_upd_resp *evt = (evt_l2cap_conn_upd_resp*)blue_evt->data;
+            PRINTF("EVT_BLUE_L2CAP_CONN_UPD_RESP code=0x%x, result=0x%x\r\n", evt->code, evt->result);
+          }
+          break;
+
+        case EVT_LE_CONN_UPDATE_COMPLETE:
+          {
+            evt_le_connection_update_complete *evt = (evt_le_connection_update_complete*)blue_evt->data;
+            PRINTF("EVT_LE_CONN_UPDATE_COMPLETE status=0x%x\r\n", evt->status);
+          }
+          break;
+
+        case EVT_BLUE_GAP_DEVICE_FOUND:
+          {
+            evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data;
+            PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type);
+
+            BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND,
+                                                   pr->evt_type,
+                                                   pr->bdaddr_type,
+                                                   pr->bdaddr,
+                                                   &pr->data_length,
+                                                   &pr->data_RSSI[0],
+                                                   &pr->data_RSSI[pr->data_length]);
+          }
+          break;
+
+        case EVT_BLUE_GAP_PROCEDURE_COMPLETE:
+          {
+            evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data;
+            //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code);
+
+            switch(pr->procedure_code) {
+            case GAP_OBSERVATION_PROC_IDB05A1:
+
+              BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL);
+              break;
+            }
+          }
+                    break;
+                }
+            }
+            break;
+        }
+        return ;
+    }
+
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,217 @@
+/**
+  ******************************************************************************
+  * @file    stm32_bluenrg_ble.cpp
+  * @author  CL
+  * @version V1.0.0
+  * @date    15-June-2015
+  * @brief   
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+  
+/* Includes ------------------------------------------------------------------*/
+#include "BlueNRGGap.h"
+#include "BlueNRGDevice.h"
+#include "btle.h"
+
+// FIXME: find a better way to get the instance of the BlueNRG device
+extern BlueNRGDevice bluenrgDeviceInstance;
+
+
+////////////////////////////////////////
+// Start of C function wrappers
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stm32_bluenrg_ble.h"
+#include "ble_debug.h"
+
+	
+void BlueNRG_RST(void)
+{
+    bluenrgDeviceInstance.reset();
+}
+
+uint8_t BlueNRG_DataPresent(void)
+{
+    return (bluenrgDeviceInstance.dataPresent());
+}
+ 
+
+/**
+ * @brief  This function is a utility to print the log time
+*          in the format HH:MM:SS:MSS (DK GUI time format)
+ * @param  None
+ * @retval None
+ */
+void print_csv_time(void){
+#ifdef PRINT_CSV_FORMAT
+  uint32_t ms = 0;//ms_counter;
+  PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000);
+#endif
+}
+
+/**
+ * @brief  Writes data to a serial interface.
+ * @param  data1   :  1st buffer
+ * @param  data2   :  2nd buffer
+ * @param  n_bytes1: number of bytes in 1st buffer
+ * @param  n_bytes2: number of bytes in 2nd buffer
+ * @retval None
+ */
+void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1,
+                      int32_t n_bytes2)
+{
+  struct timer t;
+
+  Timer_Set(&t, CLOCK_SECOND/10);
+
+#ifdef PRINT_CSV_FORMAT
+  print_csv_time();
+  for (int i=0; i<n_bytes1; i++) {
+    PRINT_CSV(" %02x", ((uint8_t *)data1)[i]);
+	 }
+  for (int i=0; i<n_bytes2; i++) {
+    PRINT_CSV(" %02x", ((uint8_t *)data2)[i]);
+	 }
+  PRINT_CSV("\n");
+#endif
+
+  while(1){
+    if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break;
+    if(Timer_Expired(&t)){
+      break;
+    }
+  }
+}
+
+
+/**
+ * @brief  Activate internal bootloader using pin.
+ * @param  None
+ * @retval None
+ */
+void BlueNRG_HW_Bootloader(void)
+{
+	// Reset BlueNRG SPI interface
+    BlueNRG_RST();
+    
+    // Send an ACI command to reboot BlueNRG in bootloader mode
+	// The safest way to get in bootloader mode is keeping high
+	// the interrupt pin during reset, but this would require many
+	// changes to the current mbed driver
+	aci_updater_start();
+}
+
+/**
+ * @brief  Reads from BlueNRG SPI buffer and store data into local buffer.
+ * @param  buffer   : Buffer where data from SPI are stored
+ * @param  buff_size: Buffer size
+ * @retval int32_t  : Number of read bytes
+ */
+int32_t BlueNRG_SPI_Read_All(uint8_t *buffer,
+                             uint8_t buff_size)
+{
+    int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size);
+
+    return ret;
+}
+
+/**
+ * @brief  Writes data from local buffer to SPI.
+ * @param  data1    : First data buffer to be written
+ * @param  data2    : Second data buffer to be written
+ * @param  Nb_bytes1: Size of first data buffer to be written
+ * @param  Nb_bytes2: Size of second data buffer to be written
+ * @retval Number of read bytes
+ */
+int32_t BlueNRG_SPI_Write(uint8_t* data1,
+                          uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2)
+{  
+    int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2);
+
+		return ret;
+}
+     
+/**
+ * @brief  Enable SPI IRQ.
+ * @param  None
+ * @retval None
+ */
+void Enable_SPI_IRQ(void)
+{
+    bluenrgDeviceInstance.enable_irq();
+}
+
+void signalEventsToProcess(void)  {
+    if(btle_handler_pending == 0) {
+        btle_handler_pending = 1;
+        bluenrgDeviceInstance.signalEventsToProcess(BLE::DEFAULT_INSTANCE);
+    }
+}
+
+/**
+ * @brief  Disable SPI IRQ.
+ * @param  None
+ * @retval None
+ */
+void Disable_SPI_IRQ(void)
+{ 
+    bluenrgDeviceInstance.disable_irq();
+}
+
+/**
+ * @brief  Clear Pending SPI IRQ.
+ * @param  None
+ * @retval None
+ */
+void Clear_SPI_IRQ(void)
+{
+}
+
+/**
+ * @brief  Clear EXTI (External Interrupt) line for SPI IRQ.
+ * @param  None
+ * @retval None
+ */
+void Clear_SPI_EXTI_Flag(void)
+{  
+}
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+// End of C function wrappers
+////////////////////////////////////////
+ 
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,118 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <ble_payload.h>   
+
+Payload::Payload() {
+    stringLength = 0;
+    payloadUnitCount = 0;
+    payload = NULL;
+}
+
+Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) {
+    // initialize private data members
+    stringLength = string_ength;
+    payloadUnitCount = 0;
+    payload = NULL;
+    
+    int index = 0;
+    while( index!=stringLength) {
+        int len=tokenString[index];
+        index=index+1+len;
+        payloadUnitCount++;               
+    }
+    
+    UnitPayload *obj = new UnitPayload[payloadUnitCount];
+    int i=0;
+    int c=0;
+    int j,k;
+
+    while(i<payloadUnitCount)
+    {   
+        obj[i].length=tokenString[c];
+        obj[i].id=tokenString[c+1];
+
+        obj[i].data = new uint8_t[obj[i].length];
+        for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++)
+        {
+            obj[i].data[k]=tokenString[j];
+            
+        }           
+        
+        c=c+obj[i].length+1;
+        i++;
+
+    }
+    payload = obj;
+}
+
+uint8_t Payload::getPayloadUnitCount() {
+    return payloadUnitCount;
+}
+
+uint8_t Payload::getIDAtIndex(int index) {
+    return payload[index].get_id();
+}
+
+uint8_t Payload::getLengthAtIndex(int index) {
+    return payload[index].get_length();
+}
+
+uint8_t* Payload::getDataAtIndex(int index) {
+    return payload[index].get_data();
+}
+
+int8_t Payload::getInt8AtIndex(int index) {
+    uint8_t* str = payload[index].get_data();
+    int8_t value = (int8_t)str[0];
+    return value;
+}
+
+uint16_t Payload::getUint16AtIndex(int index) {
+    uint16_t* str = (uint16_t*)payload[index].get_data();
+    uint16_t value = str[0];
+    return value;    
+}
+
+uint8_t* Payload::getSerializedAdDataAtIndex(int index) {
+    uint8_t length = payload[index].get_length();
+    uint8_t* data = payload[index].get_data();
+    uint8_t id = payload[index].get_id();
+    uint8_t *serializedAdData = new uint8_t[length];
+    
+    serializedAdData[0] = id;
+    for(int i=0; i<length-1; i++) {
+        serializedAdData[i+1] = data[i];
+    }
+    return serializedAdData;
+}
+
+Payload::~Payload() {
+    int i = 0;
+
+    if(payload) {
+        while(i<payloadUnitCount) {
+            if(payload->data) {
+                delete[] payload->data;
+                payload->data = NULL;
+            }
+        }
+        delete[] payload;
+        payload = NULL;
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,93 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "ble_utils.h"
+
+/**************************************************************************/
+/*!
+    @brief  sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power
+
+*/
+/**************************************************************************/
+tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) {
+    tBleStatus ret = BLE_STATUS_SUCCESS;
+
+    if(dBMLevel==-18) {
+        EN_HIGH_POWER = 0;
+        PA_LEVEL = 0;         
+    }
+    else if(dBMLevel==-15) {
+        EN_HIGH_POWER = 0;
+        PA_LEVEL = 1;
+    }
+    else if(dBMLevel==-14) {
+        EN_HIGH_POWER = 1;
+        PA_LEVEL = 0;
+    }
+    else if(dBMLevel==-12) {
+        EN_HIGH_POWER = 0;
+        PA_LEVEL = 2;
+    }
+    else if(dBMLevel==-11) {
+        EN_HIGH_POWER = 1;
+        PA_LEVEL = 1;
+    }
+    else if(dBMLevel==-9) {
+        EN_HIGH_POWER = 0;
+        PA_LEVEL = 3;
+    }
+    else if(dBMLevel==-8) {
+        EN_HIGH_POWER = 1;
+        PA_LEVEL = 2;
+    }
+    else if(dBMLevel==-6) {
+        EN_HIGH_POWER = 0;
+        PA_LEVEL = 4;
+    }
+    else if(dBMLevel==-5) {
+        EN_HIGH_POWER = 1;
+        PA_LEVEL = 3;
+    }
+    else if(dBMLevel==-2) {
+        EN_HIGH_POWER = 1;
+        PA_LEVEL = 4;
+    }
+    else if(dBMLevel==0) {
+        EN_HIGH_POWER = 0;
+        PA_LEVEL = 6;
+    }
+    else if(dBMLevel==2) {
+        EN_HIGH_POWER = 1;
+        PA_LEVEL = 5;
+    }
+    else if(dBMLevel==4) {
+        EN_HIGH_POWER = 1;
+        PA_LEVEL = 6;
+    }
+    else if(dBMLevel==5) {
+        EN_HIGH_POWER = 0;
+        PA_LEVEL = 7;
+    }
+    else if(dBMLevel==8) {
+        EN_HIGH_POWER = 1;
+        PA_LEVEL = 7;
+    }
+    else {
+        ret = ERR_INVALID_HCI_CMD_PARAMS;
+    }
+
+    return ret;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/main.cpp	Sat Apr 21 08:25:59 2018 +0000
@@ -0,0 +1,129 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2014 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <events/mbed_events.h>
+#include <mbed.h>
+#include "ble/BLE.h"
+#include "ble/Gap.h"
+#include "ble/services/BatteryService.h"
+
+DigitalOut led1(LED1, 1);
+
+const static char     DEVICE_NAME[] = "BATTERY";
+static const uint16_t uuid16_list[] = {GattService::UUID_BATTERY_SERVICE};
+
+static uint8_t batteryLevel = 50;
+static BatteryService* batteryServicePtr;
+
+static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE);
+
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
+{
+    BLE::Instance().gap().startAdvertising();
+}
+
+void updateSensorValue() {
+    batteryLevel++;
+    if (batteryLevel > 100) {
+        batteryLevel = 20;
+    }
+
+    batteryServicePtr->updateBatteryLevel(batteryLevel);
+}
+
+void blinkCallback(void)
+{
+    led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
+
+    BLE &ble = BLE::Instance();
+    if (ble.gap().getState().connected) {
+        eventQueue.call(updateSensorValue);
+    }
+}
+
+/**
+ * This function is called when the ble initialization process has failled
+ */
+void onBleInitError(BLE &ble, ble_error_t error)
+{
+    /* Initialization error handling should go here */
+}
+
+void printMacAddress()
+{
+    /* Print out device MAC address to the console*/
+    Gap::AddressType_t addr_type;
+    Gap::Address_t address;
+    BLE::Instance().gap().getAddress(&addr_type, address);
+    printf("DEVICE MAC ADDRESS: ");
+    for (int i = 5; i >= 1; i--){
+        printf("%02x:", address[i]);
+    }
+    printf("%02x\r\n", address[0]);
+}
+
+/**
+ * Callback triggered when the ble initialization process has finished
+ */
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
+{
+    BLE&        ble   = params->ble;
+    ble_error_t error = params->error;
+
+    if (error != BLE_ERROR_NONE) {
+        /* In case of error, forward the error handling to onBleInitError */
+        onBleInitError(ble, error);
+        return;
+    }
+
+    /* Ensure that it is the default instance of BLE */
+    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
+        return;
+    }
+
+    ble.gap().onDisconnection(disconnectionCallback);
+
+    /* Setup primary service */
+    batteryServicePtr = new BatteryService(ble, batteryLevel);
+
+    /* Setup advertising */
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *) uuid16_list, sizeof(uuid16_list));
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *) DEVICE_NAME, sizeof(DEVICE_NAME));
+    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble.gap().setAdvertisingInterval(1000); /* 1000ms */
+    ble.gap().startAdvertising();
+
+    printMacAddress();
+}
+
+void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
+    BLE &ble = BLE::Instance();
+    eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
+}
+
+int main()
+{
+    eventQueue.call_every(500, blinkCallback);
+
+    BLE &ble = BLE::Instance();
+    ble.onEventsToProcess(scheduleBleEventsProcessing);
+    ble.init(bleInitComplete);
+
+    eventQueue.dispatch_forever();
+
+    return 0;
+}