Antonio Vilei / X_NUCLEO_IDB0XA1

Fork of X_NUCLEO_IDB0XA1 by ST Expansion SW Team

Files at this revision

API Documentation at this revision

Comitter:
Andrea Palmieri
Date:
Mon May 16 17:22:03 2016 +0200
Parent:
218:25368f053411
Child:
220:6eb53072d82b
Commit message:
Fix issues and add features

- Fix handles management
- Fix UUIDs management
- Implement API to read random address
- Fix clearing/setting of ADV payload
- Fix scanning behaviour
- Fix scanning while a connection is ongoing
- Implement Char Descriptor discovery
- Implement scanning/advertising filter policy (White List partial management)
- Update underlying BlueNRG stack
- Cosmetics

Signed-off-by: Andrea Palmieri <andrea.palmieri@st.com>

Changed in this revision

source/BlueNRGDevice.cpp Show annotated file Show diff for this revision Revisions of this file
source/BlueNRGDiscoveredCharacteristic.cpp Show annotated file Show diff for this revision Revisions of this file
source/BlueNRGGap.cpp Show annotated file Show diff for this revision Revisions of this file
source/BlueNRGGattClient.cpp Show annotated file Show diff for this revision Revisions of this file
source/BlueNRGGattServer.cpp Show annotated file Show diff for this revision Revisions of this file
source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Show annotated file Show diff for this revision Revisions of this file
source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Show annotated file Show diff for this revision Revisions of this file
source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Show annotated file Show diff for this revision Revisions of this file
source/bluenrg-hci/hci/hci.c Show annotated file Show diff for this revision Revisions of this file
source/bluenrg-hci/hci/hci_dma_lp.c Show diff for this revision Revisions of this file
source/platform/btle.cpp Show annotated file Show diff for this revision Revisions of this file
source/platform/stm32_bluenrg_ble_dma_lp.c Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/BlueNRGDevice.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/BlueNRGDiscoveredCharacteristic.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/BlueNRGGap.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/BlueNRGGattClient.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/BlueNRGGattServer.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/bluenrg-hci/bluenrg_aci_const.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap_aci.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_aci.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/bluenrg-hci/bluenrg_hal_aci.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/bluenrg-hci/bluenrg_l2cap_aci.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/bluenrg-hci/hci.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/bluenrg-hci/hci_const.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/platform/stm32_bluenrg_ble_dma_lp.h Show diff for this revision Revisions of this file
--- a/source/BlueNRGDevice.cpp	Tue Apr 26 14:44:54 2016 +0200
+++ b/source/BlueNRGDevice.cpp	Mon May 16 17:22:03 2016 +0200
@@ -159,9 +159,9 @@
     @brief  Resets the BLE HW, removing any existing services and
             characteristics
     @param[in] void
-    @returns    ble_error_t
+    @returns    void
 */
-ble_error_t BlueNRGDevice::reset(void)
+void BlueNRGDevice::reset(void)
 {
     wait_us(500);
 
@@ -173,10 +173,7 @@
 
     /* Wait for the radio to come back up */
     wait_us(500);
-    
-    isInitialized = false;
 
-    return BLE_ERROR_NONE;
 }
 
 /*!
@@ -260,7 +257,34 @@
         return BLE_ERROR_INITIALIZATION_INCOMPLETE;
     }
 
-    return reset();
+    /* 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;
+
+    return BLE_ERROR_NONE;
+
 }
 																							
 /**
--- a/source/BlueNRGDiscoveredCharacteristic.cpp	Tue Apr 26 14:44:54 2016 +0200
+++ b/source/BlueNRGDiscoveredCharacteristic.cpp	Mon May 16 17:22:03 2016 +0200
@@ -1,60 +1,64 @@
-/* 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)
-{
-    gattc       = gattcIn;
-    connHandle  = connectionHandleIn;
-    declHandle  = declHandleIn;
-    valueHandle = valueHandleIn;
-
-    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)
-{
-    gattc       = gattcIn;
-    connHandle  = connectionHandleIn;
-    uuid        = uuidIn;
-    declHandle  = declHandleIn;
-    valueHandle = valueHandleIn;
-
-    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();
-}
+/* 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();
+}
--- a/source/BlueNRGGap.cpp	Tue Apr 26 14:44:54 2016 +0200
+++ b/source/BlueNRGGap.cpp	Mon May 16 17:22:03 2016 +0200
@@ -31,9 +31,7 @@
   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
   *
   * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
-  */ 
-
-// ANDREA: Changed some types (e.g., tHalUint8 --> uint8_t)
+  */
 
 /** @defgroup BlueNRGGap
  *  @brief BlueNRG BLE_API GAP Adaptation
@@ -109,8 +107,12 @@
     }
 
     /* Make sure we have a payload! */
-    if (advData.getPayloadLen() <= 0) {
-        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    if (advData.getPayloadLen() == 0) {
+        PRINTF("advData.getPayloadLen() == 0\n\r");
+        //return BLE_ERROR_PARAM_OUT_OF_RANGE;
+        local_name_length = 0;
+        servUuidlength = 0;
+        AdvLen = 0;
     } else { 
         PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen());        
         for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) {                  
@@ -181,8 +183,8 @@
                 PRINTF("Advertising type: COMPLETE_LOCAL_NAME\n\r");
                 loadPtr.getUnitAtIndex(index).printDataAsString();
                 local_name_length = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;
-                // The total lenght should include the Data Type Value
-                if(local_name_length>LOCAL_NAME_MAX_SIZE-1) {
+                // The total length should include the Data Type Value
+                if(local_name_length>ADV_DATA_MAX_SIZE-1) {
                     return BLE_ERROR_INVALID_PARAM;
                 }
                 local_name[0] = (uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()); //Data Type Value
@@ -222,9 +224,11 @@
                 if(buffSize>ADV_DATA_MAX_SIZE-2) {
                     return BLE_ERROR_PARAM_OUT_OF_RANGE;
                 }
+#ifdef DEBUG
                 for(int i=0; i<buffSize+1; i++) {
                     PRINTF("Advertising type: SERVICE_DATA loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r", i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
                 }
+#endif
                 AdvLen = buffSize+2; // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Service Data Type Value byte
                 AdvData[0] = buffSize+1; // the fisrt byte is the data buffer size (type+data)
                 AdvData[1] = AD_TYPE_SERVICE_DATA;
@@ -266,10 +270,12 @@
                 if(buffSize>ADV_DATA_MAX_SIZE-2) {
                     return BLE_ERROR_PARAM_OUT_OF_RANGE;
                 }
+#ifdef DBEUG
                 for(int i=0; i<buffSize+1; i++) {
                     PRINTF("Advertising type: MANUFACTURER_SPECIFIC_DATA loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r",
 				i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
                 }
+#endif
                 AdvLen = buffSize+2; // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Manufacturer Specific Data Type Value byte
                 AdvData[0] = buffSize+1; // the fisrt byte is the data buffer size (type+data)
                 AdvData[1] = AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
@@ -310,8 +316,7 @@
 
 /*
  * ADV timeout callback
- */   
-// ANDREA: mbedOS
+ */
 #ifdef AST_FOR_MBED_OS
 static void advTimeoutCB(void)
 {
@@ -402,6 +407,35 @@
         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) {
@@ -424,13 +458,14 @@
     }
 
     advtInterval = params.getIntervalInADVUnits();
-    printf("advtInterval=%ld advType=%d\n\r", advtInterval, params.getAdvertisingType());
+    PRINTF("advtInterval=%ld advType=%d\n\r", advtInterval, params.getAdvertisingType());
 
+    /* Setting discoverable mode */
     ret = aci_gap_set_discoverable(params.getAdvertisingType(), // AdvType
                                    advtInterval,                // AdvIntervMin
                                    advtInterval,                // AdvIntervMax
                                    addr_type,                   // OwnAddrType
-                                   NO_WHITE_LIST_USE,           // AdvFilterPolicy
+                                   advFilterPolicy,             // AdvFilterPolicy
                                    local_name_length,           // LocalNameLen
                                    (const char*)local_name,     // LocalName
                                    servUuidlength,              // ServiceUUIDLen
@@ -439,9 +474,9 @@
                                    0);                          // SlaveConnIntervMax
 
     
-    printf("!!!setting discoverable (servUuidlength=0x%x)\n\r", servUuidlength);
+    PRINTF("!!!setting discoverable (servUuidlength=0x%x)\n\r", servUuidlength);
     if(BLE_STATUS_SUCCESS!=ret) {
-       printf("error occurred while setting discoverable (ret=0x%x)\n\r", ret);
+       PRINTF("error occurred while setting discoverable (ret=0x%x)\n\r", ret);
        switch (ret) {
          case BLE_STATUS_INVALID_PARAMS:
            return BLE_ERROR_INVALID_PARAM;
@@ -512,11 +547,10 @@
     AdvToFlag = false;
     if(params.getTimeout() != 0) {
         PRINTF("!!! attaching to!!!\n");
-        // ANDREA: mbedOS
 #ifdef AST_FOR_MBED_OS
-        minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout()));
+        minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000));
 #else
-        advTimeout.attach(advTimeoutCB, params.getTimeout());
+        advTimeout.attach(advTimeoutCB, params.getTimeout() * 1000);
 #endif
     }
     
@@ -542,7 +576,7 @@
 ble_error_t BlueNRGGap::stopAdvertising(void)
 {
     tBleStatus ret;
-    
+
     if(state.advertising == 1) {
         //Set non-discoverable to stop advertising
         ret = aci_gap_set_non_discoverable();
@@ -714,7 +748,6 @@
     @endcode
 */
 /**************************************************************************/
-/*
 ble_error_t BlueNRGGap::setAddress(AddressType_t type, const Address_t address)
 {
     tBleStatus ret;
@@ -730,12 +763,14 @@
         ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
                                         CONFIG_DATA_PUBADDR_LEN,
                                         address);
-        printf("setAddress (ret=0x%02X)\n\r", ret);
+        if(ret != BLE_STATUS_SUCCESS) {
+            return BLE_ERROR_UNSPECIFIED;
+        }
     }
     
     return BLE_ERROR_NONE;
 }
-*/
+
 /**************************************************************************/
 /*!
     @brief      Returns boolean if the address of the device has been set
@@ -770,11 +805,18 @@
 /**************************************************************************/
 ble_error_t BlueNRGGap::getAddress(AddressType_t *typeP, Address_t address) 
 {
+    uint8_t bdaddr[BDADDR_SIZE];
+    uint8_t data_len_out;
+
     if(typeP != NULL) {
         *typeP = addr_type;
     }
 
-    hci_read_bd_addr(bdaddr);
+    tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS_IDB05A1, BDADDR_SIZE, &data_len_out, bdaddr);
+    if(ret != BLE_STATUS_SUCCESS) {
+        return BLE_ERROR_UNSPECIFIED;
+    }
+
     if(address != NULL) {
         memcpy(address, bdaddr, BDADDR_SIZE);
     }
@@ -924,7 +966,7 @@
 {
     tBleStatus ret;
 
-    ret = aci_gatt_read_handle_value(g_device_name_char_handle+CHAR_VALUE_OFFSET,
+    ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
                                      *lengthP,
                                      (uint16_t *)lengthP,
                                      deviceName);
@@ -1008,7 +1050,7 @@
     tBleStatus ret;
     uint16_t lengthP = 2;
 
-    ret = aci_gatt_read_handle_value(g_appearance_char_handle+CHAR_VALUE_OFFSET,
+    ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
                                      lengthP,
                                      &lengthP,
                                      (uint8_t*)appearanceP);
@@ -1026,35 +1068,40 @@
   return &_scanningParams;
 }
 
-static void radioScanning(void)
-{
-  GapScanningParams* scanningParams = BlueNRGGap::getInstance().getScanningParams();
-
-  BlueNRGGap::getInstance().startRadioScan(*scanningParams);
-}
-
 static void makeConnection(void)
 {
   BlueNRGGap::getInstance().createConnection();
 }
 
-// ANDREA
 void BlueNRGGap::Discovery_CB(Reason_t reason,
                               uint8_t adv_type,
-                              uint8_t *addr_type,
+                              uint8_t addr_type,
                               uint8_t *addr,
                               uint8_t *data_length,
                               uint8_t *data,
                               uint8_t *RSSI)
 {
-  /* avoid compiler warnings about unused variables */
-  (void)addr_type;
-
   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;
@@ -1084,26 +1131,22 @@
   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. Otherwise, we restart the scanning.
+    // 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 or re-scanning procedures
+    // we need to delay the starting of connection
     uint16_t delay = 2*(_scanningParams.getInterval());
 
 #ifdef AST_FOR_MBED_OS
     if(_connecting) {
       minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay));
-    } else {
-      minar::Scheduler::postCallback(radioScanning).delay(minar::milliseconds(delay));
     }
 #else
     Clock_Wait(delay);
     if(_connecting) {
       makeConnection();
-    } else {
-      radioScanning();
     }
 #endif /* AST_FOR_MBED_OS */
 
@@ -1123,13 +1166,30 @@
   }
   */
 
-  PRINTF("Scanning...\n\r");
+  /*
+   * 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;
@@ -1139,10 +1199,10 @@
   // 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");
+      PRINTF("Observation Procedure not implemented!!!\n\r");
       return BLE_ERROR_NOT_IMPLEMENTED;
     default:
-      printf("Observation Procedure failed (0x%02X)\n\r", ret);
+      PRINTF("Observation Procedure failed (0x%02X)\n\r", ret);
       return BLE_ERROR_UNSPECIFIED;
   }
 
@@ -1150,11 +1210,12 @@
 
 ble_error_t BlueNRGGap::stopScan() {
   tBleStatus ret = BLE_STATUS_SUCCESS;
-  
+
+  PRINTF("stopScan\n\r");
   ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC);
   
   if (ret != BLE_STATUS_SUCCESS) {
-    printf("GAP Terminate Gap Procedure failed\n");
+    PRINTF("GAP Terminate Gap Procedure failed\n");
     return BLE_ERROR_UNSPECIFIED; 
   } else {
     PRINTF("Discovery Procedure Terminated\n");
@@ -1199,34 +1260,75 @@
 /**************************************************************************/
 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
+        -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 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.advertising == 1) {
+
+    if (_scanningParams.getInterval() < _advParams.getInterval()) {
+      scanInterval = _advParams.getIntervalInADVUnits();
+      scanWindow = _advParams.getIntervalInADVUnits();
+    } else {
+      scanInterval = _scanningParams.getInterval();
+      scanWindow = _scanningParams.getWindow();
+    }
+    conn_min_interval = (_advParams.getInterval()+GUARD_INT)/1.25;
+    conn_max_interval = (_advParams.getInterval()+GUARD_INT)/1.25;
+
+  } else {
+
+    scanInterval = _scanningParams.getInterval();
+    scanWindow = _scanningParams.getWindow();
+    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[msec]=%u\r\n",(unsigned)(conn_min_interval*1.25));
+  PRINTF("conn_max_interval[msec]=%u\r\n",(unsigned)(conn_max_interval*1.25));
+
+}
+
 ble_error_t BlueNRGGap::createConnection ()
 {
   tBleStatus ret;
-  GapScanningParams* scanningParams = getScanningParams();
-  
+
+  /*
+     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(scanningParams->getInterval(),
-				  scanningParams->getWindow(),
-				  PUBLIC_ADDR,
+  ret = aci_gap_create_connection(scanInterval,
+				  scanWindow,
+				  _peerAddrType,
 				  (unsigned char*)_peerAddr,
-				  PUBLIC_ADDR,
-				  CONN_P1, CONN_P2, 0,
+				  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);
+    PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret);
     return BLE_ERROR_UNSPECIFIED;
   } else {
     PRINTF("Connection started.\n");
@@ -1240,7 +1342,6 @@
                                  const GapScanningParams *scanParams)
 {
   /* avoid compiler warnings about unused variables */
-  (void)peerAddrType;
   (void)connectionParams;
   (void)scanParams;
 
@@ -1248,6 +1349,7 @@
   for(int i=0; i<BDADDR_SIZE; i++) {
     _peerAddr[i] = peerAddr[i];
   }
+  _peerAddrType = peerAddrType;
 
   _connecting = true;
 
@@ -1260,3 +1362,103 @@
   
   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)
+{
+    /* Clear all state that is from the parent, including private members */
+    if (Gap::reset() != BLE_ERROR_NONE) {
+        return BLE_ERROR_INVALID_STATE;
+    }
+
+    /* Clear derived class members */
+    m_connectionHandle = BLE_CONN_HANDLE_INVALID;
+
+    memset(deviceAppearance, 0, sizeof(deviceAppearance));
+    memset(local_name, 0, LOCAL_NAME_MAX_SIZE);
+    memset(local_name, 0, UUID_BUFFER_SIZE);
+    memset(AdvData, 0, ADV_DATA_MAX_SIZE);
+
+    /* 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;
+}
+
--- a/source/BlueNRGGattClient.cpp	Tue Apr 26 14:44:54 2016 +0200
+++ b/source/BlueNRGGattClient.cpp	Mon May 16 17:22:03 2016 +0200
@@ -1,630 +1,815 @@
-/* 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"
-#include "mbed-drivers/mbed.h"
-#include "BlueNRGGap.h"
-#include "Utils.h"
-#include "debug.h"
-
-static uint8_t props_mask[] = {
-  0x01,
-  0x02,
-  0x04,
-  0x08,
-  0x10,
-  0x20,
-  0x40,
-  0x80
-  };
-
-void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code)
-{
-  if(error_code != BLE_STATUS_SUCCESS) {
-    return;
-  }
-    
-  // Service Discovery complete
-  if(_currentState != GATT_IDLE && 
-     _currentState != GATT_DISCOVERY_TERMINATED &&
-       _currentState != GATT_WRITE_CHAR &&
-         _currentState != GATT_READ_CHAR) {
-             
-    findServiceChars(connectionHandle);
-  }
-  
-  if(_currentState == GATT_WRITE_CHAR) {
-    BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
-    _currentState = GATT_IDLE;
-  }
-}
-                                                
-void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle,
-                                          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;
-  /* avoid compiler warnings about unused variables */
-  (void)connectionHandle;
-
-  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);
-      
-      PRINTF("S UUID-");
-#ifdef DEBUG
-      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);
-    
-    if(serviceDiscoveryCallback) {
-      if(_matchingServiceUUID == BLE_UUID_UNKNOWN || _matchingServiceUUID == discoveredService[_numServices].getUUID()) {
-        serviceDiscoveryCallback(&discoveredService[_numServices]);
-      }
-    }
-    _numServices++;
-
-    offset += attribute_data_length;
-  }
-
-  PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr);
-
-}
-
-void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle,
-                                         uint8_t event_data_length,
-                                         uint8_t *handles_info_list)
-{
-  GattAttribute::Handle_t startHandle, endHandle;
-  UUID uuid;
-  uint8_t i, offset, numHandlePairs;
-  /* avoid compiler warnings about unused variables */
-  (void)connectionHandle;
-
-  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);
-    
-    discoveredService[i].setup(_matchingServiceUUID, startHandle, endHandle);
-    
-    if(serviceDiscoveryCallback) {
-      serviceDiscoveryCallback(&discoveredService[_numServices]);
-    }
-    _numServices++;
-    
-    offset += 4;
-  }
-}
-
-void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle,
-                                       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;
-  UUID uuid;
-  uint8_t i, numChar, offset;
-
-  numChar = (event_data_length - 1) / handle_value_pair_length;
-
-  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);
-      PRINTF("C UUID-");
-#ifdef DEBUG
-      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];
-
-    discoveredChar[_numChars].setup(this,
-                                    connectionHandle,
-                                    uuid,
-                                    p,
-                                    declHandle,
-                                    valueHandle);
-
-    if(characteristicDiscoveryCallback) {
-      characteristicDiscoveryCallback(&discoveredChar[_numChars]);
-    }
-    _numChars++;
-
-    offset += handle_value_pair_length;
-  }
-}
-
-void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle,
-                                            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;
-  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);
-    PRINTF("C UUID-");
-#ifdef DEBUG
-    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];
-
-  discoveredChar[_numChars].setup(this,
-                                  connectionHandle,
-                                  uuid,
-                                  p,
-                                  declHandle,
-                                  valueHandle);
-  
-  if(characteristicDiscoveryCallback) {
-    characteristicDiscoveryCallback(&discoveredChar[_numChars]);
-  }
-  _numChars++;
-}
-
-ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle)
-{
-  PRINTF("findServiceChars\n\r");
-  
-  tBleStatus ret;
-  uint8_t uuid_type = UUID_TYPE_16;
-  uint8_t short_uuid[2];
-  uint8_t *uuid = NULL;
-  
-  DiscoveredService *service;
-  
-  // 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");
-  }
-  */
-  
-  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;
-      
-      PRINTF("findServiceChars C UUID-");
-      for(unsigned i = 0; i < 2; i++) {
-        PRINTF("%02X", short_uuid[i]);
-      }
-      PRINTF("\n\r");
-
-    } else if(type==UUID::UUID_TYPE_LONG) {
-      
-      uuid_type = UUID_TYPE_128;
-      uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID();
-      
-      PRINTF("(findServiceChars) C UUID-");
-      for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
-        PRINTF("%02X", uuid[i]);
-      }
-      PRINTF("\r\n");
-    }
-
-    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 BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t                               connectionHandle,
-                                                      ServiceDiscovery::ServiceCallback_t         sc,
-                                                      ServiceDiscovery::CharacteristicCallback_t  cc,
-                                                      const UUID                                 &matchingServiceUUID,
-                                                      const UUID                                 &matchingCharacteristicUUIDIn)
-{
-  PRINTF("launchServiceDiscovery\n\r");
-  
-  tBleStatus ret;
-  uint8_t uuid_type = UUID_TYPE_16;
-  uint8_t short_uuid[2];
-  uint8_t *uuid = NULL;
-  unsigned j;
-  
-  _connectionHandle = connectionHandle;
-  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
-    ret = aci_gatt_disc_all_prim_services((uint16_t)connectionHandle);
-    
-  } else {
-  
-    uint8_t type = matchingServiceUUID.shortOrLong();
-    //PRINTF("AddService(): Type:%d\n\r", type);
-    
-    if(type == UUID::UUID_TYPE_SHORT) {
-      STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID());
-      
-      PRINTF("launchServiceDiscovery short_uuid=0x");
-      for(j = 0; j < 2; j++) {
-        PRINTF("%02X", short_uuid[j]);
-      }
-      PRINTF("\n\r");
-      
-      
-      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();
-      
-      /*
-      PRINTF("launchServiceDiscovery base_uuid=0x");
-      for(j = 0; j < 16; j++) {
-        PRINTF("%02X", uuid[j]);
-      }
-      PRINTF("\n\r");
-      */
-    }
-    
-    // search for specific service by UUID
-    ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)connectionHandle, uuid_type, uuid);
-    //ret = aci_gatt_disc_all_prim_services((uint16_t)connectionHandle);
-  }
-    
-  if(ret == BLE_STATUS_SUCCESS) {
-    _currentState = GATT_SERVICE_DISCOVERY;
-  }
-  
-  PRINTF("launchServiceDiscovery ret=%d\n\r", ret);
-  
-  return BLE_ERROR_NONE;
-}
-
-ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t                        connectionHandle,
-                                                ServiceDiscovery::ServiceCallback_t  callback,
-                                                const UUID                          &matchingServiceUUID)
-{
-  /* avoid compiler warnings about unused variables */
-  (void)connectionHandle;
-  (void)callback;
-  (void)matchingServiceUUID;
-
-  return BLE_ERROR_NOT_IMPLEMENTED;
-}
-
-ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t                        connectionHandle,
-                                                ServiceDiscovery::ServiceCallback_t  callback,
-                                                GattAttribute::Handle_t              startHandle,
-                                                GattAttribute::Handle_t              endHandle)
-{
-  /* avoid compiler warnings about unused variables */
-  (void)connectionHandle;
-  (void)callback;
-  (void)startHandle;
-  (void)endHandle;
-
-  return BLE_ERROR_NOT_IMPLEMENTED;
-}
-
-bool BlueNRGGattClient::isServiceDiscoveryActive(void) const
-{
-  if(_currentState == GATT_IDLE ||
-     _currentState == GATT_DISCOVERY_TERMINATED ||
-       _currentState == GATT_READ_CHAR ||
-         _currentState == GATT_WRITE_CHAR ) {
-    return false;
-  }
-  
-  return true;
-}
-
-void BlueNRGGattClient::terminateServiceDiscovery(void)
-{
-  _currentState = GATT_DISCOVERY_TERMINATED;
-  
-  if (terminationCallback) {
-    terminationCallback(_connectionHandle);
-  }
-}
-
-void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle,
-                                   uint8_t event_data_length,
-                                   uint8_t* attribute_value)
-{
-  readCBParams.connHandle = connHandle;
-  readCBParams.offset = 0;
-  readCBParams.len = event_data_length;
-  readCBParams.data = attribute_value;
-
-  BlueNRGGattClient::getInstance().processReadResponse(&readCBParams);
-}
-
-ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const
-{
-  /* avoid compiler warnings about unused variables */
-  (void)offset;
-
-  tBleStatus ret;
-  
-  BlueNRGGattClient *gattc = const_cast<BlueNRGGattClient*>(this);
-  
-  gattc->_currentState = GATT_READ_CHAR;
-  
-  // Save the attribute_handle not provided by evt_att_read_resp    
-  gattc->readCBParams.handle = attributeHandle;
-  
-  // FIXME: We need to wait for a while before starting a read
-  // due to BlueNRG process queue handling
-  Clock_Wait(100);
-
-  ret = aci_gatt_read_charac_val(connHandle, attributeHandle);
-  
-  if(ret == BLE_STATUS_SUCCESS) {
-    return BLE_ERROR_NONE;
-  }
-  switch (ret) {
-  case BLE_STATUS_BUSY:
-    return BLE_STACK_BUSY;
-  default:
-    return BLE_ERROR_INVALID_STATE;
-  }
-}
-
-void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle,
-                                           uint8_t event_data_length,
-                                           uint16_t attribute_handle,
-                                           uint16_t offset,
-                                           uint8_t *part_attr_value)
-{
-  /* avoid compiler warnings about unused variables */
-  (void)connHandle;
-
-  // 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 BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle,
-                                        uint8_t event_data_length)
-{
-  /* avoid compiler warnings about unused variables */
-  (void)event_data_length;
-
-  writeCBParams.connHandle = connHandle;
-  
-  BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
-}
-
-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
-{
-  /* avoid compiler warnings about unused variables */
-  (void)cmd;
-
-  tBleStatus ret;
-  
-  BlueNRGGattClient *gattc = const_cast<BlueNRGGattClient*>(this);
-    
-  gattc->_currentState = GATT_WRITE_CHAR;
-  
-  // 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 = connHandle;
-  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(connHandle, attributeHandle, length, const_cast<uint8_t *>(value));
-  //ret = aci_gatt_write_charac_reliable(connHandle, attributeHandle, 0, length, const_cast<uint8_t *>(value));
-  
-  if (ret == BLE_STATUS_SUCCESS) {
-    return BLE_ERROR_NONE;
-  }
-  switch (ret) {
-  case BLE_STATUS_BUSY:
-    return BLE_STACK_BUSY;
-  default:
-    return BLE_ERROR_INVALID_STATE;
-  }
-
-}
+/* 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"
+#include "mbed-drivers/mbed.h"
+#include "BlueNRGGap.h"
+#include "Utils.h"
+#include "debug.h"
+
+static uint8_t props_mask[] = {
+  0x01,
+  0x02,
+  0x04,
+  0x08,
+  0x10,
+  0x20,
+  0x40,
+  0x80
+  };
+
+void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, 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(connectionHandle);
+  }
+
+  if(_currentState == GATT_CHAR_DESC_DISCOVERY) {
+    _currentState = GATT_IDLE;
+  }
+
+  // Read complete
+  if(_currentState == GATT_READ_CHAR) {
+    _currentState = GATT_IDLE;
+  }
+
+  // Write complete
+  if(_currentState == GATT_WRITE_CHAR) {
+    BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
+    _currentState = GATT_IDLE;
+  }
+}
+                                                
+void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle,
+                                          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;
+  /* avoid compiler warnings about unused variables */
+  (void)connectionHandle;
+
+  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);
+    
+    if(serviceDiscoveryCallback) {
+      if(_matchingServiceUUID == BLE_UUID_UNKNOWN || _matchingServiceUUID == discoveredService[_numServices].getUUID()) {
+        serviceDiscoveryCallback(&discoveredService[_numServices]);
+      }
+    }
+    _numServices++;
+
+    offset += attribute_data_length;
+  }
+
+  PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr);
+
+}
+
+void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle,
+                                         uint8_t event_data_length,
+                                         uint8_t *handles_info_list)
+{
+  GattAttribute::Handle_t startHandle, endHandle;
+  UUID uuid;
+  uint8_t i, offset, numHandlePairs;
+  /* avoid compiler warnings about unused variables */
+  (void)connectionHandle;
+
+  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);
+    
+    if(serviceDiscoveryCallback) {
+      serviceDiscoveryCallback(&discoveredService[_numServices]);
+    }
+    _numServices++;
+    
+    offset += 4;
+  }
+}
+
+void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle,
+                                       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(this,
+                                    connectionHandle,
+                                    uuid,
+                                    p,
+                                    declHandle,
+                                    valueHandle,
+                                    lastHandle);
+
+    if(characteristicDiscoveryCallback) {
+      characteristicDiscoveryCallback(&discoveredChar[_numChars]);
+    }
+    _numChars++;
+
+    offset += handle_value_pair_length;
+  }
+}
+
+void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle,
+                                            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(this,
+                                  connectionHandle,
+                                  uuid,
+                                  p,
+                                  declHandle,
+                                  valueHandle,
+                                  lastHandle);
+  
+  if(characteristicDiscoveryCallback) {
+    characteristicDiscoveryCallback(&discoveredChar[_numChars]);
+  }
+  _numChars++;
+}
+
+ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle)
+{
+  PRINTF("findServiceChars\n\r");
+  
+  tBleStatus ret;
+  uint8_t uuid_type = UUID_TYPE_16;
+  uint8_t short_uuid[2];
+  uint8_t *uuid = NULL;
+  
+  DiscoveredService *service;
+  
+  // 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");
+  }
+  */
+  
+  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 BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t                               connectionHandle,
+                                                      ServiceDiscovery::ServiceCallback_t         sc,
+                                                      ServiceDiscovery::CharacteristicCallback_t  cc,
+                                                      const UUID                                 &matchingServiceUUID,
+                                                      const UUID                                 &matchingCharacteristicUUIDIn)
+{
+  PRINTF("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("launchServiceDiscovery: nothing to do\n\r");
+    return BLE_ERROR_NONE;
+  }
+
+  _connectionHandle = connectionHandle;
+  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
+    ret = aci_gatt_disc_all_prim_services((uint16_t)connectionHandle);
+    
+  } else {
+  
+    uint8_t type = matchingServiceUUID.shortOrLong();
+    //PRINTF("AddService(): Type:%d\n\r", type);
+    
+    if(type == UUID::UUID_TYPE_SHORT) {
+      STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID());
+#ifdef DEBUG
+      PRINTF("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("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);
+    //ret = aci_gatt_disc_all_prim_services((uint16_t)connectionHandle);
+  }
+    
+  if(ret == BLE_STATUS_SUCCESS) {
+    _currentState = GATT_SERVICE_DISCOVERY;
+  }
+  
+  PRINTF("launchServiceDiscovery ret=%d\n\r", ret);
+  
+  return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t                        connectionHandle,
+                                                ServiceDiscovery::ServiceCallback_t  callback,
+                                                const UUID                          &matchingServiceUUID)
+{
+  /* avoid compiler warnings about unused variables */
+  (void)connectionHandle;
+  (void)callback;
+  (void)matchingServiceUUID;
+
+  return BLE_ERROR_NOT_IMPLEMENTED;
+}
+
+ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t                        connectionHandle,
+                                                ServiceDiscovery::ServiceCallback_t  callback,
+                                                GattAttribute::Handle_t              startHandle,
+                                                GattAttribute::Handle_t              endHandle)
+{
+  /* avoid compiler warnings about unused variables */
+  (void)connectionHandle;
+  (void)callback;
+  (void)startHandle;
+  (void)endHandle;
+
+  return BLE_ERROR_NOT_IMPLEMENTED;
+}
+
+bool BlueNRGGattClient::isServiceDiscoveryActive(void) const
+{
+  if(_currentState == GATT_SERVICE_DISCOVERY) {
+    return true;
+  }
+
+  return false;
+/*
+  if(_currentState == GATT_IDLE ||
+     _currentState == GATT_DISCOVERY_TERMINATED ||
+       _currentState == GATT_READ_CHAR ||
+         _currentState == GATT_WRITE_CHAR ) {
+    return false;
+  }
+  
+  return true;
+*/
+}
+
+void BlueNRGGattClient::terminateServiceDiscovery(void)
+{
+  _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED;
+  
+  if (terminationCallback) {
+    terminationCallback(_connectionHandle);
+  }
+}
+
+void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle,
+                                   uint8_t event_data_length,
+                                   uint8_t* attribute_value)
+{
+  readCBParams.connHandle = connHandle;
+  readCBParams.offset = 0;
+  readCBParams.len = event_data_length;
+  readCBParams.data = attribute_value;
+
+  BlueNRGGattClient::getInstance().processReadResponse(&readCBParams);
+}
+
+ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const
+{
+  /* avoid compiler warnings about unused variables */
+  (void)offset;
+
+  tBleStatus ret;
+  
+  BlueNRGGattClient *gattc = const_cast<BlueNRGGattClient*>(this);
+  
+  // Save the attribute_handle not provided by evt_att_read_resp    
+  gattc->readCBParams.handle = attributeHandle;
+  
+  // FIXME: We need to wait for a while before starting a read
+  // due to BlueNRG process queue handling
+  Clock_Wait(100);
+
+  ret = aci_gatt_read_charac_val(connHandle, attributeHandle);
+  
+  if(ret == BLE_STATUS_SUCCESS) {
+    gattc->_currentState = GATT_READ_CHAR;
+    return BLE_ERROR_NONE;
+  }
+  switch (ret) {
+  case BLE_STATUS_BUSY:
+    return BLE_STACK_BUSY;
+  default:
+    return BLE_ERROR_INVALID_STATE;
+  }
+}
+
+void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle,
+                                           uint8_t event_data_length,
+                                           uint16_t attribute_handle,
+                                           uint16_t offset,
+                                           uint8_t *part_attr_value)
+{
+  /* avoid compiler warnings about unused variables */
+  (void)connHandle;
+
+  // 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 BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle,
+                                        uint8_t event_data_length)
+{
+  /* avoid compiler warnings about unused variables */
+  (void)event_data_length;
+
+  writeCBParams.connHandle = connHandle;
+  
+  BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
+}
+
+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
+{
+  /* avoid compiler warnings about unused variables */
+  (void)cmd;
+
+  tBleStatus ret;
+  
+  BlueNRGGattClient *gattc = const_cast<BlueNRGGattClient*>(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 = connHandle;
+  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(connHandle, attributeHandle, length, const_cast<uint8_t *>(value));
+  //ret = aci_gatt_write_charac_reliable(connHandle, attributeHandle, 0, length, const_cast<uint8_t *>(value));
+  
+  if (ret == BLE_STATUS_SUCCESS) {
+    gattc->_currentState = GATT_WRITE_CHAR;
+    return BLE_ERROR_NONE;
+  }
+  switch (ret) {
+  case BLE_STATUS_BUSY:
+    return BLE_STACK_BUSY;
+  default:
+    return BLE_ERROR_INVALID_STATE;
+  }
+
+}
+
+void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle,
+                                            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;
+
+  for (i=0; i<numCharacDesc; i++) {
+    attHandle = handle_uuid_pair[offset];
+
+    // 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(),
+                                   connHandle,
+                                   attHandle,
+                                   uuid
+                                 )
+       };
+       charDescDiscoveryCallback(&params);
+     }
+
+    _numCharDesc++;
+
+    offset += handle_uuid_length;
+  }
+
+  if(charDescTerminationCallback != NULL) {
+     CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = {
+                               _characteristic,
+                               BLE_ERROR_NONE
+     };
+     charDescTerminationCallback(&params);
+   }
+
+}
+
+ble_error_t BlueNRGGattClient::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;
+
+  Gap::Handle_t connHandle = characteristic.getConnectionHandle();
+  GattAttribute::Handle_t valueHandle = characteristic.getValueHandle();
+  GattAttribute::Handle_t lastHandle = characteristic.getLastHandle();
+
+  ret = aci_gatt_disc_all_charac_descriptors(connHandle, 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 BlueNRGGattClient::reset(void) {
+  /* Clear all state that is from the parent, including private members */
+  if (GattClient::reset() != BLE_ERROR_NONE) {
+    return BLE_ERROR_INVALID_STATE;
+  }
+
+  _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));
+
+  return BLE_ERROR_NONE;
+}
+
--- a/source/BlueNRGGattServer.cpp	Tue Apr 26 14:44:54 2016 +0200
+++ b/source/BlueNRGGattServer.cpp	Mon May 16 17:22:03 2016 +0200
@@ -29,10 +29,7 @@
   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
   *
   * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
-  */ 
-  
- 
-// ANDREA: Changed some types (e.g., tHalUint8 --> uint8_t)
+  */
  
 /** @defgroup BlueNRGGATTSERVER
  *  @brief BlueNRG BLE_API GattServer Adaptation
@@ -124,14 +121,21 @@
     //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();   
-        
+        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]);
         }
         
@@ -168,7 +172,8 @@
                                      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);
+            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(),
@@ -182,20 +187,21 @@
                                      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);
+            PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r",
+                    p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
         }
-
-        /* Update the characteristic handle */
-        //uint16_t charHandle = characteristicCount;   
         
-        bleCharHanldeMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); 
+        bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle));
         
         p_characteristics[characteristicCount++] = p_char;
-        p_char->getValueAttribute().setHandle(bleCharacteristic);    //Set the characteristic count as the corresponding char handle
-        PRINTF("added bleCharacteristic handle =%u\n\r", bleCharacteristic);
+        /* 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)) {
-            write(p_char->getValueAttribute().getHandle(), p_char->getValueAttribute().getValuePtr(), p_char->getValueAttribute().getLength(), false /* localOnly */);
+            write(p_char->getValueAttribute().getHandle(),
+                  p_char->getValueAttribute().getValuePtr(),
+                  p_char->getValueAttribute().getLength(), false /* localOnly */);
         }
 
         // add descriptors now
@@ -206,10 +212,19 @@
             GattAttribute *descriptor = p_char->getDescriptor(descIndex);
             uint16_t shortUUID = descriptor->getUUID().getShortUUID();
             const uint8_t uuidArray[] = {(uint8_t)((shortUUID>>8)&0xFF), (uint8_t)((shortUUID&0xFF))};
-            ret = aci_gatt_add_char_desc(service.getHandle(), p_char->getValueAttribute().getHandle(), 
-            CHAR_DESC_TYPE_16_BIT, uuidArray, 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);
+            ret = aci_gatt_add_char_desc(service.getHandle(),
+                                         bleCharacteristic,
+                                         CHAR_DESC_TYPE_16_BIT,
+                                         uuidArray,
+                                         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);
             if(ret==(tBleStatus)0) {
                 PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle);
@@ -252,11 +267,12 @@
     @endcode
 */
 /**************************************************************************/
-ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t charHandle, uint8_t buffer[], uint16_t *lengthP)
+ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
 {
   tBleStatus ret;
+  uint16_t charHandle = attributeHandle-BlueNRGGattServer::CHAR_VALUE_HANDLE;
 
-  ret = aci_gatt_read_handle_value(charHandle+CHAR_VALUE_OFFSET, *lengthP, lengthP, buffer);
+  ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer);
 
   if(ret == BLE_STATUS_SUCCESS) {
     return BLE_ERROR_NONE;
@@ -294,8 +310,10 @@
     @endcode
 */
 /**************************************************************************/
-// <<<ANDREA>>>
-ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) {
+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;
@@ -306,7 +324,10 @@
   return BLE_ERROR_NONE;
 }
 
-ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly) {
+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;
@@ -314,21 +335,20 @@
   return BLE_ERROR_NONE;
 }
     
-ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t charHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
+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;
 
     tBleStatus ret;
-    //uint8_t buff[2];
+
+    uint16_t charHandle = attributeHandle-BlueNRGGattServer::CHAR_VALUE_HANDLE;
 
-    PRINTF("updating bleCharacteristic charHandle =%u, corresponding serviceHanle= %u len=%d\n\r", charHandle, bleCharHanldeMap.find(charHandle)->second, len);  
-    /*
-    for(int i=0; i<len; i++) {
-        PRINTF("buffer[%d]=%d\n\r", i, buffer[i]);
-    }
-    */
-    ret = aci_gatt_update_char_value(bleCharHanldeMap.find(charHandle)->second, charHandle, 0, len, buffer);
+    PRINTF("updating bleCharacteristic valueHandle=%u,\
+            corresponding serviceHandle=%u len=%d\n\r",
+            attributeHandle, bleCharHandleMap.find(charHandle)->second, len);
+
+    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);
@@ -357,8 +377,8 @@
 /*!
     @brief  Reads a value according to the handle provided
 
-    @param[in]  charHandle
-                The handle of the GattCharacteristic to read from
+    @param[in]  attributeHandle
+                The handle of the attribute to read from
 
     @returns    ble_error_t
 
@@ -372,15 +392,14 @@
     @endcode
 */
 /**************************************************************************/
-ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t handle)
+ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle)
 {
-    //signed short refvalue;
     uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle();
     
     GattReadCallbackParams readParams;
-    readParams.handle = handle;                
+    readParams.handle = attributeHandle;
 
-    //PRINTF("readParams.charHandle = %d\n\r", readParams.charHandle);
+    //PRINTF("readParams.handle = %d\n\r", readParams.handle);
     HCIDataReadEvent(&readParams);
     
     //EXIT:
@@ -396,8 +415,8 @@
 /*!
     @brief  Returns the GattCharacteristic according to the handle provided
 
-    @param[in]  charHandle
-                The handle of the GattCharacteristic
+    @param[in]  attrHandle
+                The handle of the attribute
 
     @returns    ble_error_t
 
@@ -417,10 +436,10 @@
     int i;
     uint16_t handle, handle_1;
 
-    PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attribute Handle received %d\n\r",attrHandle);
+    PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle);
     for(i=0; i<characteristicCount; i++)
     {
-        handle = p_characteristics[i]->getValueAttribute().getHandle();
+        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
         {
@@ -432,7 +451,7 @@
             }            
         }
         else {
-            handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle();
+            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)
             {
@@ -468,3 +487,29 @@
     // <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)
+{
+    /* 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;
+}
--- a/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c	Tue Apr 26 14:44:54 2016 +0200
+++ b/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c	Mon May 16 17:22:03 2016 +0200
@@ -119,7 +119,7 @@
   uint8_t buffer[40];
   uint8_t indx = 0;
     
-  if((unsigned int)(LocalNameLen + ServiceUUIDLen + 14) > sizeof(buffer))
+  if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer))
     return BLE_STATUS_INVALID_PARAMS;
 
   buffer[indx] = AdvType;
@@ -1300,7 +1300,8 @@
   }
   
   *num_devices = rp.num_addr;
-  Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7));
+  if(device_list != NULL)
+    Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7));
   
   return 0;
 }
--- a/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c	Tue Apr 26 14:44:54 2016 +0200
+++ b/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c	Mon May 16 17:22:03 2016 +0200
@@ -317,7 +317,7 @@
 				      uint16_t charHandle,
 				      uint8_t charValOffset,
 				      uint8_t charValueLen,   
-				      const uint8_t *charValue)
+				      const void *charValue)
 {
   struct hci_request rq;
   uint8_t status;
@@ -1361,7 +1361,7 @@
 				   uint16_t charDescHandle,
 				   uint16_t charDescValOffset,
 				   uint8_t charDescValueLen,   
-				   const uint8_t *charDescValue)
+				   const void *charDescValue)
 {
   struct hci_request rq;
   uint8_t status;
--- a/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c	Tue Apr 26 14:44:54 2016 +0200
+++ b/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c	Mon May 16 17:22:03 2016 +0200
@@ -67,6 +67,35 @@
   return 0;
 }
 
+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;
--- a/source/bluenrg-hci/hci/hci.c	Tue Apr 26 14:44:54 2016 +0200
+++ b/source/bluenrg-hci/hci/hci.c	Mon May 16 17:22:03 2016 +0200
@@ -535,7 +535,8 @@
   adv_cp.advtype = advtype;
   adv_cp.own_bdaddr_type = own_bdaddr_type;
   adv_cp.direct_bdaddr_type = direct_bdaddr_type;
-  Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr));
+  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;
   
@@ -817,6 +818,23 @@
   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;
--- a/source/bluenrg-hci/hci/hci_dma_lp.c	Tue Apr 26 14:44:54 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1194 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    hci_dma_lp.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>
-  */ 
-
-// ANDREA -- FIXME: to exclude from building when DMA is disabled
-#ifdef __DMA_LP__
-
-#include "hal_types.h"
-#include "osal.h"
-#include "ble_status.h"
-#include "hal.h"
-#include "hci_const.h"
-#include "gp_timer.h"
-
-#include "bluenrg_interface.h"
-#include "stm32xx_timerserver.h"
-
-extern SPI_HandleTypeDef SpiHandle;
-
-#if BLE_CONFIG_DBG_ENABLE
-#define PRINTF(...) printf(__VA_ARGS__)
-#else
-#define PRINTF(...)
-#endif
-
-#define HCI_LOG_ON 0
-
-#define HCI_READ_PACKET_NUM_MAX 		 (5)
-
-#define MIN(a,b)            ((a) < (b) )? (a) : (b)
-#define MAX(a,b)            ((a) > (b) )? (a) : (b)
-
-static void enqueue_packet(tHciDataPacket * hciReadPacket);
-static void hci_timeout_callback(void);
-
-tListNode hciReadPktPool;
-tListNode hciReadPktRxQueue;
-/* pool of hci read packets */
-static tHciDataPacket     hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX];
-
-static volatile uint8_t readPacketListFull=FALSE;
-
-static uint8_t *hci_buffer = NULL;
-static volatile uint16_t hci_pckt_len;
-static volatile uint8_t hci_timer_id;
-static volatile uint8_t hci_timeout;
-
-uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE];
-
-void hci_timeout_callback(void)
-{
-	hci_timeout = 1;
-
-	return;
-}
-
-void HCI_Init(void)
-{
-    uint8_t index;
-    
-    /* 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]);
-    }
-}
-
-#define HCI_PCK_TYPE_OFFSET                 0
-#define  EVENT_PARAMETER_TOT_LEN_OFFSET     2
-
-void Hal_Init_Event_Request(void)
-{  
-  tHciDataPacket * hciReadPacket = NULL;
-  
-  list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket);
-  
-  Hal_Event_Request ((uint8_t*)hciReadPacket, HCI_READ_PACKET_SIZE);
-}
-
-static volatile hci_packet_complete_callback packet_complete_callback = NULL;
-
-static void hci_set_packet_complete_callback(hci_packet_complete_callback cb)
-{
-	packet_complete_callback = cb;
-}
-
-void HCI_Input(tHciDataPacket * hciReadPacket)
-{
-    uint8_t byte;
-    hci_acl_hdr *acl_hdr;
-
-	static hci_state state = WAITING_TYPE;
-
-        uint16_t collected_payload_len = 0;
-	uint16_t payload_len;
-    
-    hci_buffer = hciReadPacket->dataBuff;
-    
-    if(state == WAITING_TYPE)
-        hci_pckt_len = 0;
-    
-    while(hci_pckt_len < HCI_READ_PACKET_SIZE){
-
-        byte = hci_buffer[hci_pckt_len++];
-
-        if(state == WAITING_TYPE){
-            /* Only ACL Data and Events packets are accepted. */
-            if(byte == HCI_EVENT_PKT){
-                 state = WAITING_EVENT_CODE;
-            }
-//            else if(byte == HCI_ACLDATA_PKT){
-//                state = WAITING_HANDLE;
-//            }
-            else{
-                /* Incorrect type. Reset state machine. */
-                state = WAITING_TYPE;
-                break;
-            }
-        }
-        else if(state == WAITING_EVENT_CODE)
-            state = WAITING_PARAM_LEN;
-        else if(state == WAITING_HANDLE)
-            state = WAITING_HANDLE_FLAG;
-        else if(state == WAITING_HANDLE_FLAG)
-            state = WAITING_DATA_LEN1;
-        else if(state == WAITING_DATA_LEN1)
-            state = WAITING_DATA_LEN2;
-
-        else if(state == WAITING_DATA_LEN2){
-            acl_hdr = (void *)&hci_buffer[HCI_HDR_SIZE];
-            payload_len = acl_hdr->dlen;
-            collected_payload_len = 0;
-            state = WAITING_PAYLOAD;
-        }
-        else if(state == WAITING_PARAM_LEN){
-             payload_len = byte;
-             collected_payload_len = 0;
-             state = WAITING_PAYLOAD;
-        }
-        else if(state == WAITING_PAYLOAD){
-            collected_payload_len += 1;
-            if(collected_payload_len >= payload_len){
-                /* Reset state machine. */
-                state = WAITING_TYPE;
-                enqueue_packet(hciReadPacket);
-                
-                if(packet_complete_callback){
-                  uint16_t len = hci_pckt_len;
-                  packet_complete_callback(hci_buffer, len);
-                }
-                break;
-            }
-        }
-    }        
-}
-
-void enqueue_packet(tHciDataPacket * hciReadPacket)
-{
-    hci_uart_pckt *hci_pckt = (void*)hciReadPacket->dataBuff;
-    hci_event_pckt *event_pckt = (void*)hci_pckt->data;
-    
-    // Do not enqueue Command Complete or Command Status events
-    
-    if((hci_pckt->type != HCI_EVENT_PKT) ||
-       event_pckt->evt == EVT_CMD_COMPLETE ||
-           event_pckt->evt == EVT_CMD_STATUS){
-        // Insert the packet back into the pool.
-        list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
-    }
-    else {    
-        // Insert the packet into the queue of events to be processed.
-        list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket);
-        HCI_Process_Notification_Request();
-    }
-}
-
-void HCI_Process(void)
-{
-    //uint8_t data_len;
-    //uint8_t buffer[HCI_PACKET_SIZE];
-    tHciDataPacket * hciReadPacket = NULL;
-
-    uint8_t list_empty = list_is_empty(&hciReadPktRxQueue);        
-    /* process any pending events read */
-    while(list_empty == FALSE)
-    {
-        list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
-        HCI_Event_CB(hciReadPacket->dataBuff);
-        list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
-        list_empty = list_is_empty(&hciReadPktRxQueue);
-    }
-}
-
-BOOL HCI_Queue_Empty(void)
-{
-  return list_is_empty(&hciReadPktRxQueue);
-}
-
-void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len)
-{
-  tHciDataPacket * hciReadPacket = NULL;
-  
-  if (list_is_empty (&hciReadPktPool) == FALSE){
-    
-    list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket);
-    
-    Hal_Event_Request ((uint8_t*)hciReadPacket, HCI_READ_PACKET_SIZE);
-  }
-  
-  if(event_payload_len > 0){
-    
-    HCI_Input((tHciDataPacket*)buffer);
-    // Packet will be inserted to te correct queue by 
-  }
-  else {
-    // Insert the packet back into the pool.
-    list_insert_head(&hciReadPktPool, (tListNode*)buffer);
-  }
-}
-
-void hci_write(const void* data1, const void* data2, uint16_t n_bytes1, uint16_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 uint8_t new_packet;
-
-void new_hci_event(void *pckt, uint16_t len)
-{
-  
-  new_packet = TRUE;
-}
-
-/**
- * FIXME: Param async is unused, it has been introduced to align the interface
- * to DK 1.6.0 HCI stack
- */
-/* 'to' is timeout in system clock ticks.  */
-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 try;
-  uint32_t to = DEFAULT_TIMEOUT;
-  
-  new_packet = FALSE;
-  HCI_Cmd_Status(BUSY);
-  hci_set_packet_complete_callback(new_hci_event);
-  hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam);
-  
-  try = 10;
-  while (try--) {
-    evt_cmd_complete *cc;
-    evt_cmd_status *cs;
-    evt_le_meta_event *me;
-    int len;
-    
-    /* Minimum timeout is 1. */
-    if(to == 0)
-      to = 1;
-    
-    hci_timeout = 0;
-    Blue_NRG_HCI_Timer_Start(to, hci_timeout_callback, (uint8_t*)&hci_timer_id);
-    
-    while(1){
-      if(hci_timeout){
-        Blue_NRG_HCI_Timer_Stop(hci_timer_id);
-        goto failed;
-      }
-      if(new_packet){
-        Blue_NRG_HCI_Timer_Stop(hci_timer_id);
-        break;
-      }
-      HCI_Wait_For_Response();
-    }
-    
-    hci_hdr = (void *)hci_buffer;
-    if(hci_hdr->type != HCI_EVENT_PKT){
-      new_packet = FALSE;
-      continue;
-    }
-    
-    event_pckt = (void *) (hci_hdr->data);
-    
-    ptr = hci_buffer + (1 + HCI_EVENT_HDR_SIZE);
-    len = hci_pckt_len - (1 + HCI_EVENT_HDR_SIZE);
-    
-    switch (event_pckt->evt) {
-      
-    case EVT_CMD_STATUS:
-      cs = (void *) ptr;
-      
-      if (cs->opcode != opcode)
-        break;
-      
-      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)
-        break;
-      
-      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; // In the meantime there could be other events from the controller.
-    }
-    
-    new_packet = FALSE;
-    
-  }
-  
-failed:
-  hci_set_packet_complete_callback(NULL);
-  return -1;
-  
-done:
-  hci_set_packet_complete_callback(NULL);
-  HCI_Cmd_Status(AVAILABLE);
-  return 0;
-}
-
-int hci_reset()
-{
-  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 -1;
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;  
-}
-
-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 -1;
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;  
-}
-
-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 -1;
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  
-  *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 -1;
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  *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;
-  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 -1;
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-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 -1;
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-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 -1;
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-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 -1;
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  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 -1;
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-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 -1;
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  *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 -1;
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-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 -1;
-  
-  if (resp.status) {
-    return -1;
-  }
-  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 -1;
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-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 -1;
-  }
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  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 -1;
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-int hci_le_ltk_request_neg_reply()
-{
-  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 -1;
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-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 -1;
-  }
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  *size = resp.size;
-  
-  return 0;
-}
-
-int hci_le_clear_white_list()
-{
-  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 -1;
-  }
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-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 -1;
-  }
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-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 -1;
-  }
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-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 -1;
-  }
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  *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 -1;
-  }
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  *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 -1;
-  }
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  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 -1;
-  }
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  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 -1;
-  }
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  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 -1;
-  }
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-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 -1;
-  }
-  
-  if (status) {
-    return -1;
-  }
-  
-  return 0;
-}
-
-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 -1;
-  }
-  
-  if (resp.status) {
-    return -1;
-  }
-  
-  *num_pkts = resp.num_pkts;
-  
-  return 0;
-}
-
-#endif /* __DMA_LP__ */
\ No newline at end of file
--- a/source/platform/btle.cpp	Tue Apr 26 14:44:54 2016 +0200
+++ b/source/platform/btle.cpp	Mon May 16 17:22:03 2016 +0200
@@ -48,7 +48,6 @@
 
 
 /* C File Includes ------------------------------------------------------------------*/
-// ANDREA: Updated includes and changed some types (e.g., tHalUint8 --> uint8_t)
 #include <stdio.h>
 #include <string.h>
 #include "hci.h"
@@ -100,6 +99,8 @@
 void btleInit(bool isSetAddress, uint8_t role)
 {
     PRINTF("btleInit>>\n\r");
+    /* Avoid compiler warnings about unused variables. */
+    (void)isSetAddress;
     
     int ret;
     uint8_t  hwVersion;
@@ -143,7 +144,6 @@
 
     /* The Nucleo board must be configured as SERVER */
     //check if isSetAddress is set then set address.
-    // ANDREA
 #if 0
     if(isSetAddress)
     {
@@ -165,13 +165,21 @@
                                         BLE_address_BE);
     }
 #endif
+
+    const Gap::Address_t BLE_address_BE = {0xFD,0x66,0x05,0x13,0xBE,0xBA};
+    BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE);
     
     ret = aci_gatt_init();
     if(ret){
         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, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle);
+        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 {
         ret = aci_gap_init_IDB04A1(role, &service_handle, &dev_name_char_handle, &appearance_char_handle);
     }
@@ -180,7 +188,7 @@
         PRINTF("GAP_Init failed.\n");
     }
 
-    //ANDREA -- FIXME: Security and passkey set by default    
+    //FIXME: Security and passkey set by default
     ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED,
                                        OOB_AUTH_DATA_ABSENT,
                                        NULL,
@@ -202,7 +210,6 @@
     /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0,
                             strlen(name), (tHalUint8 *)name);*/
 
-    // Andrea: mbedOS
 #ifdef AST_FOR_MBED_OS
     minar::Scheduler::postCallback(btle_handler);
 #endif
@@ -211,7 +218,7 @@
 
 /**************************************************************************/
 /*!
-    @brief  Andrea: mbedOS
+    @brief  mbedOS
 
     @param[in]  void
     
@@ -282,20 +289,43 @@
     return;
 }
    
-void Attribute_Modified_CB(uint16_t attr_handle, uint8_t data_length, uint8_t *att_data, uint8_t offset)
-{        
+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();
+        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+CHAR_VALUE_OFFSET) {
+
+        if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) {
             currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE;
         }
 
-        if(attr_handle == charHandle+CHAR_DESC_OFFSET) {
+        if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) {
             currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE;
         }
         PRINTF("currentHandle %d\n\r", currentHandle);
@@ -303,18 +333,20 @@
             (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, p_char->getValueAttribute().getHandle());
+                BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle);
             } else {
                 //PRINTF("Notify DISABLED\n\r"); 
-                BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, p_char->getValueAttribute().getHandle());
+                BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle);
             }
         }
                     
-        //Check is attr handle property is WRITEABLE, if yes, generate GATT_EVENT_DATA_WRITTEN Event
+        //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) {
@@ -322,21 +354,22 @@
             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;                                                                                    
-            if (bnrg_expansion_board == IDB05A1) {
-                writeParams.offset = offset;
-            } else {
-                writeParams.offset = 0;
-            }
+            writeParams.data = att_data;
+            writeParams.offset = offset;
+
             BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams);
 
-            //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, evt->attr_handle);
+            //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().write(p_char->getValueAttribute().getHandle(),
+                                                       (uint8_t*)att_data,
+                                                       data_length,
+                                                       false);
             }
         } 
     }
@@ -383,7 +416,7 @@
                 evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data;
                 
                 switch(evt->subevent){
-                // ANDREA
+
                 case EVT_LE_CONN_COMPLETE:
                     {                            
                         PRINTF("EVT_LE_CONN_COMPLETE\n");
@@ -448,7 +481,7 @@
           
           BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND,
                                                  pr->evt_type,
-                                                 &pr->bdaddr_type,
+                                                 pr->bdaddr_type,
                                                  pr->bdaddr,
                                                  &pr->data_length,
                                                  &pr->data_RSSI[0],
@@ -469,7 +502,8 @@
                     {
                         PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r");
                         evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data;
-                        BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle-CHAR_VALUE_OFFSET);                                                
+                        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;
                     
@@ -478,13 +512,7 @@
                         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 */
-                        if (bnrg_expansion_board == IDB05A1) {
-                            evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data;
-                            Attribute_Modified_CB(evt->attr_handle, evt->data_length, evt->att_data, evt->offset);
-                        } else {
-                            evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data;
-                            Attribute_Modified_CB(evt->attr_handle, evt->data_length, evt->att_data, 0);
-                        }                  
+                        Attribute_Modified_CB(blue_evt);
                     }
                     break;  
                     
@@ -565,7 +593,17 @@
                                                               pr->handles_info_list);
           }
           break;
-                case EVT_BLUE_GATT_PROCEDURE_COMPLETE:
+        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:
           {
             //PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE\n\r");
             evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data;
@@ -582,7 +620,7 @@
             
             BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND,
                                                    pr->evt_type,
-                                                   &pr->bdaddr_type,
+                                                   pr->bdaddr_type,
                                                    pr->bdaddr,
                                                    &pr->data_length,
                                                    &pr->data_RSSI[0],
@@ -593,12 +631,12 @@
         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);
+            //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, NULL, NULL, NULL, NULL, NULL);
+              BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL);
               break;
             }
           }
--- a/source/platform/stm32_bluenrg_ble_dma_lp.c	Tue Apr 26 14:44:54 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,989 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32_bluenrg_ble_dma_lp.c
-  * @author  CL
-  * @version V1.0.0
-  * @date    04-July-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.
-  *
-  ******************************************************************************
-  */ 
-
-// ANDREA -- FIXME: to exclude from building when DMA is disabled
-#ifdef __DMA_LP__
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32_bluenrg_ble_dma_lp.h"
-#include "hci_const.h"
-
-/** @addtogroup BSP
- *  @{
- */
-
-/** @addtogroup X-NUCLEO-IDB04A1
- *  @{
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP
- *  @{
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Defines 
- *  @{
- */
- 
-#define TEST_TX_BUFFER_LIMITATION 0
-#define MAX_TX_BUFFER_SIZE 0x7F
-#define BLUENRG_READY_STATE 0x02
-
-#define HEADER_SIZE 5
-#define MAX_BUFFER_SIZE 255
-
-/**
- * @}
- */
- 
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Types
-* @{
-*/ 
-
-typedef enum
-{
-  SPI_HEADER_TRANSMIT,
-  SPI_PAYLOAD_TRANSMIT
-} SPI_TRANSMIT_REQUEST_t;
-
-typedef enum
-{
-  SPI_HEADER_TRANSMITTED,
-  SPI_PAYLOAD_TRANSMITTED
-} SPI_TRANSMIT_EVENT_t;
-
-typedef enum
-{
-  SPI_REQUEST_VALID_HEADER_FOR_RX,
-  SPI_REQUEST_VALID_HEADER_FOR_TX,
-  SPI_REQUEST_PAYLOAD
-} SPI_RECEIVE_REQUEST_t;
-
-typedef enum
-{
-  SPI_CHECK_RECEIVED_HEADER_FOR_RX,
-  SPI_CHECK_RECEIVED_HEADER_FOR_TX,
-  SPI_RECEIVE_END
-} SPI_RECEIVE_EVENT_t;
-
-typedef enum
-{
-  SPI_AVAILABLE,
-  SPI_BUSY
-} SPI_PERIPHERAL_STATUS_t;
-
-typedef struct
-{
-  SPI_TRANSMIT_EVENT_t Spi_Transmit_Event;
-  uint8_t* header_data;
-  uint8_t* payload_data;
-  uint8_t header_size;
-  uint8_t payload_size;
-  uint8_t payload_size_to_transmit;
-  uint8_t packet_cont;
-  uint8_t RequestPending;
-} SPI_Transmit_Context_t;
-
-typedef struct
-{
-  SPI_RECEIVE_EVENT_t Spi_Receive_Event;
-  uint16_t payload_len;
-  uint8_t* buffer;
-  uint8_t buffer_size;
-} SPI_Receive_Context_t;
-
-typedef struct
-{
-  SPI_HandleTypeDef *hspi;
-  SPI_PERIPHERAL_STATUS_t Spi_Peripheral_State;
-  SPI_Receive_Context_t SPI_Receive_Context;
-  SPI_Transmit_Context_t SPI_Transmit_Context;
-} SPI_Context_t;
-
-/**
- * @}
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Variables
- * @{
- */
-
-SPI_HandleTypeDef SpiHandle;
-SPI_Context_t SPI_Context;
-
-const uint8_t Write_Header_CMD[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00};
-const uint8_t Read_Header_CMD[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00};
-const uint8_t dummy_bytes = 0xFF;
-
-uint8_t Received_Header[HEADER_SIZE];
-
-#ifdef ENABLE_SPI_FIX
-static uint8_t StartupTimerId;
-#endif
-static uint8_t TxRxTimerId;
-volatile uint8_t ubnRFresetTimerLock;
-pf_TIMER_TimerCallBack_t pTimerTxRxCallback;
-
-/**
- * @}
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Extern_Variables
- * @{
- */
-extern uint8_t* HCI_read_packet;
-
-/**
- * @}
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Function_Prototypes 
- *  @{
- */
- 
-/* Private function prototypes -----------------------------------------------*/
-static void SPI_Transmit_Manager(SPI_TRANSMIT_REQUEST_t TransmitRequest);
-static void SPI_Receive_Manager(SPI_RECEIVE_REQUEST_t ReceiveRequest);
-static void set_irq_as_output(void);
-static void set_irq_as_input(void);
-static void Disable_SPI_Receiving_Path(void);
-static void Enable_SPI_Receiving_Path(void);
-static void Enable_SPI_CS(void);
-static void Disable_SPI_CS(void);
-static void DisableEnable_SPI_CS(void);
-static void TransmitClosure(void);
-static void ReceiveClosure(void);
-static void ReceiveHeader(SPI_RECEIVE_EVENT_t ReceiveEvent, uint8_t * DataHeader);
-static void WakeupBlueNRG(void);
-static void TimerStartupCallback(void);
-static void TimerTransmitCallback(void);
-static void pf_nRFResetTimerCallBack(void);
-static void TimerTxRxCallback(void);
-static void ProcessEndOfReceive(void);
-
-/**
- * @}
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Exported_Functions 
- * @{
- */ 
- 
-/**
- * @brief  This function notify when then BlueNRG nRESET may be released
- * @param  None
- * @retval None
- */
-static void pf_nRFResetTimerCallBack(void)
-{
-  ubnRFresetTimerLock = 0;
-  
-  return;
-}
-
-/**
- * @brief  Timer callback to handle RxTx Timers
- * @param  None
- * @retval None
- */
-static void TimerTxRxCallback(void)
-{
-  pTimerTxRxCallback();
-  
-  return;
-}
-
-/**
- * @brief  Close the receiver path
- * @param  None
- * @retval None
- */
-static void ReceiveClosure(void)
-{
-  /*
-   *  Disable both DMA
-   */
-  __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
-  __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
-  
-  /*
-   * Check if a command is pending
-   */
-  __disable_irq();
-  if(SPI_Context.SPI_Transmit_Context.RequestPending == TRUE)
-  {
-    SPI_Context.SPI_Transmit_Context.RequestPending = FALSE;
-    SPI_Context.Spi_Peripheral_State = SPI_BUSY;
-    Disable_SPI_Receiving_Path();
-    __enable_irq();
-    WakeupBlueNRG();
-  }
-  else
-  {
-    SPI_Context.Spi_Peripheral_State = SPI_AVAILABLE;
-    __enable_irq();
-  }
-  
-  return;
-}
-
-/**
- * @brief  Delay Notification to the App to prevent dummy event read
- * @param  None
- * @retval None
- */
-static void ProcessEndOfReceive(void)
-{
-  ReceiveClosure();
-  
-  HCI_Isr(HCI_read_packet, SPI_Context.SPI_Receive_Context.payload_len);
-  
-  return;
-}
-
-/**
- * @brief  Timer callback to apply timeout SPI FIX
- * @param  None
- * @retval None
- */
-static void TimerTransmitCallback(void)
-{
-  SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX);	/**< BlueNRG not ready for writing */
-  LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_Sleep);
-  
-  return;
-}
-
-/**
- * @brief  Closes the SPI when BLE is disabled by the application
- * 		   Releases allocated resources
- * @param  None
- * @retval None
- */
-void BNRG_SPI_Close(void)
-{
-#ifdef ENABLE_SPI_FIX
-  TIMER_Delete(StartupTimerId);
-#endif
-  TIMER_Delete(TxRxTimerId);
-  
-  return;
-}
-
-/**
- * @brief  Initializes the SPI communication with the BlueNRG Shield.
- * @param  None
- * @retval None
- */
-void BNRG_SPI_Init(void)
-{
-  BNRG_MSP_SPI_Init(&SpiHandle);
-  
-  SPI_Context.hspi = &SpiHandle;  
-  
-  SPI_Context.Spi_Peripheral_State = SPI_AVAILABLE;
-  SPI_Context.SPI_Transmit_Context.RequestPending = FALSE;
-  
-  __HAL_BLUENRG_SPI_ENABLE_DMAREQ(&SpiHandle, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);
-  
-  __HAL_SPI_ENABLE(&SpiHandle);
-
-#ifdef ENABLE_SPI_FIX
-  TIMER_Create(eTimerModuleID_Interrupt, &StartupTimerId, eTimerMode_SingleShot, TimerStartupCallback);
-#endif
-  TIMER_Create(eTimerModuleID_Interrupt, &TxRxTimerId, eTimerMode_SingleShot, TimerTxRxCallback);
-  return;
-}
-
-/**
- * @brief  Initializes the SPI communication with the BlueNRG Shield
- * @param  None
- * @retval None
- */
-void BNRG_MSP_SPI_Init(SPI_HandleTypeDef * hspi)
-{
-  hspi->Instance = BNRG_SPI_INSTANCE;
-  hspi->Init.Mode = BNRG_SPI_MODE;
-  hspi->Init.Direction = BNRG_SPI_DIRECTION;
-  hspi->Init.DataSize = BNRG_SPI_DATASIZE;
-  hspi->Init.CLKPolarity = BNRG_SPI_CLKPOLARITY;
-  hspi->Init.CLKPhase = BNRG_SPI_CLKPHASE;
-  hspi->Init.NSS = BNRG_SPI_NSS;
-  hspi->Init.FirstBit = BNRG_SPI_FIRSTBIT;
-  hspi->Init.TIMode = BNRG_SPI_TIMODE;
-  hspi->Init.CRCPolynomial = BNRG_SPI_CRCPOLYNOMIAL;
-  hspi->Init.BaudRatePrescaler = BNRG_SPI_BAUDRATEPRESCALER;
-  hspi->Init.CRCCalculation = BNRG_SPI_CRCCALCULATION;
-
-  HAL_SPI_Init(hspi);
-
-  return;
-}
-
-/**
- * @brief  Resets the BlueNRG.
- * @param  None
- * @retval None
- */
-void BlueNRG_RST(void)
-{
-  uint8_t ubnRFResetTimerID;
-  
-  GPIO_InitTypeDef GPIO_InitStruct;
-  
-  GPIO_InitStruct.Pin = BNRG_SPI_RESET_PIN;
-  GPIO_InitStruct.Speed = BNRG_SPI_RESET_SPEED;
-  TIMER_Create(eTimerModuleID_Interrupt, &ubnRFResetTimerID, eTimerMode_SingleShot, pf_nRFResetTimerCallBack);
-  
-  BNRG_SPI_RESET_CLK_ENABLE();
-  
-  HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET);
-  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);
-  
-  TIMER_Start(ubnRFResetTimerID, BLUENRG_HOLD_TIME_IN_RESET);
-  ubnRFresetTimerLock = 1;
-  while(ubnRFresetTimerLock == 1);
-  
-  HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_SET);
-  
-#if 1
-  /*
-   * Limitation in HAL V1.1.0
-   * The HAL_GPIO_Init() is first configuring the Mode of the IO before the Pull UP configuration
-   * To avoid glitch on the IO, the configuration shall go through an extra step OUTPUT/PULLUP
-   * to set upfront the PULL UP configuration.
-   */
-  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Pull = GPIO_PULLUP;
-  HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);
-#endif
-  
-  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
-  GPIO_InitStruct.Pull = GPIO_PULLUP;
-  HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);
-  
-  TIMER_Start(ubnRFResetTimerID, BLUENRG_HOLD_TIME_AFTER_RESET);
-  ubnRFresetTimerLock = 1;
-  while(ubnRFresetTimerLock == 1);
-  TIMER_Delete(ubnRFResetTimerID);
-  
-  return;
-}
-
-/**
- * @brief  Writes data from local buffer to SPI.
- * @param  hspi: SPI handle
- * @param  header_data: First data buffer to be written
- * @param  payload_data: Second data buffer to be written
- * @param  header_size: Size of first data buffer to be written
- * @param  payload_size: Size of second data buffer to be written
- * @retval Number of read bytes
- */
-void BlueNRG_SPI_Write(uint8_t* header_data, uint8_t* payload_data, uint8_t header_size, uint8_t payload_size)
-{  
-  SPI_Context.SPI_Transmit_Context.header_data = header_data;
-  SPI_Context.SPI_Transmit_Context.payload_data = payload_data;
-  SPI_Context.SPI_Transmit_Context.header_size = header_size;
-  SPI_Context.SPI_Transmit_Context.payload_size = payload_size;
-  
-  SPI_Context.SPI_Transmit_Context.packet_cont = FALSE;
-  
-  __disable_irq();
-  if(SPI_Context.Spi_Peripheral_State == SPI_AVAILABLE)
-  {
-    SPI_Context.Spi_Peripheral_State = SPI_BUSY;
-    Disable_SPI_Receiving_Path();
-    __enable_irq();
-    WakeupBlueNRG();
-  }
-  else
-  {
-    SPI_Context.SPI_Transmit_Context.RequestPending = TRUE;
-    __enable_irq();
-  }
-  
-  return;
-}
-
-/**
- * @brief  Set in Output mode the IRQ.
- * @param  None
- * @retval None
- */
-static void set_irq_as_output(void)
-{
-  HAL_GPIO_WritePin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN, GPIO_PIN_SET);
-  HAL_LPPUART_GPIO_Set_Mode(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN_POSITION, GPIO_MODE_OUTPUT_PP);
-  __HAL_GPIO_EXTI_CLEAR_IT(BNRG_SPI_IRQ_PIN);
-}
-
-/**
- * @brief  Set the IRQ in input mode.
- * @param  None
- * @retval None
- */
-static void set_irq_as_input(void)
-{
-  HAL_GPIO_WritePin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN, GPIO_PIN_RESET); // WARNING: it may conflict with BlueNRG driving High
-  HAL_LPPUART_GPIO_Set_Mode(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN_POSITION, GPIO_MODE_INPUT);
-}
-
-/**
- * @brief  Enable SPI IRQ.
- * @param  None
- * @retval None
- */
-static void Enable_SPI_Receiving_Path(void)
-{  
-  __HAL_GPIO_EXTI_CLEAR_IT(BNRG_SPI_EXTI_PIN);
-  HAL_NVIC_ClearPendingIRQ(BNRG_SPI_EXTI_IRQn);
-  HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn);
-  
-  if (HAL_GPIO_ReadPin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN) == GPIO_PIN_SET)
-  {
-    __HAL_GPIO_EXTI_GENERATE_SWIT(BNRG_SPI_IRQ_PIN);
-  }
-}
-
-/**
- * @brief  Disable SPI IRQ.
- * @param  None
- * @retval None
- */
-static void Disable_SPI_Receiving_Path(void)
-{  
-  HAL_NVIC_DisableIRQ(BNRG_SPI_EXTI_IRQn);
-}
-
-/**
- * @brief  Enable SPI CS.
- * @param  None
- * @retval None
- */
-static void Enable_SPI_CS(void)
-{
-  /* CS reset */
-  HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET);
-}
-
-/**
- * @brief  Disable SPI CS.
- * @param  None
- * @retval None
- */
-static void Disable_SPI_CS(void)
-{
-  while (__HAL_SPI_GET_FLAG(SPI_Context.hspi,SPI_FLAG_BSY) == SET);
-  
-  /* CS set */
-  HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
-}
-
-/**
- * @brief  Disable and Enable SPI CS.
- * @param  None
- * @retval None
- */
-static void DisableEnable_SPI_CS(void)
-{
-  while (__HAL_SPI_GET_FLAG(SPI_Context.hspi,SPI_FLAG_BSY) == SET);
-  
-  /* CS set */
-  HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
-  
-  /* CS reset */
-  HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET);
-}
-
-/**
- * @brief Tx and Rx Transfer completed callbacks
- * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
- *              the configuration information for SPI module.
- * @retval None
- */
-void BlueNRG_DMA_RxCallback(void)
-{
-  uint16_t byte_count;
-  uint8_t ready_state;
-  
-  __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmarx, BNRG_SPI_RX_DMA_TC_FLAG);
-  
-  /**
-   * The TCIF shall be cleared to be able to start a new DMA transmission later on when required.
-   * When receiving data, the TCIE is not set as there is no need to handle the interrupt
-   * handler of the DMA_Tx.
-   * The TCIF clearing is mandatory on STM32F4 but not on STM32L0.
-   * In order to keep code identical across platform, the TCIF clearing may be kept as well on
-   * the STM32L0 and all other MCUs.
-   */
-  __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG);
-  switch (SPI_Context.SPI_Receive_Context.Spi_Receive_Event)
-  {
-  case SPI_CHECK_RECEIVED_HEADER_FOR_RX:
-    byte_count = (Received_Header[4]<<8)|Received_Header[3];
-    ready_state = Received_Header[0];
-    
-    if ((byte_count == 0) || (ready_state != BLUENRG_READY_STATE))
-    {
-      if (HAL_GPIO_ReadPin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN) == GPIO_PIN_RESET)
-      {
-        /**
-         * This USE CASE shall never happen as this may break the IRQ/CS specification
-         * The IRQ line shall never be low when CS is low to avoid BlueNRG race condition when
-         * entering low power mode
-         * the SPI_END_RECEIVE_FIX has been implemented to make sure this USE CASE never occurs
-         * However, even when the behavior is not compliant to the specification, the BlueNRG
-         * may not fail so it is increasing robustness by adding this checking just in case the
-         * timeout define in the workaround is too short which will end up to marginally brake
-         * the specification.
-         * This checking will poping BluenRG for a dummy even
-         */
-        
-        /* Release CS line */
-        Disable_SPI_CS();
-        
-        LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_LP_Stop);
-        
-        ReceiveClosure();
-      }
-      else
-      {
-        DisableEnable_SPI_CS();
-        SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_RX); /**< BlueNRG not ready for reading */
-      }
-    }
-    else
-    {
-      SPI_Receive_Manager(SPI_REQUEST_PAYLOAD);	/**< BlueNRG is ready for reading */
-    }
-    break;
-    
-  case SPI_RECEIVE_END:
-    /* Release CS line */
-    Disable_SPI_CS();
-    
-    LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_LP_Stop);
-    
-#if (SPI_END_RECEIVE_FIX == 1)
-    pTimerTxRxCallback = ProcessEndOfReceive;
-    TIMER_Start(TxRxTimerId, SPI_END_RECEIVE_FIX_TIMEOUT);
-#else
-    ProcessEndOfReceive();
-#endif
-    break;
-    
-  case SPI_CHECK_RECEIVED_HEADER_FOR_TX:
-    byte_count = (Received_Header[2]<<8)|Received_Header[1];
-    ready_state = Received_Header[0];
-    
-    if ((byte_count == 0) || (ready_state != BLUENRG_READY_STATE))
-    {
-      DisableEnable_SPI_CS();
-      SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX);	/**< BlueNRG not ready for writing */
-    }
-    else
-    {
-#if (TEST_TX_BUFFER_LIMITATION == 1)
-      if(byte_count > MAX_TX_BUFFER_SIZE)
-      {
-        byte_count = MAX_TX_BUFFER_SIZE;
-      }
-#endif
-      
-      if(SPI_Context.SPI_Transmit_Context.packet_cont != TRUE)
-      {
-        if( byte_count < (SPI_Context.SPI_Transmit_Context.header_size + SPI_Context.SPI_Transmit_Context.payload_size))
-        {
-          SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = byte_count - SPI_Context.SPI_Transmit_Context.header_size;
-          SPI_Context.SPI_Transmit_Context.payload_size -= SPI_Context.SPI_Transmit_Context.payload_size_to_transmit;
-          SPI_Context.SPI_Transmit_Context.packet_cont = TRUE;
-        }
-        else
-        {
-          SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = SPI_Context.SPI_Transmit_Context.payload_size;
-        }
-        
-        SPI_Transmit_Manager(SPI_HEADER_TRANSMIT);
-      }
-      else
-      {
-        if( byte_count < SPI_Context.SPI_Transmit_Context.payload_size)
-        {
-          SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = byte_count;
-          SPI_Context.SPI_Transmit_Context.payload_size -= SPI_Context.SPI_Transmit_Context.payload_size_to_transmit;
-        }
-        else
-        {
-          SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = SPI_Context.SPI_Transmit_Context.payload_size;
-          SPI_Context.SPI_Transmit_Context.payload_size = 0;
-        }
-        
-        SPI_Transmit_Manager(SPI_PAYLOAD_TRANSMIT);
-      }
-    }
-    
-    break;
-    
-  default:
-    break;
-  }
-}
-
-#ifdef ENABLE_SPI_FIX
-/**
- * @brief  Wakeup BlueNRG
- * @param  None
- * @retval None
- */
-static void WakeupBlueNRG(void)
-{
-  Disable_SPI_Receiving_Path();
-  pTimerTxRxCallback = TimerTransmitCallback;
-  set_irq_as_output();
-  TIMER_Start(StartupTimerId, SPI_FIX_TIMEOUT);
-  TIMER_Start(TxRxTimerId, SPI_FIX_TIMEOUT+SPI_TX_TIMEOUT);
-  LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_LP_Stop);
-    
-  return;
-}
-
-/**
- * @brief  Timer callback to apply timeout SPI FIX
- * @param  None
- * @retval None
- */
-static void TimerStartupCallback(void)
-{
-  Enable_SPI_CS();
-  
-  return;
-}
-
-#else
-/**
- * @brief  Wakeup BlueNRG
- * @param  None
- * @retval None
- */
-static void WakeupBlueNRG(void)
-{
-  Disable_SPI_Receiving_Path();
-  pTimerTxRxCallback = TimerTransmitCallback;
-  Enable_SPI_CS();
-  TIMER_Start(TxRxTimerId, SPI_TX_TIMEOUT);
-  LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_LP_Stop);
-  
-  return;
-}
-#endif /* ENABLE_SPI_FIX */
-
-/**
- * @brief  Tx and Rx Transfer completed callbacks
- * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
- *               the configuration information for SPI module.
- * @retval None
- */
-void BlueNRG_DMA_TxCallback(void)
-{
-  __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG);
-  
-  switch (SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event)
-  {
-  case SPI_HEADER_TRANSMITTED:
-    if(SPI_Context.SPI_Transmit_Context.payload_size_to_transmit != 0)
-    {
-      SPI_Transmit_Manager(SPI_PAYLOAD_TRANSMIT);
-    }
-    else
-    {
-      TransmitClosure();
-    }
-    break;
-    
-  case SPI_PAYLOAD_TRANSMITTED:
-    if( (SPI_Context.SPI_Transmit_Context.packet_cont == TRUE) && (SPI_Context.SPI_Transmit_Context.payload_size != 0))
-    {
-      SPI_Context.SPI_Transmit_Context.payload_data += SPI_Context.SPI_Transmit_Context.payload_size_to_transmit;
-      DisableEnable_SPI_CS();
-      SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX);
-    }
-    else
-    {
-      TransmitClosure();
-    }
-    break;
-    
-  default:
-    break;
-  }
-  
-  return;
-}
-
-/**
- * @brief  Close the transmit mechanism after packet has been sent
- *         Wait for the event to come back
- * @param  None
- * @retval None
- */
-static void TransmitClosure(void)
-{ 
-  LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_LP_Stop);
-  SPI_Context.Spi_Peripheral_State = SPI_AVAILABLE;
-  Disable_SPI_CS();
-  /*
-   *  Disable both DMA
-   */
-  __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
-  __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
-  Enable_SPI_Receiving_Path();
-  
-  return;
-}
-
-/**
- * @brief  Manage the SPI transmit
- * @param  TransmitRequest: the transmit request
- * @retval None
- */
-static void SPI_Transmit_Manager(SPI_TRANSMIT_REQUEST_t TransmitRequest)
-{
-  /*
-   *  Disable both DMA
-   */
-  __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
-  __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
-  
-  __HAL_DMA_DISABLE_IT(SPI_Context.hspi->hdmarx, DMA_IT_TC); /**< Disable Receive packet notification */
-  
-  __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG); /**< Clear flag in DMA */
-	HAL_NVIC_ClearPendingIRQ(BNRG_SPI_DMA_TX_IRQn); /**< Clear DMA pending bit in NVIC */
-  __HAL_DMA_ENABLE_IT(SPI_Context.hspi->hdmatx, DMA_IT_TC);	/**< Enable Transmit packet notification */
-  
-  __HAL_BLUENRG_DMA_SET_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send Tx packet */
-  
-  switch (TransmitRequest)
-  {
-  case SPI_HEADER_TRANSMIT:
-    SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event = SPI_HEADER_TRANSMITTED;
-    
-#ifdef ENABLE_SPI_FIX
-    set_irq_as_input();
-#endif
-    
-    __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, SPI_Context.SPI_Transmit_Context.header_size); /**< Set counter in DMA TX */
-    __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)SPI_Context.SPI_Transmit_Context.header_data); /**< Set memory address in DMA TX */
-    break;
-    
-  case SPI_PAYLOAD_TRANSMIT:
-    SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event = SPI_PAYLOAD_TRANSMITTED;
-    
-    __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, SPI_Context.SPI_Transmit_Context.payload_size_to_transmit); /**< Set counter in DMA TX */
-    __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)SPI_Context.SPI_Transmit_Context.payload_data); /**< Set memory address in DMA TX */
-    break;
-    
-  default:
-    break;
-  }
-  
-  __HAL_DMA_ENABLE(SPI_Context.hspi->hdmatx); /**< Enable DMA TX */
-  
-}
-
-/**
- * @brief  Manage the SPI receive
- * @param  ReceiveRequest: the receive request
- * @retval None
- */
-static void SPI_Receive_Manager(SPI_RECEIVE_REQUEST_t ReceiveRequest)
-{
-  uint16_t byte_count;
-	uint8_t localloop;
-  
-  /*
-   *  Disable both DMA
-   */
-  __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
-  __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
-  
-  /**
-   * Flush the Rx register or FIFO
-   */
-  for (localloop = 0 ; localloop < SPI_FIFO_RX_DEPTH ; localloop++)
-  {
-    *(volatile uint8_t*)__HAL_BLUENRG_SPI_GET_RX_DATA_REGISTER_ADDRESS(SPI_Context.hspi);
-  }
-  
-  __HAL_DMA_ENABLE_IT(SPI_Context.hspi->hdmarx, DMA_IT_TC);	/**< Enable Receive packet notification */
-  __HAL_DMA_DISABLE_IT(SPI_Context.hspi->hdmatx, DMA_IT_TC); /**< Disable Transmit packet notification */
-  
-  switch (ReceiveRequest)
-  {
-  case SPI_REQUEST_VALID_HEADER_FOR_RX:
-    ReceiveHeader(SPI_CHECK_RECEIVED_HEADER_FOR_RX, (uint8_t *)Read_Header_CMD);
-    break;
-    
-  case SPI_REQUEST_VALID_HEADER_FOR_TX:
-    ReceiveHeader(SPI_CHECK_RECEIVED_HEADER_FOR_TX, (uint8_t *)Write_Header_CMD);
-    break;
-    
-  case SPI_REQUEST_PAYLOAD:
-    SPI_Context.SPI_Receive_Context.Spi_Receive_Event = SPI_RECEIVE_END;
-    
-    /*
-     * Check data to received is not available buffer size
-     */
-    byte_count = (Received_Header[4]<<8)|Received_Header[3];
-    if (byte_count > SPI_Context.SPI_Receive_Context.buffer_size)
-    {
-      byte_count = SPI_Context.SPI_Receive_Context.buffer_size;
-    }
-    SPI_Context.SPI_Receive_Context.payload_len = byte_count;
-    
-    __HAL_BLUENRG_DMA_CLEAR_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send same Byte */
-    
-    /*
-     *  Set counter in both DMA
-     */
-    __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmarx, byte_count);
-    __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, byte_count);
-    
-    /*
-     *  Set memory address in both DMA
-     */
-    __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmarx, (uint32_t)SPI_Context.SPI_Receive_Context.buffer);
-    __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)&dummy_bytes);
-    break;
-    
-  default:
-    break;
-  }
-  
-  /*
-   *  Enable both DMA - Rx First
-   */
-  __HAL_DMA_ENABLE(SPI_Context.hspi->hdmarx);
-  __HAL_DMA_ENABLE(SPI_Context.hspi->hdmatx);
-  
-  return;
-}
-
-/**
- * @brief Receive header
- * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
- *               the configuration information for SPI module.
- * @retval None
- */
-static void ReceiveHeader(SPI_RECEIVE_EVENT_t ReceiveEvent, uint8_t * DataHeader)
-{
-  SPI_Context.SPI_Receive_Context.Spi_Receive_Event = ReceiveEvent;
-  
-  __HAL_BLUENRG_DMA_SET_MINC(SPI_Context.hspi->hdmatx);	/**< Configure DMA to send Tx packet */
-  
-  /*
-   *  Set counter in both DMA
-   */
-  __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, HEADER_SIZE);
-  __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmarx, HEADER_SIZE);
-  
-  /*
-   *  Set memory address in both DMA
-   */
-  __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmarx, (uint32_t)Received_Header);
-  __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)DataHeader);
-  
-  return;
-}
-
-/**
- * @brief  BlueNRG SPI request event
- * @param  buffer: the event
- * @param  buff_size: the event size
- * @retval None
- */
-void BlueNRG_SPI_Request_Events(uint8_t *buffer, uint8_t buff_size)
-{
-  SPI_Context.SPI_Receive_Context.buffer = buffer;
-  SPI_Context.SPI_Receive_Context.buffer_size = buff_size;
-  
-  Enable_SPI_Receiving_Path();
-  
-  return;
-}
-
-/**
- * @brief  BlueNRG SPI IRQ Callback
- * @param  None
- * @retval None
- */
-void BlueNRG_SPI_IRQ_Callback(void)
-{  
-  __disable_irq();
-  if(SPI_Context.Spi_Peripheral_State == SPI_AVAILABLE)
-  {
-    SPI_Context.Spi_Peripheral_State = SPI_BUSY;
-    __enable_irq();
-    Enable_SPI_CS();
-    SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_RX);
-    LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_Sleep);
-  }
-  else
-  {
-    __enable_irq();
-  }
-}
-
-#endif /* __DMA_LP__ */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
- 
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- a/x-nucleo-idb0xa1/BlueNRGDevice.h	Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/BlueNRGDevice.h	Mon May 16 17:22:03 2016 +0200
@@ -76,7 +76,7 @@
     virtual const SecurityManager& getSecurityManager() const {
         return *sm;
     }
-    ble_error_t reset(void);
+    void reset(void);
     virtual bool hasInitialized(void) const {
         return isInitialized;
     }
--- a/x-nucleo-idb0xa1/BlueNRGDiscoveredCharacteristic.h	Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/BlueNRGDiscoveredCharacteristic.h	Mon May 16 17:22:03 2016 +0200
@@ -1,41 +1,43 @@
-/* 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);
-  
-  void setup(BlueNRGGattClient         *gattcIn,
-             Gap::Handle_t            connectionHandleIn,
-             UUID   uuidIn,
-             DiscoveredCharacteristic::Properties_t    propsIn,
-             GattAttribute::Handle_t  declHandleIn,
-             GattAttribute::Handle_t  valueHandleIn);
-};
-
-#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
+/* 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);
+};
+
+#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- a/x-nucleo-idb0xa1/BlueNRGGap.h	Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/BlueNRGGap.h	Mon May 16 17:22:03 2016 +0200
@@ -46,8 +46,8 @@
 #define BDADDR_SIZE 6
 
 #define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020)
-#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x00A0)
-#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x4000)
+#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)
@@ -59,8 +59,9 @@
 #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        (0x000C)
-#define CONN_L2        (0x000C)
+#define CONN_L1        (0x0008)
+#define CONN_L2        (0x0008)
+#define GUARD_INT      5 //msec
 
 #define LOCAL_NAME_MAX_SIZE 9 //8 + 1(AD_DATA_TYPE)
 #define UUID_BUFFER_SIZE 17 //Either 8*2(16-bit UUIDs) or 4*4(32-bit UUIDs) or 1*16(128-bit UUIDs) +1(AD_DATA_TYPE)
@@ -80,22 +81,13 @@
         return m_instance;
     }
 
-    // <<<ANDREA>>>
-    /*
-    enum AdvType_t {
-        ADV_IND           = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED,//Gap::ADV_IND,
-        ADV_DIRECT_IND    = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED,//Gap::ADV_DIRECT_IND,
-        ADV_SCAN_IND      = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED,//Gap::ADV_SCAN_IND,
-        ADV_NONCONN_IND   = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED//Gap::ADV_NONCONN_IND
-    };
-    */
     enum Reason_t {
         DEVICE_FOUND,
         DISCOVERY_COMPLETE
     };
     
     /* Functions that must be implemented from Gap */
-    /*virtual ble_error_t setAddress(addr_type_t type,   const Address_t address);*/
+    virtual ble_error_t setAddress(addr_type_t type,   const Address_t address);
     virtual ble_error_t getAddress(addr_type_t *typeP, Address_t address);
     virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &);
     virtual ble_error_t startAdvertising(const GapAdvertisingParams &);
@@ -114,19 +106,25 @@
     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 *);
-    // <<<ANDREA>>>
+
     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_type,
                                      uint8_t *addr,
                                      uint8_t *data_length,
                                      uint8_t *data,
@@ -156,6 +154,7 @@
     uint16_t m_connectionHandle;
     AddressType_t addr_type;
     Address_t _peerAddr;
+    AddressType_t _peerAddrType;
     uint8_t bdaddr[BDADDR_SIZE];
     bool _scanning;
     bool _connecting;
@@ -174,9 +173,29 @@
     Timeout advTimeout;
     bool AdvToFlag;
 
+    static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) {
+        return (duration * 625) / 1000;
+    }
+
+    uint16_t scanInterval;
+    uint16_t scanWindow;
+    uint16_t conn_min_interval;
+    uint16_t conn_max_interval;
+    void setConnectionParameters(void);
+
+    Gap::AdvertisingPolicyMode_t advertisingPolicyMode;
+    Gap::ScanningPolicyMode_t scanningPolicyMode;
+
+    Whitelist_t whitelistAddresses;
+
     BlueNRGGap() {
         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_FILTER_ALL_ADV;//Gap::SCAN_POLICY_IGNORE_WHITELIST;
+
         isSetAddress = false;
         memset(deviceAppearance, 0, sizeof(deviceAppearance));
     }
--- a/x-nucleo-idb0xa1/BlueNRGGattClient.h	Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/BlueNRGGattClient.h	Mon May 16 17:22:03 2016 +0200
@@ -1,162 +1,181 @@
-/* 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__
-
-#include "mbed-drivers/mbed.h"
-#include "ble/blecommon.h"
-#include "btle.h"
-#include "ble/GattClient.h"
-#include "ble/DiscoveredService.h"
-#include "BlueNRGDiscoveredCharacteristic.h"
-
-using namespace std;
-
-#define BLE_TOTAL_DISCOVERED_SERVICES 10
-#define BLE_TOTAL_DISCOVERED_CHARS 10
-
-class BlueNRGGattClient : public GattClient
-{
-public:
-    static BlueNRGGattClient &getInstance() {
-        static BlueNRGGattClient m_instance;
-        return m_instance;
-    }
-    
-    enum {
-      GATT_IDLE,
-      GATT_SERVICE_DISCOVERY,
-      GATT_CHARS_DISCOVERY_COMPLETE,
-      GATT_DISCOVERY_TERMINATED,
-            GATT_READ_CHAR,
-            GATT_WRITE_CHAR
-    };
-    
-    /* 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) {
-      terminationCallback = 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;
-    
-    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 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() {
-      _currentState = GATT_IDLE;
-      _matchingServiceUUID = BLE_UUID_UNKNOWN;
-      _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN;
-    }
-
-    ServiceDiscovery::ServiceCallback_t  serviceDiscoveryCallback;
-    ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback;
-    ServiceDiscovery::TerminationCallback_t terminationCallback;
-
-private:
-
-  BlueNRGGattClient(BlueNRGGattClient const &);
-  void operator=(BlueNRGGattClient const &);
-
-  Gap::Handle_t _connectionHandle;
-  DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES];
-  BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS];
-  
-  GattReadCallbackParams readCBParams;
-  GattWriteCallbackParams writeCBParams;
-  
-  UUID _matchingServiceUUID;
-  UUID _matchingCharacteristicUUIDIn;
-  uint8_t _currentState;
-  uint8_t _numServices, _servIndex;
-  uint8_t _numChars;
-  
-};
-
-#endif /* __BLUENRG_GATT_CLIENT_H__ */
+/* 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__
+
+#include "mbed-drivers/mbed.h"
+#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 BlueNRGGattClient : public GattClient
+{
+public:
+    static BlueNRGGattClient &getInstance() {
+        static BlueNRGGattClient m_instance;
+        return m_instance;
+    }
+    
+    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 */
+    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) {
+      terminationCallback = 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() {
+      _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:
+
+  BlueNRGGattClient(BlueNRGGattClient const &);
+  void operator=(BlueNRGGattClient const &);
+
+  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;
+  
+};
+
+#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- a/x-nucleo-idb0xa1/BlueNRGGattServer.h	Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/BlueNRGGattServer.h	Mon May 16 17:22:03 2016 +0200
@@ -29,9 +29,7 @@
   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
   *
   * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
-  */ 
-  
-// ANDREA: Changed some types (e.g., tHalUint8 --> uint8_t)
+  */
  
 #ifndef __BLUENRG_GATT_SERVER_H__
 #define __BLUENRG_GATT_SERVER_H__
@@ -46,11 +44,6 @@
 
 #define BLE_TOTAL_CHARACTERISTICS 10
 
-// If the char has handle 'x', then the value declaration will have the handle 'x+1'
-// If the char has handle 'x', then the char descriptor declaration will have the handle 'x+2'
-#define CHAR_VALUE_OFFSET 1
-#define CHAR_DESC_OFFSET 2
-
 using namespace std;
 
 class BlueNRGGattServer : public GattServer
@@ -68,7 +61,6 @@
     };
     
     /* Functions that must be implemented from GattServer */
-    // <<<ANDREA>>>
     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);
@@ -79,12 +71,13 @@
     virtual bool isOnDataReadAvailable() const {
         return true;
     }
-    // <<<ANDREA>>>
+
+    virtual ble_error_t reset(void);
     
     /* BlueNRG Functions */
     void eventCallback(void);
     //void hwCallback(void *pckt);
-    ble_error_t Read_Request_CB(uint16_t handle);
+    ble_error_t Read_Request_CB(uint16_t attributeHandle);
     GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle);
     void HCIDataWrittenEvent(const GattWriteCallbackParams *params);
     void HCIDataReadEvent(const GattReadCallbackParams *params);
@@ -97,7 +90,7 @@
     uint8_t characteristicCount;
     uint16_t servHandle, charHandle;
 
-    std::map<uint16_t, uint16_t> bleCharHanldeMap;  // 1st argument is characteristic, 2nd argument is service
+    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];
 
--- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_aci_const.h	Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_aci_const.h	Mon May 16 17:22:03 2016 +0200
@@ -25,6 +25,16 @@
 
 #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;
@@ -34,6 +44,12 @@
 
 #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;
--- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap_aci.h	Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap_aci.h	Mon May 16 17:22:03 2016 +0200
@@ -206,7 +206,14 @@
  * @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 Bluehci_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).
+ * 		  the default values for advertising intervals for IDB04A1 (1.28 s and 2.56 s respectively).
+ *        For IDB05A1:
+ *        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.
@@ -229,8 +236,8 @@
  *              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)/0.625,
- *                                                     (ADV_INTERVAL_MAX_MS*1000)/0.625,
+ *              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,
@@ -591,7 +598,7 @@
  *        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.
+ *        event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) and @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.
@@ -618,7 +625,7 @@
  * 		  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.
+ * 		  the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) and @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.
@@ -766,7 +773,7 @@
  * @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.
+ *        are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) and @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
@@ -805,7 +812,7 @@
  * @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. The upper layer then has to select one of the
+ * 		  event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) and @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.
@@ -894,7 +901,7 @@
 				     uint16_t max_conn_length);
 
 /**
- * @brief Terminate the specified GATT procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is
+ * @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.
--- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_aci.h	Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_aci.h	Mon May 16 17:22:03 2016 +0200
@@ -47,10 +47,13 @@
  *        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
@@ -227,7 +230,7 @@
 				      uint16_t charHandle,
 				      uint8_t charValOffset,
 				      uint8_t charValueLen,   
-				      const uint8_t *charValue);
+				      const void *charValue);
 /**
  * @brief Delete the specified characteristic from the service.
  * @param servHandle Handle of the service to which characteristic belongs
@@ -704,7 +707,7 @@
 				   uint16_t charDescHandle,
 				   uint16_t charDescValOffset,
 				   uint8_t charDescValueLen,
-				   const uint8_t *charDescValue);
+				   const void *charDescValue);
 
 /**
  * @brief Reads the value of the attribute handle specified from the local GATT database.
@@ -1035,6 +1038,28 @@
 } 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_IDB05A1   (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_IDB05A1 (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. */
+  uint16_t reserved; /**< Not used. */
+} PACKED evt_gatt_server_confirmation;
+
+/**
  * @}
  */
 
--- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_hal_aci.h	Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_hal_aci.h	Mon May 16 17:22:03 2016 +0200
@@ -43,6 +43,18 @@
                                     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).
@@ -63,6 +75,18 @@
 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,
@@ -119,6 +143,8 @@
  	 	 	 	 	 	 	 	 	 	 	 	 	 It can be written only if aci_hal_write_config_data() is the first command
  	 	 	 	 	 	 	 	 	 	 	 	 	 after reset. */
 
+#define CONFIG_DATA_RANDOM_ADDRESS_IDB05A1  (0x80) /**< Stored static random address. Read-only (IDB05A1 only) */
+
 /**
  * Select the BlueNRG roles and mode configurations.\n
  * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB)
--- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_l2cap_aci.h	Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_l2cap_aci.h	Mon May 16 17:22:03 2016 +0200
@@ -123,6 +123,10 @@
  * 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.
--- a/x-nucleo-idb0xa1/bluenrg-hci/hci.h	Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/hci.h	Mon May 16 17:22:03 2016 +0200
@@ -163,6 +163,8 @@
                              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);
--- a/x-nucleo-idb0xa1/bluenrg-hci/hci_const.h	Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/hci_const.h	Mon May 16 17:22:03 2016 +0200
@@ -14,7 +14,6 @@
 #include "hal_types.h"
 #include "clock.h"
 #include "link_layer.h"
-
 #include "hci.h"
 
 #define DEFAULT_TIMEOUT (CLOCK_SECOND/10)
@@ -287,7 +286,7 @@
   uint8_t  status;
   uint16_t handle;
   uint8_t  map[5];
-}  le_read_channel_map_rp;
+} PACKED le_read_channel_map_rp;
 #define LE_READ_CHANNEL_MAP_RP_SIZE 8
 
 #define OCF_LE_READ_REMOTE_USED_FEATURES	0x0016
--- a/x-nucleo-idb0xa1/platform/stm32_bluenrg_ble_dma_lp.h	Tue Apr 26 14:44:54 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32_bluenrg_ble_dma_lp.h
-  * @author  CL
-  * @version V1.0.0
-  * @date    04-July-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_DMA_LP_H
-#define __STM32_BLUENRG_BLE_DMA_LP_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif 
-
-/* Includes ------------------------------------------------------------------*/ 
-#ifdef USE_STM32F4XX_NUCLEO
-  #include "stm32f4xx_hal.h"
-  #include "stm32f4xx_nucleo.h"
-  #include "stm32f4xx_nucleo_bluenrg_dma_lp.h"
-  #include "stm32f4xx_hal_bluenrg_gpio.h"
-  #include "stm32f4xx_hal_bluenrg_spi.h"
-  #include "stm32f4xx_hal_bluenrg_dma.h"
-#endif /* USE_STM32F4XX_NUCLEO */
-   
-#ifdef USE_STM32L0XX_NUCLEO
-  #include "stm32l0xx_hal.h"
-  #include "stm32l0xx_nucleo.h"
-  #include "stm32l0xx_nucleo_bluenrg_dma_lp.h"
-  #include "stm32l0xx_hal_bluenrg_gpio.h"
-  #include "stm32l0xx_hal_bluenrg_spi.h"
-  #include "stm32l0xx_hal_bluenrg_dma.h"   
-#endif /* USE_STM32L0XX_NUCLEO */
-  
-#include "stm32xx_lpm.h"  
-#include "stm32xx_timerserver.h"
-
-/** @addtogroup BSP
- *  @{
- */
-
-/** @addtogroup X-NUCLEO-IDB04A1
- *  @{
- */
-
-/** @addtogroup STM32_BLUENRG_BLE_DMA_LP
- *  @{
- */
- 
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Exported_Constants 
- * @{
- */ 
- 
-#define	SPI_END_RECEIVE_FIX	1	/**< Need some delay after receiving an event to prevent dummy read */
-
- /**
-  * All timeout below are given in term of Ticks of the TimerServer.
-  * The tick of the timerserver depends on the LPO clock used as input and the
-  * prescaler of the wakeup timer.
-  * In order to get the most efficient implementation, the wakeuptimer prescaler should divide
-  * the input clock by 2
-  *
-  * The values below are based on the LSI clock @37Kz.
-  * For this, the tick is 54us
-  */
-#define SPI_FIX_TIMEOUT	                2  /**< 150 us - Note: 2 ticks result into more than 2*54us due to some inaccuracies and latencies */
-#define SPI_TX_TIMEOUT                  3  /**< Value to be tuned to prevent trying to send a command to BlueNRG if it is not yet woken up */
-#define	SPI_END_RECEIVE_FIX_TIMEOUT	    2
-#define	BLUENRG_HOLD_TIME_IN_RESET	    1
-#define	BLUENRG_HOLD_TIME_AFTER_RESET	93 /**< 5ms */
- 
-/**
- * When the SPI does not have any FIFO (STM32L0, etc...), this parameter should be set to 1
- * When the SPI does have a FIFO, this parameter shall be set to the size of the FIFO in bytes (STM32L4 = 4)
- */
-#define	SPI_FIFO_RX_DEPTH	1
-
-/**
- * @}
- */
- 
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Exported_Functions 
- * @{
- */
-// FIXME: add prototypes for BlueNRG here
-void BNRG_SPI_Close(void);
-void BNRG_SPI_Init(void);
-void BlueNRG_RST(void);
-void BlueNRG_SPI_Write(uint8_t* header_data,
-                       uint8_t* payload_data,
-                       uint8_t header_size,
-                       uint8_t payload_size);
-void BlueNRG_SPI_Request_Events(uint8_t *buffer, uint8_t buff_size);
-void BlueNRG_DMA_RxCallback(void);
-void BlueNRG_DMA_TxCallback(void);
-void BlueNRG_SPI_IRQ_Callback(void);
-void BNRG_MSP_SPI_Init(SPI_HandleTypeDef * hspi);
-
-/**
- * @}
- */
- 
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32_BLUENRG_BLE_DMA_LP_H */
- 
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-