Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:1eec8720727a, committed 2017-01-16
- Comitter:
- sog_yang
- Date:
- Mon Jan 16 14:16:03 2017 +0000
- Commit message:
- NQ62X BLE DOORCTL 4CH project init
Changed in this revision
diff -r 000000000000 -r 1eec8720727a .mbed --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.mbed Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,1 @@ +ROOT=.
diff -r 000000000000 -r 1eec8720727a .mbedignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.mbedignore Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,4 @@ +mbed-os/features/net/* +mbed-os/uvisor-mbed-lib/* +mbed-os/frameworks/* +mbed-os/features/mbedtls/*
diff -r 000000000000 -r 1eec8720727a img/connection.png Binary file img/connection.png has changed
diff -r 000000000000 -r 1eec8720727a img/discovery.png Binary file img/discovery.png has changed
diff -r 000000000000 -r 1eec8720727a img/notifications.png Binary file img/notifications.png has changed
diff -r 000000000000 -r 1eec8720727a img/register_to_notifications.png Binary file img/register_to_notifications.png has changed
diff -r 000000000000 -r 1eec8720727a img/scan_result.png Binary file img/scan_result.png has changed
diff -r 000000000000 -r 1eec8720727a img/start_scan.png Binary file img/start_scan.png has changed
diff -r 000000000000 -r 1eec8720727a mbed-os.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#532da7133f7d51db958eacb2b5f13e7cf7feb81f
diff -r 000000000000 -r 1eec8720727a mbed_app.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_app.json Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,13 @@
+{
+ "target_overrides": {
+ "K64F": {
+ "target.features_add": ["BLE"],
+ "target.extra_labels_add": ["ST_BLUENRG"],
+ "target.macros_add": ["IDB0XA1_D13_PATCH"]
+ },
+ "NUCLEO_F401RE": {
+ "target.features_add": ["BLE"],
+ "target.extra_labels_add": ["ST_BLUENRG"]
+ }
+ }
+}
diff -r 000000000000 -r 1eec8720727a module.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/module.json Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,16 @@
+{
+ "name": "ble-batterylevel",
+ "version": "0.0.1",
+ "description": "An example of creating and updating a simple GATT Service using the BLE_API",
+ "licenses": [
+ {
+ "url": "https://spdx.org/licenses/Apache-2.0",
+ "type": "Apache-2.0"
+ }
+ ],
+ "dependencies": {
+ "ble": "^2.0.0"
+ },
+ "targetDependencies": {},
+ "bin": "./source"
+}
diff -r 000000000000 -r 1eec8720727a readme.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/readme.md Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,68 @@ +This example creates and updates a standard Battery Level service containing a single +GATT characteristic. + +The [battery service transmits](https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml) a device's battery level in percentage, with 100% being a fully charged battery and 0% being a fully drained battery. + +Although the sample application runs on a BLE device, it doesn't show the device's real battery level (because that changes very slowly and will make for a dull example). Instead, it transmits a fake battery level that starts at 50% (half charged). Every half second, it increments the battery level, going in single increments until reaching 100% (as if the battery is charging). It then drops down to 20% to start incrementing again. + +# Running the application + +## Requirements + +The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : + +- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. + +- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Checking for success + +**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. + +1. Build the application and install it on your board as explained in the building instructions. +1. Open the BLE scanner on your phone. +1. Start a scan. + +  + + **figure 1** How to start scan using nRF Master Control Panel 4.0.5 + +1. Find your device; it should be named `BATTERY`. + +  + + **figure 2** Scan results using nRF Master Control Panel 4.0.5 + +1. Establish a connection with your device. + +  + + **figure 3** How to establish a connection using Master Control Panel 4.0.5 + +1. Discover the services and the characteristics on the device. The *Battery service* has the UUID 0x180F and includes the *Battery level* characteristic which has the UUID 0x2A19. + +  + + **figure 4** Representation of the Battery service using Master Control Panel 4.0.5 + +1. Register for the notifications sent by the *Battery level* characteristic. + +  + + **figure 5** How to register to notifications using Master Control Panel 4.0.5 + + +1. You should see the battery level value change every half second. It begins at 50, goes up to 100 (in steps of 1), resets to 20 and so on. + +  + + **figure 6** Notifications view using Master Control Panel 4.0.5 + +If you can see the characteristic, and if its value is incrementing correctly, the application is working properly. +
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG.lib Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/#a5d5d0b558395110a5c2edd398a167b1a70e7c99
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/.gitignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/.gitignore Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,9 @@ +# vim temporary files +*.sw* + +# yotta files +build +yotta_modules +yotta_targets +.yotta.json +upload.tar.gz
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/module.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/module.json Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,37 @@
+{
+ "name": "x-nucleo-idb0xa1",
+ "version": "2.0.3",
+ "description": "ST driver for the mbed BLE API.",
+ "keywords": [
+ "expansion",
+ "board",
+ "x-nucleo",
+ "nucleo",
+ "ST",
+ "STM",
+ "Bluetooth",
+ "BLE"
+ ],
+ "author": "Andrea Palmieri",
+ "repository": {
+ "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git",
+ "type": "git"
+ },
+ "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1",
+ "licenses": [
+ {
+ "url": "https://spdx.org/licenses/Apache-2.0",
+ "type": "Apache-2.0"
+ }
+ ],
+ "extraIncludes": [
+ "x-nucleo-idb0xa1",
+ "x-nucleo-idb0xa1/utils",
+ "x-nucleo-idb0xa1/platform",
+ "x-nucleo-idb0xa1/bluenrg-hci"
+ ],
+ "dependencies": {
+ "mbed-drivers": ">=0.11.3",
+ "ble": "^2.5.0"
+ }
+}
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,475 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/**
+ ******************************************************************************
+ * @file BlueNRGDevice.cpp
+ * @author STMicroelectronics
+ * @brief Implementation of BLEDeviceInstanceBase
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
+ */
+
+/** @defgroup BlueNRGDevice
+ * @brief BlueNRG BLE_API Device Adaptation
+ * @{
+ */
+
+#ifdef YOTTA_CFG_MBED_OS
+ #include "mbed-drivers/mbed.h"
+#else
+ #include "mbed.h"
+#endif
+#include "BlueNRGDevice.h"
+#include "BlueNRGGap.h"
+#include "BlueNRGGattServer.h"
+
+#include "btle.h"
+#include "ble_utils.h"
+#include "ble_osal.h"
+
+#include "ble_debug.h"
+#include "stm32_bluenrg_ble.h"
+
+extern "C" {
+ #include "ble_hci.h"
+ #include "bluenrg_utils.h"
+}
+
+#define HEADER_SIZE 5
+#define MAX_BUFFER_SIZE 255
+
+/**
+ * The singleton which represents the BlueNRG transport for the BLEDevice.
+ *
+ * See file 'x_nucleo_idb0xa1_targets.h' for details regarding the peripheral pins used!
+ */
+#include "x_nucleo_idb0xa1_targets.h"
+
+BlueNRGDevice bluenrgDeviceInstance(IDB0XA1_PIN_SPI_MOSI,
+ IDB0XA1_PIN_SPI_MISO,
+ IDB0XA1_PIN_SPI_SCK,
+ IDB0XA1_PIN_SPI_nCS,
+ IDB0XA1_PIN_SPI_RESET,
+ IDB0XA1_PIN_SPI_IRQ);
+
+/**
+* BLE-API requires an implementation of the following function in order to
+* obtain its transport handle.
+*/
+BLEInstanceBase *
+createBLEInstance(void)
+{
+ return (&bluenrgDeviceInstance);
+}
+
+/**************************************************************************/
+/**
+ @brief Constructor
+ * @param mosi mbed pin to use for MOSI line of SPI interface
+ * @param miso mbed pin to use for MISO line of SPI interface
+ * @param sck mbed pin to use for SCK line of SPI interface
+ * @param cs mbed pin to use for not chip select line of SPI interface
+ * @param rst mbed pin to use for BlueNRG reset
+ * @param irq mbed pin for BlueNRG IRQ
+*/
+/**************************************************************************/
+BlueNRGDevice::BlueNRGDevice(PinName mosi,
+ PinName miso,
+ PinName sck,
+ PinName cs,
+ PinName rst,
+ PinName irq) :
+ isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq)
+{
+ // Setup the spi for 8 bit data, low clock polarity,
+ // 1-edge phase, with an 8MHz clock rate
+ spi_.format(8, 0);
+ spi_.frequency(8000000);
+
+ // Deselect the BlueNRG chip by keeping its nCS signal high
+ nCS_ = 1;
+
+ wait_us(500);
+
+ // Prepare communication between the host and the BlueNRG SPI interface
+ HCI_Init();
+
+ // Set the interrupt handler for the device
+ irq_.mode(PullDown); // set irq mode
+ irq_.rise(&HCI_Isr);
+}
+
+/**************************************************************************/
+/**
+ @brief Destructor
+*/
+/**************************************************************************/
+BlueNRGDevice::~BlueNRGDevice(void)
+{
+}
+
+/**
+ * @brief Get BlueNRG HW version in bootloader mode
+ * @param hw_version The HW version is written to this parameter
+ * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise
+ */
+uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version)
+{
+ uint8_t status;
+
+ status = getBlueNRGUpdaterHWVersion(hw_version);
+
+ return (status);
+}
+
+/**
+ * @brief Flash a new firmware using internal bootloader.
+ * @param fw_image Pointer to the firmware image (raw binary data,
+ * little-endian).
+ * @param fw_size Size of the firmware image. The firmware image size shall
+ * be multiple of 4 bytes.
+ * @retval int It returns BLE_STATUS_SUCCESS on success, or a number
+ * not equal to 0 in case of error
+ * (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR)
+ */
+int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size)
+{
+ int status = program_device(fw_image, fw_size);
+
+ return (status);
+}
+
+
+/**
+ * @brief Initialises anything required to start using BLE
+ * @param[in] instanceID
+ * The ID of the instance to initialize.
+ * @param[in] callback
+ * A callback for when initialization completes for a BLE
+ * instance. This is an optional parameter set to NULL when not
+ * supplied.
+ *
+ * @return BLE_ERROR_NONE if the initialization procedure was started
+ * successfully.
+ */
+ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback)
+{
+ if (isInitialized) {
+ BLE::InitializationCompleteCallbackContext context = {
+ BLE::Instance(instanceID),
+ BLE_ERROR_ALREADY_INITIALIZED
+ };
+ callback.call(&context);
+ return BLE_ERROR_ALREADY_INITIALIZED;
+ }
+
+ // Init the BlueNRG/BlueNRG-MS stack
+ btleInit();
+
+ isInitialized = true;
+ BLE::InitializationCompleteCallbackContext context = {
+ BLE::Instance(instanceID),
+ BLE_ERROR_NONE
+ };
+ callback.call(&context);
+
+ return BLE_ERROR_NONE;
+}
+
+
+/**
+ @brief Resets the BLE HW, removing any existing services and
+ characteristics
+ @param[in] void
+ @returns void
+*/
+void BlueNRGDevice::reset(void)
+{
+ wait_us(500);
+
+ /* Reset BlueNRG SPI interface */
+ rst_ = 0;
+ wait_us(5);
+ rst_ = 1;
+ wait_us(5);
+
+ /* Wait for the radio to come back up */
+ wait_us(500);
+
+}
+
+/*!
+ @brief Wait for any BLE Event like BLE Connection, Read Request etc.
+ @param[in] void
+ @returns char *
+*/
+void BlueNRGDevice::waitForEvent(void)
+{
+ bool must_return = false;
+
+ do {
+ bluenrgDeviceInstance.processEvents();
+
+ if(must_return) return;
+
+ __WFE(); /* it is recommended that SEVONPEND in the
+ System Control Register is NOT set */
+ must_return = true; /* after returning from WFE we must guarantee
+ that conrol is given back to main loop before next WFE */
+ } while(true);
+
+}
+
+/*!
+ @brief get GAP version
+ @brief Get the BLE stack version information
+ @param[in] void
+ @returns char *
+ @returns char *
+*/
+const char *BlueNRGDevice::getVersion(void)
+{
+ return getVersionString();
+}
+
+/**************************************************************************/
+/*!
+ @brief get reference to GAP object
+ @param[in] void
+ @returns Gap&
+*/
+/**************************************************************************/
+Gap &BlueNRGDevice::getGap()
+{
+ return BlueNRGGap::getInstance();
+}
+
+const Gap &BlueNRGDevice::getGap() const
+{
+ return BlueNRGGap::getInstance();
+}
+
+/**************************************************************************/
+/*!
+ @brief get reference to GATT server object
+ @param[in] void
+ @returns GattServer&
+*/
+/**************************************************************************/
+GattServer &BlueNRGDevice::getGattServer()
+{
+ return BlueNRGGattServer::getInstance();
+}
+
+const GattServer &BlueNRGDevice::getGattServer() const
+{
+ return BlueNRGGattServer::getInstance();
+}
+
+/**************************************************************************/
+/*!
+ @brief shut down the BLE device
+ @param[out] error if any
+*/
+/**************************************************************************/
+ble_error_t BlueNRGDevice::shutdown(void) {
+ if (!isInitialized) {
+ return BLE_ERROR_INITIALIZATION_INCOMPLETE;
+ }
+
+ /* Reset the BlueNRG device first */
+ reset();
+
+ /* Shutdown the BLE API and BlueNRG glue code */
+ ble_error_t error;
+
+ /* GattServer instance */
+ error = BlueNRGGattServer::getInstance().reset();
+ if (error != BLE_ERROR_NONE) {
+ return error;
+ }
+
+ /* GattClient instance */
+ error = BlueNRGGattClient::getInstance().reset();
+ if (error != BLE_ERROR_NONE) {
+ return error;
+ }
+
+ /* Gap instance */
+ error = BlueNRGGap::getInstance().reset();
+ if (error != BLE_ERROR_NONE) {
+ return error;
+ }
+
+ isInitialized = false;
+
+ return BLE_ERROR_NONE;
+
+}
+
+/**
+ * @brief Reads from BlueNRG SPI buffer and store data into local buffer.
+ * @param buffer : Buffer where data from SPI are stored
+ * @param buff_size: Buffer size
+ * @retval int32_t : Number of read bytes
+ */
+int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size)
+{
+ uint16_t byte_count;
+ uint8_t len = 0;
+ uint8_t char_ff = 0xff;
+ volatile uint8_t read_char;
+
+ uint8_t i = 0;
+ volatile uint8_t tmpreg;
+
+ uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00};
+ uint8_t header_slave[HEADER_SIZE];
+
+ /* Select the chip */
+ nCS_ = 0;
+
+ /* Read the header */
+ for (i = 0; i < 5; i++)
+ {
+ tmpreg = spi_.write(header_master[i]);
+ header_slave[i] = (uint8_t)(tmpreg);
+ }
+
+ if (header_slave[0] == 0x02) {
+ /* device is ready */
+ byte_count = (header_slave[4]<<8)|header_slave[3];
+
+ if (byte_count > 0) {
+
+ /* avoid to read more data that size of the buffer */
+ if (byte_count > buff_size){
+ byte_count = buff_size;
+ }
+
+ for (len = 0; len < byte_count; len++){
+ read_char = spi_.write(char_ff);
+ buffer[len] = read_char;
+ }
+ }
+ }
+ /* Release CS line to deselect the chip */
+ nCS_ = 1;
+
+ // Add a small delay to give time to the BlueNRG to set the IRQ pin low
+ // to avoid a useless SPI read at the end of the transaction
+ for(volatile int i = 0; i < 2; i++)__NOP();
+
+#ifdef PRINT_CSV_FORMAT
+ if (len > 0) {
+ print_csv_time();
+ for (int i=0; i<len; i++) {
+ PRINT_CSV(" %02x", buffer[i]);
+ }
+ PRINT_CSV("\n");
+ }
+#endif
+
+ return len;
+}
+
+/**
+ * @brief Writes data from local buffer to SPI.
+ * @param data1 : First data buffer to be written
+ * @param data2 : Second data buffer to be written
+ * @param Nb_bytes1: Size of first data buffer to be written
+ * @param Nb_bytes2: Size of second data buffer to be written
+ * @retval Number of read bytes
+ */
+int32_t BlueNRGDevice::spiWrite(uint8_t* data1,
+ uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2)
+{
+ int32_t result = 0;
+ uint32_t i;
+ volatile uint8_t tmpreg;
+
+ unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00};
+ unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00};
+
+ disable_irq();
+
+ /* CS reset */
+ nCS_ = 0;
+
+ /* Exchange header */
+ for (i = 0; i < 5; i++)
+ {
+ tmpreg = spi_.write(header_master[i]);
+ header_slave[i] = tmpreg;
+ }
+
+ if (header_slave[0] == 0x02) {
+ /* SPI is ready */
+ if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) {
+
+ /* Buffer is big enough */
+ for (i = 0; i < Nb_bytes1; i++) {
+ spi_.write(*(data1 + i));
+ }
+ for (i = 0; i < Nb_bytes2; i++) {
+ spi_.write(*(data2 + i));
+ }
+ } else {
+ /* Buffer is too small */
+ result = -2;
+ }
+ } else {
+ /* SPI is not ready */
+ result = -1;
+ }
+
+ /* Release CS line */
+ //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
+ nCS_ = 1;
+
+ enable_irq();
+
+ return result;
+}
+
+bool BlueNRGDevice::dataPresent()
+{
+ return (irq_ == 1);
+}
+
+void BlueNRGDevice::disable_irq()
+{
+ irq_.disable_irq();
+}
+
+void BlueNRGDevice::enable_irq()
+{
+ irq_.enable_irq();
+}
+
+void BlueNRGDevice::processEvents() {
+ btle_handler();
+}
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,68 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BlueNRGDiscoveredCharacteristic.h"
+#include "BlueNRGGattClient.h"
+
+void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ DiscoveredCharacteristic::Properties_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn,
+ GattAttribute::Handle_t lastHandleIn)
+{
+ gattc = gattcIn;
+ connHandle = connectionHandleIn;
+ declHandle = declHandleIn;
+ valueHandle = valueHandleIn;
+ lastHandle = lastHandleIn;
+
+ props._broadcast = propsIn.broadcast();
+ props._read = propsIn.read();
+ props._writeWoResp = propsIn.writeWoResp();
+ props._write = propsIn.write();
+ props._notify = propsIn.notify();
+ props._indicate = propsIn.indicate();
+ props._authSignedWrite = propsIn.authSignedWrite();
+}
+
+void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ UUID uuidIn,
+ DiscoveredCharacteristic::Properties_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn,
+ GattAttribute::Handle_t lastHandleIn)
+{
+ gattc = gattcIn;
+ connHandle = connectionHandleIn;
+ uuid = uuidIn;
+ declHandle = declHandleIn;
+ valueHandle = valueHandleIn;
+ lastHandle = lastHandleIn;
+
+ props._broadcast = propsIn.broadcast();
+ props._read = propsIn.read();
+ props._writeWoResp = propsIn.writeWoResp();
+ props._write = propsIn.write();
+ props._notify = propsIn.notify();
+ props._indicate = propsIn.indicate();
+ props._authSignedWrite = propsIn.authSignedWrite();
+}
+
+ void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) {
+ lastHandle = lastHandleIn;
+ }
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,1447 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/**
+ ******************************************************************************
+ * @file BlueNRGGap.cpp
+ * @author STMicroelectronics
+ * @brief Implementation of BLE_API Gap Class
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
+ */
+
+/** @defgroup BlueNRGGap
+ * @brief BlueNRG BLE_API GAP Adaptation
+ * @{
+ */
+
+#include "BlueNRGDevice.h"
+#ifdef YOTTA_CFG_MBED_OS
+ #include "mbed-drivers/mbed.h"
+#else
+ #include "mbed.h"
+#endif
+#include "ble_payload.h"
+#include "ble_utils.h"
+#include "ble_debug.h"
+
+/*
+ * Utility to process GAP specific events (e.g., Advertising timeout)
+ */
+void BlueNRGGap::Process(void)
+{
+ if(AdvToFlag) {
+ stopAdvertising();
+ }
+
+}
+
+/**************************************************************************/
+/*!
+ @brief Sets the advertising parameters and payload for the device.
+ Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API
+
+ @params[in] advData
+ The primary advertising data payload
+ @params[in] scanResponse
+ The optional Scan Response payload if the advertising
+ type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
+ in \ref GapAdveritinngParams
+
+ @returns \ref ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @retval BLE_ERROR_BUFFER_OVERFLOW
+ The proposed action would cause a buffer overflow. All
+ advertising payloads must be <= 31 bytes, for example.
+
+ @retval BLE_ERROR_NOT_IMPLEMENTED
+ A feature was requested that is not yet supported in the
+ nRF51 firmware or hardware.
+
+ @retval BLE_ERROR_PARAM_OUT_OF_RANGE
+ One of the proposed values is outside the valid range.
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
+{
+ PRINTF("BlueNRGGap::setAdvertisingData\n\r");
+ /* Make sure we don't exceed the advertising payload length */
+ if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
+ PRINTF("Exceeded the advertising payload length\n\r");
+ return BLE_ERROR_BUFFER_OVERFLOW;
+ }
+
+ /* Make sure we have a payload! */
+ if (advData.getPayloadLen() != 0) {
+ PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen());
+
+ /* Align the GAP Service Appearance Char value coherently
+ This setting is duplicate (see below GapAdvertisingData::APPEARANCE)
+ since BLE API has an overloaded function for appearance
+ */
+ STORE_LE_16(deviceAppearance, advData.getAppearance());
+ setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]));
+
+
+ for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) {
+ loadPtr.getUnitAtIndex(index);
+
+ PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr()));
+ PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()));
+
+ switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) {
+ /**< TX Power Level (in dBm) */
+ case GapAdvertisingData::TX_POWER_LEVEL:
+ {
+ PRINTF("Advertising type: TX_POWER_LEVEL\n\r");
+ int8_t enHighPower = 0;
+ int8_t paLevel = 0;
+
+ int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr();
+ tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel);
+#ifdef DEBUG
+ PRINTF("dbm=%d, ret=%d\n\r", dbm, ret);
+ PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);
+#endif
+ if(ret == BLE_STATUS_SUCCESS) {
+ aci_hal_set_tx_power_level(enHighPower, paLevel);
+ }
+ break;
+ }
+ /**< Appearance */
+ case GapAdvertisingData::APPEARANCE:
+ {
+ PRINTF("Advertising type: APPEARANCE\n\r");
+
+ GapAdvertisingData::Appearance appearanceP;
+ memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2);
+
+ PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]);
+
+ appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]);
+ /* Align the GAP Service Appearance Char value coherently */
+ setAppearance(appearanceP);
+ break;
+ }
+
+ } // end switch
+
+ } //end for
+
+ }
+
+ // update the advertising data in the shield if advertising is running
+ if (state.advertising == 1) {
+ tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload());
+
+ if(BLE_STATUS_SUCCESS != ret) {
+ PRINTF(" error while setting scan response data (ret=0x%x)\n", ret);
+ switch (ret) {
+ case BLE_STATUS_TIMEOUT:
+ return BLE_STACK_BUSY;
+ default:
+ return BLE_ERROR_UNSPECIFIED;
+ }
+ }
+
+ ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload());
+ if (ret) {
+ PRINTF("error while setting the payload\r\n");
+ return BLE_ERROR_UNSPECIFIED;
+ }
+ }
+
+ _advData = advData;
+ _scanResponse = scanResponse;
+
+ return BLE_ERROR_NONE;
+}
+
+/*
+ * Utility to set ADV timeout flag
+ */
+void BlueNRGGap::setAdvToFlag(void) {
+ AdvToFlag = true;
+}
+
+/*
+ * ADV timeout callback
+ */
+#ifdef AST_FOR_MBED_OS
+static void advTimeoutCB(void)
+{
+ Gap::GapState_t state;
+
+ state = BlueNRGGap::getInstance().getState();
+ if (state.advertising == 1) {
+
+ BlueNRGGap::getInstance().stopAdvertising();
+
+ }
+}
+#else
+static void advTimeoutCB(void)
+{
+ Gap::GapState_t state;
+
+ state = BlueNRGGap::getInstance().getState();
+ if (state.advertising == 1) {
+
+ BlueNRGGap::getInstance().setAdvToFlag();
+
+ Timeout t = BlueNRGGap::getInstance().getAdvTimeout();
+ t.detach(); /* disable the callback from the timeout */
+
+ }
+}
+#endif /* AST_FOR_MBED_OS */
+
+/**************************************************************************/
+/*!
+ @brief Starts the BLE HW, initialising any services that were
+ added before this function was called.
+
+ @param[in] params
+ Basic advertising details, including the advertising
+ delay, timeout and how the device should be advertised
+
+ @note All services must be added before calling this function!
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+
+ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms)
+{
+ tBleStatus ret;
+ int err;
+
+ /* Make sure we support the advertising type */
+ if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
+ /* ToDo: This requires a proper security implementation, etc. */
+ return BLE_ERROR_NOT_IMPLEMENTED;
+ }
+
+ /* Check interval range */
+ if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
+ /* Min delay is slightly longer for unconnectable devices */
+ if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
+ (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+ } else {
+ if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
+ (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+ }
+
+ /* Check timeout is zero for Connectable Directed */
+ if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
+ /* Timeout must be 0 with this type, although we'll never get here */
+ /* since this isn't implemented yet anyway */
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ /* Check timeout for other advertising types */
+ if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
+ (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ /*
+ * Advertising filter policy setting
+ * FIXME: the Security Manager should be implemented
+ */
+ AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode();
+ if(mode != ADV_POLICY_IGNORE_WHITELIST) {
+ ret = aci_gap_configure_whitelist();
+ if(ret != BLE_STATUS_SUCCESS) {
+ PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret);
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ }
+ }
+
+ uint8_t advFilterPolicy = NO_WHITE_LIST_USE;
+ switch(mode) {
+ case ADV_POLICY_FILTER_SCAN_REQS:
+ advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN;
+ break;
+ case ADV_POLICY_FILTER_CONN_REQS:
+ advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN;
+ break;
+ case ADV_POLICY_FILTER_ALL_REQS:
+ advFilterPolicy = WHITE_LIST_FOR_ALL;
+ break;
+ default:
+ advFilterPolicy = NO_WHITE_LIST_USE;
+ break;
+ }
+
+ /* Check the ADV type before setting scan response data */
+ if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED ||
+ params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) {
+
+ /* set scan response data */
+ PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen());
+ ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload());
+
+ if(BLE_STATUS_SUCCESS!=ret) {
+ PRINTF(" error while setting scan response data (ret=0x%x)\n", ret);
+ switch (ret) {
+ case BLE_STATUS_TIMEOUT:
+ return BLE_STACK_BUSY;
+ default:
+ return BLE_ERROR_UNSPECIFIED;
+ }
+ }
+ } else {
+ hci_le_set_scan_resp_data(0, NULL);
+ }
+
+ setAdvParameters();
+ PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType());
+
+ err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload());
+
+ if (err) {
+ PRINTF("error while setting the payload\r\n");
+ return BLE_ERROR_UNSPECIFIED;
+ }
+
+ tBDAddr dummy_addr = { 0 };
+ uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval;
+ uint16_t advIntervalMax = advIntervalMin + 1;
+
+ err = hci_le_set_advertising_parameters(
+ advIntervalMin,
+ advIntervalMax,
+ params.getAdvertisingType(),
+ addr_type,
+ 0x00,
+ dummy_addr,
+ /* all channels */ 7,
+ advFilterPolicy
+ );
+
+ if (err) {
+ PRINTF("impossible to set advertising parameters\n\r");
+ PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1);
+ PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy);
+ return BLE_ERROR_INVALID_PARAM;
+ }
+
+ err = hci_le_set_advertise_enable(0x01);
+ if (err) {
+ PRINTF("impossible to start advertising\n\r");
+ return BLE_ERROR_UNSPECIFIED;
+ }
+
+ state.advertising = 1;
+
+ AdvToFlag = false;
+ if(params.getTimeout() != 0) {
+ PRINTF("!!! attaching to!!!\n");
+#ifdef AST_FOR_MBED_OS
+ minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000));
+#else
+ advTimeout.attach(advTimeoutCB, params.getTimeout() * 1000);
+#endif
+ }
+
+ return BLE_ERROR_NONE;
+
+}
+
+
+/**************************************************************************/
+/*!
+ @brief Stops the BLE HW and disconnects from any devices
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::stopAdvertising(void)
+{
+
+ if(state.advertising == 1) {
+
+ int err = hci_le_set_advertise_enable(0);
+ if (err) {
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ }
+
+ PRINTF("Advertisement stopped!!\n\r") ;
+ //Set GapState_t::advertising state
+ state.advertising = 0;
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Disconnects if we are connected to a central device
+
+ @param[in] reason
+ Disconnection Reason
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason)
+{
+ tBleStatus ret;
+
+ ret = aci_gap_terminate(connectionHandle, reason);
+
+ if (BLE_STATUS_SUCCESS != ret){
+ PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ;
+ switch (ret) {
+ case ERR_COMMAND_DISALLOWED:
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ case BLE_STATUS_TIMEOUT:
+ return BLE_STACK_BUSY;
+ default:
+ return BLE_ERROR_UNSPECIFIED;
+ }
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Disconnects if we are connected to a central device
+
+ @param[in] reason
+ Disconnection Reason
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason)
+{
+ return disconnect(m_connectionHandle, reason);
+}
+
+/**************************************************************************/
+/*!
+ @brief Sets the 16-bit connection handle
+
+ @param[in] conn_handle
+ Connection Handle which is set in the Gap Instance
+
+ @returns void
+*/
+/**************************************************************************/
+void BlueNRGGap::setConnectionHandle(uint16_t conn_handle)
+{
+ m_connectionHandle = conn_handle;
+}
+
+/**************************************************************************/
+/*!
+ @brief Gets the 16-bit connection handle
+
+ @param[in] void
+
+ @returns uint16_t
+ Connection Handle of the Gap Instance
+*/
+/**************************************************************************/
+uint16_t BlueNRGGap::getConnectionHandle(void)
+{
+ return m_connectionHandle;
+}
+
+/**************************************************************************/
+/*!
+ @brief Sets the BLE device address. SetAddress will reset the BLE
+ device and re-initialize BTLE. Will not start advertising.
+
+ @param[in] type
+ Type of Address
+
+ @param[in] address[6]
+ Value of the Address to be set
+
+ @returns ble_error_t
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address)
+{
+ if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ if(type == BLEProtocol::AddressType::PUBLIC){
+ tBleStatus ret = aci_hal_write_config_data(
+ CONFIG_DATA_PUBADDR_OFFSET,
+ CONFIG_DATA_PUBADDR_LEN,
+ address
+ );
+ if(ret != BLE_STATUS_SUCCESS) {
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ }
+ } else if (type == BLEProtocol::AddressType::RANDOM_STATIC) {
+ // ensure that the random static address is well formed
+ if ((address[5] & 0xC0) != 0xC0) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ // thanks to const correctness of the API ...
+ tBDAddr random_address = { 0 };
+ memcpy(random_address, address, sizeof(random_address));
+ int err = hci_le_set_random_address(random_address);
+ if (err) {
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ }
+
+ // It is not possible to get the bluetooth address when it is set
+ // store it locally in class data member
+ memcpy(bdaddr, address, sizeof(bdaddr));
+ } else {
+ // FIXME random addresses are not supported yet
+ // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE
+ // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE
+ return BLE_ERROR_NOT_IMPLEMENTED;
+ }
+
+ // if we're here then the address was correctly set
+ // commit it inside the addr_type
+ addr_type = type;
+ isSetAddress = true;
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Returns boolean if the address of the device has been set
+ or not
+
+ @returns bool
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+bool BlueNRGGap::getIsSetAddress()
+{
+ return isSetAddress;
+}
+
+/**************************************************************************/
+/*!
+ @brief Returns the address of the device if set
+
+ @returns Pointer to the address if Address is set else NULL
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address)
+{
+ uint8_t bdaddr[BDADDR_SIZE];
+ uint8_t data_len_out;
+
+ // precondition, check that pointers in input are valid
+ if (typeP == NULL || address == NULL) {
+ return BLE_ERROR_INVALID_PARAM;
+ }
+
+ if (addr_type == BLEProtocol::AddressType::PUBLIC) {
+ tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr);
+ if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) {
+ return BLE_ERROR_UNSPECIFIED;
+ }
+ } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) {
+ // FIXME hci_read_bd_addr and
+ // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1
+ // does not work, use the address stored in class data member
+ memcpy(bdaddr, this->bdaddr, sizeof(bdaddr));
+ } else {
+ // FIXME: should be implemented with privacy features
+ // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE
+ // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE
+ return BLE_ERROR_NOT_IMPLEMENTED;
+ }
+
+ *typeP = addr_type;
+ memcpy(address, bdaddr, BDADDR_SIZE);
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief obtains preferred connection params
+
+ @returns ble_error_t
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params)
+{
+ static const size_t parameter_size = 2;
+
+ if (!g_preferred_connection_parameters_char_handle) {
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ }
+
+ // Peripheral preferred connection parameters are an array of 4 uint16_t
+ uint8_t parameters_packed[parameter_size * 4];
+ uint16_t bytes_read = 0;
+
+ tBleStatus err = aci_gatt_read_handle_value(
+ g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE,
+ sizeof(parameters_packed),
+ &bytes_read,
+ parameters_packed
+ );
+
+ PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read);
+
+ // check that the read succeed and the result have the expected length
+ if (err || bytes_read != sizeof(parameters_packed)) {
+ return BLE_ERROR_UNSPECIFIED;
+ }
+
+ // memcpy field by field
+ memcpy(¶ms->minConnectionInterval, parameters_packed, parameter_size);
+ memcpy(¶ms->maxConnectionInterval, ¶meters_packed[parameter_size], parameter_size);
+ memcpy(¶ms->slaveLatency, ¶meters_packed[2 * parameter_size], parameter_size);
+ memcpy(¶ms->connectionSupervisionTimeout, ¶meters_packed[3 * parameter_size], parameter_size);
+
+ return BLE_ERROR_NONE;
+}
+
+
+/**************************************************************************/
+/*!
+ @brief sets preferred connection params
+
+ @returns ble_error_t
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params)
+{
+ static const size_t parameter_size = 2;
+ uint8_t parameters_packed[parameter_size * 4];
+
+ // ensure that parameters are correct
+ // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C]
+ // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC
+ if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) &&
+ params->minConnectionInterval != 0xFFFF) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) &&
+ params->maxConnectionInterval != 0xFFFF) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ if (params->slaveLatency > 0x01F3) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) &&
+ params->connectionSupervisionTimeout != 0xFFFF) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ // copy the parameters inside the byte array
+ memcpy(parameters_packed, ¶ms->minConnectionInterval, parameter_size);
+ memcpy(¶meters_packed[parameter_size], ¶ms->maxConnectionInterval, parameter_size);
+ memcpy(¶meters_packed[2 * parameter_size], ¶ms->slaveLatency, parameter_size);
+ memcpy(¶meters_packed[3 * parameter_size], ¶ms->connectionSupervisionTimeout, parameter_size);
+
+ tBleStatus err = aci_gatt_update_char_value(
+ g_gap_service_handle,
+ g_preferred_connection_parameters_char_handle,
+ /* offset */ 0,
+ sizeof(parameters_packed),
+ parameters_packed
+ );
+
+ if (err) {
+ PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ;
+ switch (err) {
+ case BLE_STATUS_INVALID_HANDLE:
+ case BLE_STATUS_INVALID_PARAMETER:
+ return BLE_ERROR_INVALID_PARAM;
+ case BLE_STATUS_INSUFFICIENT_RESOURCES:
+ return BLE_ERROR_NO_MEM;
+ case BLE_STATUS_TIMEOUT:
+ return BLE_STACK_BUSY;
+ default:
+ return BLE_ERROR_UNSPECIFIED;
+ }
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief updates preferred connection params
+
+ @returns ble_error_t
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params)
+{
+ tBleStatus ret = BLE_STATUS_SUCCESS;
+
+ if(gapRole == Gap::CENTRAL) {
+ ret = aci_gap_start_connection_update(handle,
+ params->minConnectionInterval,
+ params->maxConnectionInterval,
+ params->slaveLatency,
+ params->connectionSupervisionTimeout,
+ CONN_L1, CONN_L2);
+ } else {
+ ret = aci_l2cap_connection_parameter_update_request(handle,
+ params->minConnectionInterval,
+ params->maxConnectionInterval,
+ params->slaveLatency,
+ params->connectionSupervisionTimeout);
+ }
+
+ if (BLE_STATUS_SUCCESS != ret){
+ PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ;
+ switch (ret) {
+ case ERR_INVALID_HCI_CMD_PARAMS:
+ case BLE_STATUS_INVALID_PARAMETER:
+ return BLE_ERROR_INVALID_PARAM;
+ case ERR_COMMAND_DISALLOWED:
+ case BLE_STATUS_NOT_ALLOWED:
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ default:
+ return BLE_ERROR_UNSPECIFIED;
+ }
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Sets the Device Name Characteristic
+
+ @param[in] deviceName
+ pointer to device name to be set
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName)
+{
+ tBleStatus ret;
+ uint8_t nameLen = 0;
+
+ nameLen = strlen((const char*)deviceName);
+ PRINTF("DeviceName Size=%d\n\r", nameLen);
+
+ ret = aci_gatt_update_char_value(g_gap_service_handle,
+ g_device_name_char_handle,
+ 0,
+ nameLen,
+ deviceName);
+
+ if (BLE_STATUS_SUCCESS != ret){
+ PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ;
+ switch (ret) {
+ case BLE_STATUS_INVALID_HANDLE:
+ case BLE_STATUS_INVALID_PARAMETER:
+ return BLE_ERROR_INVALID_PARAM;
+ case BLE_STATUS_INSUFFICIENT_RESOURCES:
+ return BLE_ERROR_NO_MEM;
+ case BLE_STATUS_TIMEOUT:
+ return BLE_STACK_BUSY;
+ default:
+ return BLE_ERROR_UNSPECIFIED;
+ }
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Gets the Device Name Characteristic
+
+ @param[in] deviceName
+ pointer to device name
+
+ @param[in] lengthP
+ pointer to device name length
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
+{
+ tBleStatus ret;
+
+ ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
+ *lengthP,
+ (uint16_t *)lengthP,
+ deviceName);
+ PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP);
+ if (ret == BLE_STATUS_SUCCESS) {
+ return BLE_ERROR_NONE;
+ } else {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief Sets the Device Appearance Characteristic
+
+ @param[in] appearance
+ device appearance
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance)
+{
+ tBleStatus ret;
+ uint8_t deviceAppearance[2];
+
+ STORE_LE_16(deviceAppearance, appearance);
+ PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]);
+
+ ret = aci_gatt_update_char_value(g_gap_service_handle,
+ g_appearance_char_handle,
+ 0, 2, (uint8_t *)deviceAppearance);
+ if (BLE_STATUS_SUCCESS == ret){
+ return BLE_ERROR_NONE;
+ }
+
+ PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret);
+ switch (ret) {
+ case BLE_STATUS_INVALID_HANDLE:
+ case BLE_STATUS_INVALID_PARAMETER:
+ return BLE_ERROR_INVALID_PARAM;
+ case BLE_STATUS_INSUFFICIENT_RESOURCES:
+ return BLE_ERROR_NO_MEM;
+ case BLE_STATUS_TIMEOUT:
+ return BLE_STACK_BUSY;
+ default:
+ return BLE_ERROR_UNSPECIFIED;
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief Gets the Device Appearance Characteristic
+
+ @param[in] appearance
+ pointer to device appearance value
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
+{
+ tBleStatus ret;
+ uint16_t lengthP = 2;
+
+ ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
+ lengthP,
+ &lengthP,
+ (uint8_t*)appearanceP);
+ PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP);
+ if (ret == BLE_STATUS_SUCCESS) {
+ return BLE_ERROR_NONE;
+ } else {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+}
+
+GapScanningParams* BlueNRGGap::getScanningParams(void)
+{
+ return &_scanningParams;
+}
+
+static void makeConnection(void)
+{
+ BlueNRGGap::getInstance().createConnection();
+}
+
+void BlueNRGGap::Discovery_CB(Reason_t reason,
+ uint8_t adv_type,
+ uint8_t addr_type,
+ uint8_t *addr,
+ uint8_t *data_length,
+ uint8_t *data,
+ uint8_t *RSSI)
+{
+ switch (reason) {
+ case DEVICE_FOUND:
+ {
+ GapAdvertisingParams::AdvertisingType_t type;
+ bool isScanResponse = false;
+
+ /*
+ * Whitelisting (scan policy):
+ * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) &&
+ * Private Random Address
+ * => scan_results = FALSE
+ * FIXME: the Security Manager should be implemented
+ */
+ ScanningPolicyMode_t mode = getScanningPolicyMode();
+ PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type);
+ if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV ||
+ (addr_type == RESOLVABLE_PRIVATE_ADDR ||
+ addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) {
+ return;
+ }
+
+ switch(adv_type) {
+ case ADV_IND:
+ type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
+ break;
+ case ADV_DIRECT_IND:
+ type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED;
+ break;
+ case ADV_SCAN_IND:
+ case SCAN_RSP:
+ type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED;
+ isScanResponse = true;
+ break;
+ case ADV_NONCONN_IND:
+ type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED;
+ break;
+ default:
+ type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
+ }
+
+ PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n",
+ *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
+ if(!_connecting) {
+ processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data);
+ }
+ PRINTF("!!!After processAdvertisementReport\n\r");
+ }
+ break;
+
+ case DISCOVERY_COMPLETE:
+ // The discovery is complete. If this is due to a stop scanning (i.e., the device
+ // we are interested in has been found) and a connection has been requested
+ // then we start the device connection.
+ PRINTF("DISCOVERY_COMPLETE\n\r");
+ _scanning = false;
+
+ // Since the DISCOVERY_COMPLETE event can be received during the scanning interval,
+ // we need to delay the starting of connection
+ uint16_t delay = 2*(_scanningParams.getInterval());
+
+#ifdef AST_FOR_MBED_OS
+ if(_connecting) {
+ minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay));
+ }
+#else
+ Clock_Wait(delay);
+ if(_connecting) {
+ makeConnection();
+ }
+#endif /* AST_FOR_MBED_OS */
+
+ break;
+ }
+}
+
+ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams)
+{
+
+ tBleStatus ret = BLE_STATUS_SUCCESS;
+
+ // Stop ADV before scanning
+ /*
+ if (state.advertising == 1) {
+ stopAdvertising();
+ }
+ */
+
+ /*
+ * Whitelisting (scan policy):
+ * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) &&
+ * White List is empty
+ * => scan operation = FAILURE
+ * FIXME: the Security Manager should be implemented
+ */
+ ScanningPolicyMode_t mode = getScanningPolicyMode();
+ uint8_t whiteListSize = whitelistAddresses.size;
+ if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) {
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ }
+
+ ret = btleStartRadioScan(scanningParams.getActiveScanning(),
+ scanningParams.getInterval(),
+ scanningParams.getWindow(),
+ addr_type);
+
+ PRINTF("Scanning...\n\r");
+ PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000);
+ PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000);
+ //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval());
+ //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1);
+ //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2);
+ if (BLE_STATUS_SUCCESS == ret){
+ PRINTF("Observation Procedure Started\n");
+ _scanning = true;
+ return BLE_ERROR_NONE;
+ }
+
+ // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED
+ switch (ret) {
+ case BLE_STATUS_INVALID_CID:
+ PRINTF("Observation Procedure not implemented!!!\n\r");
+ return BLE_ERROR_NOT_IMPLEMENTED;
+ default:
+ PRINTF("Observation Procedure failed (0x%02X)\n\r", ret);
+ return BLE_ERROR_UNSPECIFIED;
+ }
+
+}
+
+ble_error_t BlueNRGGap::stopScan() {
+ tBleStatus ret = BLE_STATUS_SUCCESS;
+
+ PRINTF("stopScan\n\r");
+ ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC);
+
+ if (ret != BLE_STATUS_SUCCESS) {
+ PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret);
+ return BLE_ERROR_UNSPECIFIED;
+ } else {
+ PRINTF("Discovery Procedure Terminated\n");
+ return BLE_ERROR_NONE;
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief set Tx power level
+ @param[in] txPower Transmission Power level
+ @returns ble_error_t
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setTxPower(int8_t txPower)
+{
+ tBleStatus ret;
+
+ int8_t enHighPower = 0;
+ int8_t paLevel = 0;
+
+ ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel);
+ if(ret!=BLE_STATUS_SUCCESS) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);
+ ret = aci_hal_set_tx_power_level(enHighPower, paLevel);
+ if(ret!=BLE_STATUS_SUCCESS) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief get permitted Tx power values
+ @param[in] values pointer to pointer to permitted power values
+ @param[in] num number of values
+*/
+/**************************************************************************/
+void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
+ static const int8_t permittedTxValues[] = {
+ -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8
+ };
+
+ *valueArrayPP = permittedTxValues;
+ *countP = sizeof(permittedTxValues) / sizeof(int8_t);
+}
+
+/**************************************************************************/
+/*!
+ @brief Set advertising parameters according to the current state
+ Parameters value is set taking into account guidelines of the BlueNRG
+ time slots allocation
+*/
+/**************************************************************************/
+void BlueNRGGap::setAdvParameters(void)
+{
+ uint32_t advIntMS;
+
+ if(state.connected == 1) {
+ advIntMS = (conn_min_interval*1.25)-GUARD_INT;
+ advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS);
+
+ PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval);
+ } else {
+ advInterval = _advParams.getIntervalInADVUnits();
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief Set connection parameters according to the current state (ADV and/or SCAN)
+ Parameters value is set taking into account guidelines of the BlueNRG
+ time slots allocation
+*/
+/**************************************************************************/
+void BlueNRGGap::setConnectionParameters(void)
+{
+ if (state.advertising == 1) {
+
+ if (_scanningParams.getInterval() < advInterval) {
+ PRINTF("state.adv=1 scanInterval<advInterval\r\n");
+ scanInterval = advInterval;
+ scanWindow = advInterval;
+ } else {
+ PRINTF("state.adv=1 scanInterval>=advInterval\r\n");
+ scanInterval = _scanningParams.getInterval();
+ scanWindow = _scanningParams.getWindow();
+ }
+
+ if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms
+ conn_min_interval = MAX_INT_CONN;
+ conn_max_interval = MAX_INT_CONN;
+ } else {
+ conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25;
+ conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25;
+ }
+
+ } else {
+
+ PRINTF("state.adv = 0\r\n");
+
+ scanInterval = _scanningParams.getInterval();
+ scanWindow = _scanningParams.getWindow();
+ if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) ||
+ SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms
+ conn_min_interval = DEF_INT_CONN;
+ conn_max_interval = DEF_INT_CONN;
+ } else {
+ conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25;
+ conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25;
+ }
+ }
+ PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval));
+ PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow));
+ PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25));
+ PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25));
+
+}
+
+ble_error_t BlueNRGGap::createConnection ()
+{
+ tBleStatus ret;
+
+ /*
+ Before creating connection, set parameters according
+ to previous or current procedure (ADV and/or SCAN)
+ */
+ setConnectionParameters();
+
+ /*
+ Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min,
+ Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max
+ */
+ ret = aci_gap_create_connection(scanInterval,
+ scanWindow,
+ _peerAddrType,
+ (unsigned char*)_peerAddr,
+ addr_type,
+ conn_min_interval, conn_max_interval, 0,
+ SUPERV_TIMEOUT, CONN_L1, CONN_L1);
+
+ //_connecting = false;
+
+ if (ret != BLE_STATUS_SUCCESS) {
+ PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret);
+ return BLE_ERROR_UNSPECIFIED;
+ } else {
+ PRINTF("Connection started.\n");
+ _connecting = false;
+ return BLE_ERROR_NONE;
+ }
+}
+
+ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr,
+ Gap::AddressType_t peerAddrType,
+ const ConnectionParams_t *connectionParams,
+ const GapScanningParams *scanParams)
+{
+ /* avoid compiler warnings about unused variables */
+ (void)connectionParams;
+
+ setScanParams(scanParams->getInterval(),
+ scanParams->getWindow(),
+ scanParams->getTimeout(),
+ scanParams->getActiveScanning()
+ );
+
+ // Save the peer address
+ for(int i=0; i<BDADDR_SIZE; i++) {
+ _peerAddr[i] = peerAddr[i];
+ }
+ _peerAddrType = peerAddrType;
+
+ _connecting = true;
+
+ if(_scanning) {
+ stopScan();
+ } else {
+ PRINTF("Calling createConnection from connect()\n\r");
+ return createConnection();
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Set the advertising policy filter mode that will be used in
+ the next call to startAdvertising().
+
+ @returns \ref ble_errror_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly.
+
+ BLE_ERROR_NOT_IMPLEMENTED
+ This feature is currently note implemented.
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode)
+{
+ advertisingPolicyMode = mode;
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Set the scanning policy filter mode that will be used in
+ the next call to startAdvertising().
+
+ @returns \ref ble_errror_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly.
+
+ BLE_ERROR_NOT_IMPLEMENTED
+ This feature is currently note implemented.
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode)
+{
+ scanningPolicyMode = mode;
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Get the current advertising policy filter mode.
+
+ @returns The advertising policy filter mode.
+*/
+/**************************************************************************/
+Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const
+{
+ return advertisingPolicyMode;
+}
+
+/**************************************************************************/
+/*!
+ @brief Get the current scanning policy filter mode.
+
+ @returns The scanning policy filter mode.
+
+*/
+/**************************************************************************/
+Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const
+{
+ return scanningPolicyMode;
+}
+
+/**************************************************************************/
+/*!
+ @brief Clear BlueNRGGap's state.
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::reset(void)
+{
+ /* 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;
+
+ /* Set the whitelist policy filter modes to IGNORE_WHITELIST */
+ advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST;
+ scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST;
+
+ return BLE_ERROR_NONE;
+}
+
+void BlueNRGGap::setConnectionInterval(uint16_t interval) {
+ conn_min_interval = interval;
+ conn_max_interval = interval;
+}
+
+void BlueNRGGap::setGapRole(Role_t role)
+{
+ gapRole = role;
+}
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,835 @@
+/* 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>© COPYRIGHT 2013 STMicroelectronics</center></h2>
+ */
+
+/** @defgroup BlueNRGGATTClient
+ * @brief BlueNRG BLE_API GattClient Adaptation
+ * @{
+ */
+
+#include "BlueNRGGattClient.h"
+#ifdef YOTTA_CFG_MBED_OS
+ #include "mbed-drivers/mbed.h"
+#else
+ #include "mbed.h"
+#endif
+#include "BlueNRGGap.h"
+#include "ble_utils.h"
+#include "ble_debug.h"
+
+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) {
+ if(charDescTerminationCallback != NULL) {
+ CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = {
+ _characteristic,
+ BLE_ERROR_NONE
+ };
+ charDescTerminationCallback(¶ms);
+ }
+ _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);
+
+ _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);
+
+ _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 (_numChars != 0) {
+ discoveredChar[_numChars - 1].setLastHandle(declHandle - 1);
+
+ if(characteristicDiscoveryCallback) {
+ characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]);
+ }
+ }
+
+ _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;
+
+ // complete the discovery of the last characteristic of the previous service.
+ // Its last handle wasn't known before this point
+ // update the handle and call the characteristic discovery callback.
+ if (_servIndex != 0 && _numChars != 0) {
+ discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle());
+
+ if(characteristicDiscoveryCallback) {
+ characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]);
+ }
+ }
+
+ _numChars = 0;
+
+ // We finished chars discovery for all services
+ if(_servIndex >= _numServices) {
+ PRINTF("!!!We finished chars discovery for all services!!!\n\r");
+ //_currentState = GATT_CHARS_DISCOVERY_COMPLETE;
+
+ terminateServiceDiscovery();
+
+ return BLE_ERROR_NONE;
+ }
+
+ service = &discoveredService[_servIndex];
+ /*
+ if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
+ PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID());
+ } else {
+ PRINTF("S UUID-");
+ const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
+ for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+ PRINTF("%02X", longUUIDBytes[i]);
+ }
+ PRINTF("\r\n");
+ }
+ */
+
+ if(serviceDiscoveryCallback) {
+ serviceDiscoveryCallback(service);
+ }
+
+ PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex);
+ //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
+
+ if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) {
+ PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r");
+ ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
+ } else {
+
+ uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong();
+
+ if(type == UUID::UUID_TYPE_SHORT) {
+ STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID());
+
+ uuid_type = UUID_TYPE_16;
+ uuid = short_uuid;
+#ifdef DEBUG
+ PRINTF("findServiceChars C UUID-");
+ for(unsigned i = 0; i < 2; i++) {
+ PRINTF("%02X", short_uuid[i]);
+ }
+ PRINTF("\n\r");
+#endif
+ } else if(type==UUID::UUID_TYPE_LONG) {
+
+ uuid_type = UUID_TYPE_128;
+ uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID();
+#ifdef DEBUG
+ PRINTF("(findServiceChars) C UUID-");
+ for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+ PRINTF("%02X", uuid[i]);
+ }
+ PRINTF("\r\n");
+#endif
+ }
+
+ ret = aci_gatt_disc_charac_by_uuid(connectionHandle,
+ service->getStartHandle(),
+ service->getEndHandle(),
+ uuid_type,
+ uuid);
+ }
+
+ if(ret == BLE_STATUS_SUCCESS) {
+ _servIndex++;
+ }
+
+ PRINTF("findServiceChars ret=%d\n\r", ret);
+
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t 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;
+
+ PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n",
+ event_data_length, format);
+
+
+ for (i=0; i<numCharacDesc; i++) {
+ memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle));
+
+ // UUID Type
+ if (handle_uuid_length == 4) {
+
+ PRINTF("UUID_TYPE_16\n\r");
+ uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2];
+ PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle);
+
+ } else {
+
+ PRINTF("UUID_TYPE_128\n\r");
+ uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB);
+#ifdef DEBUG
+ PRINTF("D UUID-");
+ const uint8_t *longUUIDBytes = uuid.getBaseUUID();
+ for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) {
+ PRINTF("%02x", longUUIDBytes[j]);
+ }
+#endif
+ }
+
+ if(charDescDiscoveryCallback != NULL) {
+ CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = {
+ _characteristic,
+ DiscoveredCharacteristicDescriptor(
+ _characteristic.getGattClient(),
+ connHandle,
+ attHandle,
+ uuid
+ )
+ };
+ charDescDiscoveryCallback(¶ms);
+ }
+
+ _numCharDesc++;
+
+ offset += handle_uuid_length;
+ }
+}
+
+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();
+
+ PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle);
+ 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;
+}
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,753 @@
+/* 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>© COPYRIGHT 2013 STMicroelectronics</center></h2>
+ */
+
+/** @defgroup BlueNRGGATTSERVER
+ * @brief BlueNRG BLE_API GattServer Adaptation
+ * @{
+ */
+
+#include "BlueNRGGattServer.h"
+#ifdef YOTTA_CFG_MBED_OS
+ #include "mbed-drivers/mbed.h"
+#else
+ #include "mbed.h"
+#endif
+#include "BlueNRGGap.h"
+#include "ble_utils.h"
+#include "ble_debug.h"
+
+/**************************************************************************/
+/*!
+ @brief Adds a new service to the GATT table on the peripheral
+
+ @params[in] service
+ Pointer to instance of the Gatt Server to add
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattServer::addService(GattService &service)
+{
+ /* ToDo: Make sure we don't overflow the array, etc. */
+ /* ToDo: Make sure this service UUID doesn't already exist (?) */
+ /* ToDo: Basic validation */
+
+ tBleStatus ret;
+ uint8_t type;
+ uint16_t short_uuid;
+ uint8_t primary_short_uuid[2];
+ uint8_t primary_base_uuid[16];
+ uint8_t char_base_uuid[16];
+ const uint8_t *base_uuid;
+ const uint8_t *base_char_uuid;
+
+ uint8_t charsCount = service.getCharacteristicCount();
+ const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount;
+
+ // check that there is enough characteristics left in the
+ // characteristic array.
+ if (charsCount > available_characteristics) {
+ PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics);
+ return BLE_ERROR_NO_MEM;
+ }
+
+ const uint16_t maxAttrRecords = computeAttributesRecord(service);
+
+ type = (service.getUUID()).shortOrLong();
+ PRINTF("AddService(): Type:%d\n\r", type);
+
+ /* Add the service to the BlueNRG */
+ short_uuid = (service.getUUID()).getShortUUID();
+ STORE_LE_16(primary_short_uuid, short_uuid);
+
+ if(type==UUID::UUID_TYPE_LONG) {
+ base_uuid = (service.getUUID()).getBaseUUID();
+
+ COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]);
+ }
+
+ ret = BLE_STATUS_SUCCESS;
+
+ if(type==UUID::UUID_TYPE_SHORT) {
+ ret = aci_gatt_add_serv(UUID_TYPE_16,
+ primary_short_uuid,
+ PRIMARY_SERVICE,
+ maxAttrRecords/*7*/,
+ &servHandle);
+ PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret);
+
+ } else if(type==UUID::UUID_TYPE_LONG) {
+ ret = aci_gatt_add_serv(UUID_TYPE_128,
+ primary_base_uuid,
+ PRIMARY_SERVICE,
+ maxAttrRecords/*7*/,
+ &servHandle);
+ PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret);
+ }
+
+ switch (ret) {
+ case BLE_STATUS_SUCCESS:
+ break;
+
+ case BLE_STATUS_INVALID_PARAMETER:
+ return BLE_ERROR_INVALID_PARAM;
+
+ case BLE_STATUS_OUT_OF_HANDLE:
+ case BLE_STATUS_INSUFFICIENT_RESOURCES:
+ case ERR_UNSPECIFIED_ERROR:
+ return BLE_ERROR_NO_MEM;
+
+ case BLE_STATUS_ERROR:
+ default:
+ return BLE_ERROR_INTERNAL_STACK_FAILURE;
+ }
+
+
+
+ service.setHandle(servHandle);
+ //serviceHandleVector.push_back(servHandle);
+ PRINTF("added servHandle handle =%u\n\r", servHandle);
+ uint16_t bleCharacteristic;
+
+ //iterate to include all characteristics
+ for (uint8_t i = 0; i < charsCount; i++) {
+ GattCharacteristic *p_char = service.getCharacteristic(i);
+ uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID();
+
+ uint8_t int_8_uuid[2];
+ STORE_LE_16(int_8_uuid, char_uuid);
+
+ type = (p_char->getValueAttribute().getUUID()).shortOrLong();
+
+ if(type==UUID::UUID_TYPE_LONG) {
+ base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID();
+#ifdef DEBUG
+ for(uint8_t j=0; j<16; j++) {
+ PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]);
+ }
+ PRINTF("\n\r");
+#endif
+ COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]);
+ }
+
+ PRINTF("Char Properties 0x%x\n\r", p_char->getProperties());
+ /*
+ * Gatt_Evt_Mask -> HardCoded (0)
+ * Encryption_Key_Size -> Hardcoded (16)
+ * isVariable (variable length value field) -> Hardcoded (1)
+ */
+ uint8_t Gatt_Evt_Mask = 0x0;
+
+ if((p_char->getProperties() &
+ (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE|
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) {
+ PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r");
+ Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP;
+ }
+ if((p_char->getProperties() &
+ (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ|
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) {
+ PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r");
+ Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP;
+ } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check.
+
+ if(type==UUID::UUID_TYPE_SHORT) {
+ ret = aci_gatt_add_char(service.getHandle(),
+ UUID_TYPE_16,
+ int_8_uuid,
+ p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/,
+ p_char->getProperties(),
+ ATTR_PERMISSION_NONE,
+ Gatt_Evt_Mask /*Gatt_Evt_Mask*/,
+ 16 /*Encryption_Key_Size*/,
+ 1 /*isVariable*/,
+ &bleCharacteristic);
+
+ PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r",
+ p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
+
+ } else if(type==UUID::UUID_TYPE_LONG) {
+ ret = aci_gatt_add_char(service.getHandle(),
+ UUID_TYPE_128,
+ char_base_uuid,
+ p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/,
+ p_char->getProperties(),
+ ATTR_PERMISSION_NONE,
+ Gatt_Evt_Mask /*Gatt_Evt_Mask*/,
+ 16 /*Encryption_Key_Size*/,
+ 1 /*isVariable*/,
+ &bleCharacteristic);
+
+ PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r",
+ p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
+ }
+
+ switch (ret) {
+ case BLE_STATUS_SUCCESS:
+ break;
+
+ case ERR_UNSPECIFIED_ERROR:
+ case BLE_STATUS_INSUFFICIENT_RESOURCES:
+ case BLE_STATUS_OUT_OF_HANDLE:
+ // TODO remove characteristics and the service previously added.
+ // remove service in the stack by using: Aci_Gatt_Del_Service
+ // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+ // update service counter
+ // destroy registered characteristic and updat echaracteristic counter
+ return BLE_ERROR_NO_MEM;
+
+ case BLE_STATUS_INVALID_HANDLE:
+ case BLE_STATUS_INVALID_PARAMETER:
+ case BLE_STATUS_CHARAC_ALREADY_EXISTS:
+ // TODO remove characteristics and the service previously added.
+ // remove service in the stack by using: Aci_Gatt_Del_Service
+ // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+ // update service counter
+ // destroy registered characteristic and updat echaracteristic counter
+ return BLE_ERROR_INVALID_PARAM;
+
+ case BLE_STATUS_ERROR:
+ default:
+ // TODO remove characteristics and the service previously added.
+ // remove service in the stack by using: Aci_Gatt_Del_Service
+ // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+ // update service counter
+ // destroy registered characteristic and updat echaracteristic counter
+ return BLE_ERROR_INTERNAL_STACK_FAILURE;
+ }
+
+ bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle));
+
+ p_characteristics[characteristicCount++] = p_char;
+ /* Set the characteristic value handle */
+ p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE);
+ PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle());
+
+ if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) {
+ ble_error_t err = write(p_char->getValueAttribute().getHandle(),
+ p_char->getValueAttribute().getValuePtr(),
+ p_char->getValueAttribute().getLength(), false /* localOnly */);
+ if (err) {
+ PRINTF("ERROR HERE !!!!\r\n");
+ return err;
+ }
+ }
+
+ // add descriptors now
+ uint16_t descHandle = 0;
+ PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount());
+
+ for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) {
+ GattAttribute *descriptor = p_char->getDescriptor(descIndex);
+ uint8_t desc_uuid[16] = { 0 };
+
+
+ uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT;
+ STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID());
+
+ if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) {
+ desc_uuid_type = CHAR_DESC_TYPE_128_BIT;
+ const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID();
+
+ COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]);
+ }
+
+ ret = aci_gatt_add_char_desc(service.getHandle(),
+ bleCharacteristic,
+ desc_uuid_type,
+ desc_uuid,
+ descriptor->getMaxLength(),
+ descriptor->getLength(),
+ descriptor->getValuePtr(),
+ CHAR_DESC_SECURITY_PERMISSION,
+ CHAR_DESC_ACCESS_PERMISSION,
+ GATT_NOTIFY_ATTRIBUTE_WRITE,
+ MIN_ENCRY_KEY_SIZE,
+ CHAR_ATTRIBUTE_LEN_IS_FIXED,
+ &descHandle);
+ PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret);
+
+ switch (ret) {
+ case BLE_STATUS_SUCCESS:
+ PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle);
+ descriptor->setHandle(descHandle);
+ break;
+
+ case ERR_UNSPECIFIED_ERROR:
+ case BLE_STATUS_INSUFFICIENT_RESOURCES:
+ case BLE_STATUS_OUT_OF_HANDLE:
+ // TODO remove characteristics and the service previously added.
+ // remove service in the stack by using: Aci_Gatt_Del_Service
+ // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+ // update service counter
+ // destroy registered characteristic and updat echaracteristic counter
+ return BLE_ERROR_NO_MEM;
+
+ case BLE_STATUS_INVALID_HANDLE:
+ case BLE_STATUS_INVALID_PARAMETER:
+ // TODO remove characteristics and the service previously added.
+ // remove service in the stack by using: Aci_Gatt_Del_Service
+ // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+ // update service counter
+ // destroy registered characteristic and updat echaracteristic counter
+ return BLE_ERROR_INVALID_PARAM;
+
+ case BLE_STATUS_INVALID_OPERATION:
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+
+ case BLE_STATUS_ERROR:
+ default:
+ // TODO remove characteristics and the service previously added.
+ // remove service in the stack by using: Aci_Gatt_Del_Service
+ // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+ // update service counter
+ // destroy registered characteristic and updat echaracteristic counter
+ return BLE_ERROR_INTERNAL_STACK_FAILURE;
+ }
+ }
+ }
+
+ serviceCount++;
+
+ //FIXME: There is no GattService pointer array in GattServer.
+ // There should be one? (Only the user is aware of GattServices!) Report to forum.
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Reads the value of a characteristic, based on char handle
+
+ @param[in] attributeHandle
+ The handle of the GattCharacteristic to read from
+ @param[in] buffer
+ Buffer to hold the the characteristic's value
+ (raw byte array in LSB format)
+ @param[in] lengthP
+ The number of bytes read into the buffer
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
+{
+ tBleStatus ret;
+ uint16_t charHandle = attributeHandle;
+
+ ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer);
+
+ if(ret == BLE_STATUS_SUCCESS) {
+ return BLE_ERROR_NONE;
+ }
+ switch (ret) {
+ case ERR_INVALID_HCI_CMD_PARAMS:
+ return BLE_ERROR_INVALID_PARAM;
+ default:
+ return BLE_ERROR_UNSPECIFIED;
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief Reads the value of a characteristic, based on the connection
+ and char handle
+
+ @param[in] connectionHandle
+ The handle of the connection
+ @param[in] attributeHandle
+ The handle of the GattCharacteristic to write to
+ @param[in] buffer
+ Data to use when updating the characteristic's value
+ (raw byte array in LSB format)
+ @param[in] lengthP
+ The number of bytes in buffer
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle,
+ GattAttribute::Handle_t attributeHandle,
+ uint8_t buffer[],
+ uint16_t *lengthP) {
+
+ /* avoid compiler warnings about unused variables */
+ (void)connectionHandle;
+ (void)attributeHandle;
+ (void)buffer;
+ (void)lengthP;
+
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle,
+ GattAttribute::Handle_t,
+ const uint8_t[],
+ uint16_t, bool localOnly) {
+ /* avoid compiler warnings about unused variables */
+ (void)connectionHandle;
+ (void)localOnly;
+
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
+{
+ /* avoid compiler warnings about unused variables */
+ (void)localOnly;
+
+ // check that the len of the data to write are compatible with the characteristic
+ GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle);
+ if (!characteristic) {
+ PRINTF("characteristic not found\r\n");
+ return BLE_ERROR_INVALID_PARAM;
+ }
+
+ // if the attribute handle is the attribute handle of the characteristic value then
+ // write the value
+ if (attributeHandle == characteristic->getValueHandle()) {
+ // assert the len in input is correct for this characteristic
+ const GattAttribute& value_attribute = characteristic->getValueAttribute();
+
+ // reject write if the lenght exceed the maximum lenght of this attribute
+ if (value_attribute.getMaxLength() < len) {
+ PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength());
+ return BLE_ERROR_INVALID_PARAM;
+ }
+
+ // reject write if the attribute size is fixed and the lenght in input is different than the
+ // length of the attribute.
+ if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) {
+ PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength());
+ return BLE_ERROR_INVALID_PARAM;
+ }
+
+ tBleStatus ret;
+
+ uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE;
+
+ PRINTF("updating bleCharacteristic valueHandle=%u,\
+ corresponding serviceHandle=%u len=%d\n\r",
+ attributeHandle, bleCharHandleMap.find(charHandle)->second, len);
+
+ /*
+ * If notifications (or indications) are enabled on that characteristic, a notification (or indication)
+ * will be sent to the client after sending this command to the BlueNRG.
+ */
+ ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer);
+
+ if (ret != BLE_STATUS_SUCCESS){
+ PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret);
+ switch (ret) {
+ case BLE_STATUS_INVALID_HANDLE:
+ case BLE_STATUS_INVALID_PARAMETER:
+ return BLE_ERROR_INVALID_PARAM;
+ default:
+ return BLE_STACK_BUSY;
+ }
+ }
+
+ return BLE_ERROR_NONE;
+ } else {
+ // write this handle has a descriptor handle
+ uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE;
+ uint16_t service_handle = bleCharHandleMap.find(charHandle)->second;
+
+ tBleStatus ret = aci_gatt_set_desc_value(
+ service_handle,
+ charHandle,
+ attributeHandle,
+ 0,
+ len,
+ buffer
+ );
+
+ if (ret != BLE_STATUS_SUCCESS){
+ PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret);
+ switch (ret) {
+ case BLE_STATUS_INVALID_HANDLE:
+ case BLE_STATUS_INVALID_PARAMETER:
+ return BLE_ERROR_INVALID_PARAM;
+ default:
+ return BLE_STACK_BUSY;
+ }
+ }
+
+ return BLE_ERROR_NONE;
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief Reads a value according to the handle provided
+
+ @param[in] attributeHandle
+ The handle of the attribute to read from
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle)
+{
+ uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle();
+
+ GattReadCallbackParams readParams;
+ readParams.handle = attributeHandle;
+
+ //PRINTF("readParams.handle = %d\n\r", readParams.handle);
+ HCIDataReadEvent(&readParams);
+
+ //EXIT:
+ if(gapConnectionHandle != 0){
+ //PRINTF("Calling aci_gatt_allow_read\n\r");
+ aci_gatt_allow_read(gapConnectionHandle);
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+// ask if the write request should be accepted of rejected
+// return 0 in case of success or an ATT error response in
+// case of faillure
+uint8_t BlueNRGGattServer::Write_Request_CB(
+ uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length,
+ const uint8_t* data) {
+
+ GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle);
+ if(!characteristic) {
+ return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF;
+ }
+
+ // check if the data length is in range
+ if (characteristic->getValueAttribute().getMaxLength() < data_length) {
+ return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF;
+ }
+
+ // if the length of the characteristic value is fixed
+ // then the data in input should be of that length
+ if (characteristic->getValueAttribute().hasVariableLength() == false &&
+ characteristic->getValueAttribute().getMaxLength() != data_length) {
+ return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF;
+ }
+
+ GattWriteAuthCallbackParams params = {
+ connection_handle,
+ attr_handle,
+ /* offset */ 0,
+ data_length,
+ data,
+ /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED
+ };
+
+ return characteristic->authorizeWrite(¶ms) & 0xFF;
+}
+
+/**************************************************************************/
+/*!
+ @brief Returns the GattCharacteristic according to the handle provided
+
+ @param[in] attrHandle
+ The handle of the attribute
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle)
+{
+ GattCharacteristic *p_char = NULL;
+ int i;
+ uint16_t handle, handle_1;
+
+ PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle);
+ for(i=0; i<characteristicCount; i++)
+ {
+ handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
+ PRINTF("handle(%d)=%d\n\r", i, handle);
+ if(i==characteristicCount-1)//Last Characteristic check
+ {
+ if(attrHandle>=handle)
+ {
+ p_char = p_characteristics[i];
+ PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle);
+ break;
+ }
+ }
+ else {
+ handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
+ //Testing if attribute handle is between two Characteristic Handles
+ if(attrHandle>=handle && attrHandle<handle_1)
+ {
+ p_char = p_characteristics[i];
+ PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1);
+ break;
+ } else continue;
+ }
+ }
+
+ return p_char;
+}
+
+void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) {
+ this->handleDataWrittenEvent(params);
+}
+
+void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) {
+ PRINTF("Called HCIDataReadEvent\n\r");
+ this->handleDataReadEvent(params);
+}
+
+void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) {
+ this->handleEvent(type, charHandle);
+}
+
+void BlueNRGGattServer::HCIDataSentEvent(unsigned count) {
+ this->handleDataSentEvent(count);
+}
+
+
+ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) {
+ // <TODO>
+ return (ble_error_t)0;
+}
+
+/**************************************************************************/
+/*!
+ @brief Clear BlueNRGGattServer's state.
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattServer::reset(void)
+{
+ /* Clear all state that is from the parent, including private members */
+ if (GattServer::reset() != BLE_ERROR_NONE) {
+ return BLE_ERROR_INVALID_STATE;
+ }
+
+ /* Clear class members */
+ memset(p_characteristics, 0, sizeof(p_characteristics));
+ memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles));
+ serviceCount = 0;
+ characteristicCount = 0;
+
+ return BLE_ERROR_NONE;
+}
+
+
+/// compute the number of attributes needed by this service.
+uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) {
+ uint16_t attribute_records = 1;
+
+ for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) {
+ // add two attributes, one for the characteristic declaration
+ // and the other for the characteristic value.
+ attribute_records += 2;
+
+ const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index);
+ const uint8_t properties = characteristic->getProperties();
+ // if notify or indicate are present, two attributes are
+ // needed
+ if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ||
+ (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) {
+ attribute_records += 2;
+ }
+
+ // if broadcast is set, two attributes are needed
+ if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) {
+ attribute_records += 2;
+ }
+
+ // if extended properties flag is set, two attributes are needed
+ if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) {
+ attribute_records += 2;
+ }
+
+ attribute_records += characteristic->getDescriptorCount();
+ }
+
+ // for some reason, if there is just a service, this value should
+ // be equal to 5
+ if (attribute_records == 1) {
+ attribute_records = 5;
+ }
+
+ return attribute_records;
+}
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,1228 @@
+/**
+ ******************************************************************************
+ * @file ble_hci.c
+ * @author AMS/HESA Application Team
+ * @brief Function for managing HCI interface.
+ ******************************************************************************
+ *
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
+ */
+
+#include "ble_hal_types.h"
+#include "ble_osal.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_hci_const.h"
+#include "ble_gp_timer.h"
+#include "ble_debug.h"
+
+#include "stm32_bluenrg_ble.h"
+
+#if BLE_CONFIG_DBG_ENABLE
+#undef PRINTF
+#endif
+
+#define HCI_LOG_ON 0
+
+#define HCI_READ_PACKET_NUM_MAX (0x40)
+
+#define MIN(a,b) ((a) < (b) )? (a) : (b)
+#define MAX(a,b) ((a) > (b) )? (a) : (b)
+
+tListNode hciReadPktPool;
+tListNode hciReadPktRxQueue;
+
+// betzw - DEBUG:
+//#define POOL_CNT
+#ifdef POOL_CNT
+#include <stdio.h>
+static unsigned int nr_hciReadPktPool;
+static unsigned int lowest_nr_hciReadPktPool;
+#endif // POOL_CNT
+
+/* pool of hci read packets */
+static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX];
+
+static volatile uint8_t readPacketListFull=FALSE;
+
+static volatile uint8_t hci_timer_id;
+static volatile uint8_t hci_timeout;
+
+void hci_timeout_callback(void)
+{
+ hci_timeout = 1;
+ return;
+}
+
+void HCI_Init(void)
+{
+ uint8_t index;
+
+ Disable_SPI_IRQ();
+
+#ifdef POOL_CNT
+ nr_hciReadPktPool = 0;
+#endif // POOL_CNT
+
+ /* Initialize list heads of ready and free hci data packet queues */
+ list_init_head (&hciReadPktPool);
+ list_init_head (&hciReadPktRxQueue);
+
+ /* Initialize the queue of free hci data packets */
+ for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++)
+ {
+ list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]);
+#ifdef POOL_CNT
+ nr_hciReadPktPool++;
+#endif // POOL_CNT
+ }
+
+#ifdef POOL_CNT
+ lowest_nr_hciReadPktPool = nr_hciReadPktPool;
+#endif // POOL_CNT
+
+ Enable_SPI_IRQ();
+}
+
+#define HCI_PCK_TYPE_OFFSET 0
+#define EVENT_PARAMETER_TOT_LEN_OFFSET 2
+
+/**
+ * Verify if HCI packet is correctly formatted..
+ *
+ * @param[in] hciReadPacket The packet that is received from HCI interface.
+ * @return 0 if HCI packet is as expected
+ */
+int HCI_verify(const tHciDataPacket * hciReadPacket)
+{
+ const uint8_t *hci_pckt = hciReadPacket->dataBuff;
+
+ if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT)
+ return 1; /* Incorrect type. */
+
+ if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE))
+ return 2; /* Wrong length (packet truncated or too long). */
+
+ return 0;
+}
+
+void HCI_Process(void)
+{
+ uint8_t data_len;
+ uint8_t buffer[HCI_READ_PACKET_SIZE];
+ tHciDataPacket * hciReadPacket = NULL;
+
+#ifdef POOL_CNT
+ printf("betzw(%s, %d): nr_hciReadPktPool = %u (lowest = %u)\r\n", __func__, __LINE__,
+ nr_hciReadPktPool, lowest_nr_hciReadPktPool);
+#endif // POOL_CNT
+
+ Disable_SPI_IRQ();
+ uint8_t list_empty = list_is_empty(&hciReadPktRxQueue);
+ /* process any pending events read */
+ while(list_empty == FALSE)
+ {
+ list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
+ Enable_SPI_IRQ();
+ HCI_Event_CB(hciReadPacket->dataBuff);
+ Disable_SPI_IRQ();
+ list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
+#ifdef POOL_CNT
+ nr_hciReadPktPool++;
+#endif
+ list_empty = list_is_empty(&hciReadPktRxQueue);
+ }
+ if (readPacketListFull) {
+ while(BlueNRG_DataPresent()) {
+ data_len = BlueNRG_SPI_Read_All(buffer, HCI_READ_PACKET_SIZE);
+ if(data_len > 0)
+ HCI_Event_CB(buffer);
+ }
+ readPacketListFull = FALSE;
+ }
+
+ Enable_SPI_IRQ();
+}
+
+BOOL HCI_Queue_Empty(void)
+{
+ return list_is_empty(&hciReadPktRxQueue);
+}
+
+void HCI_Isr(void)
+{
+ tHciDataPacket * hciReadPacket = NULL;
+ uint8_t data_len;
+
+ Clear_SPI_EXTI_Flag();
+ while(BlueNRG_DataPresent()){
+ if (list_is_empty (&hciReadPktPool) == FALSE){
+
+ /* enqueueing a packet for read */
+ list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket);
+#ifdef POOL_CNT
+ nr_hciReadPktPool--;
+ if(nr_hciReadPktPool < lowest_nr_hciReadPktPool)
+ lowest_nr_hciReadPktPool = nr_hciReadPktPool;
+#endif
+
+ data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE);
+ if(data_len > 0){
+ hciReadPacket->data_len = data_len;
+ if(HCI_verify(hciReadPacket) == 0) {
+ list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket);
+ signalEventsToProcess();
+ } else {
+ list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket);
+#ifdef POOL_CNT
+ nr_hciReadPktPool++;
+#endif
+ }
+ }
+ else {
+ // Insert the packet back into the pool.
+ list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket);
+#ifdef POOL_CNT
+ nr_hciReadPktPool++;
+#endif
+ }
+ }
+ else{
+ // HCI Read Packet Pool is empty, wait for a free packet.
+ signalEventsToProcess();
+ readPacketListFull = TRUE;
+ Clear_SPI_EXTI_Flag();
+ return;
+ }
+ Clear_SPI_EXTI_Flag();
+ }
+}
+
+void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){
+#if HCI_LOG_ON
+ PRINTF("HCI <- ");
+ for(int i=0; i < n_bytes1; i++)
+ PRINTF("%02X ", *((uint8_t*)data1 + i));
+ for(int i=0; i < n_bytes2; i++)
+ PRINTF("%02X ", *((uint8_t*)data2 + i));
+ PRINTF("\n");
+#endif
+
+ Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2);
+}
+
+void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param)
+{
+ hci_command_hdr hc;
+
+ hc.opcode = htobs(cmd_opcode_pack(ogf, ocf));
+ hc.plen= plen;
+
+ uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE];
+ header[0] = HCI_COMMAND_PKT;
+ Osal_MemCpy(header+1, &hc, sizeof(hc));
+
+ hci_write(header, param, sizeof(header), plen);
+}
+
+static void move_list(tListNode * dest_list, tListNode * src_list)
+{
+ pListNode tmp_node;
+
+ while(!list_is_empty(src_list)){
+ list_remove_head(src_list, &tmp_node);
+ list_insert_tail(dest_list, tmp_node);
+ }
+}
+
+int hci_send_req(struct hci_request *r, BOOL async)
+{
+ uint8_t *ptr;
+ uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf));
+ hci_event_pckt *event_pckt;
+ hci_uart_pckt *hci_hdr;
+ int to = DEFAULT_TIMEOUT;
+ struct timer t;
+ tHciDataPacket * hciReadPacket = NULL;
+ tListNode hciTempQueue;
+
+ list_init_head(&hciTempQueue);
+
+ hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam);
+
+ if(async){
+ goto done;
+ }
+
+ /* Minimum timeout is 1. */
+ if(to == 0)
+ to = 1;
+
+ Timer_Set(&t, to);
+
+ while(1) {
+ evt_cmd_complete *cc;
+ evt_cmd_status *cs;
+ evt_le_meta_event *me;
+ int len;
+
+#if ENABLE_MICRO_SLEEP
+ while(1){
+ ATOMIC_SECTION_BEGIN();
+ if(Timer_Expired(&t)){
+ ATOMIC_SECTION_END();
+ goto failed;
+ }
+ if(!HCI_Queue_Empty()){
+ ATOMIC_SECTION_END();
+ break;
+ }
+ Enter_Sleep_Mode();
+ ATOMIC_SECTION_END();
+ }
+#else
+ while(1){
+ if(Timer_Expired(&t)){
+ goto failed;
+ }
+ if(!HCI_Queue_Empty()){
+ break;
+ }
+ }
+#endif
+
+ /* Extract packet from HCI event queue. */
+ Disable_SPI_IRQ();
+ list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
+
+ hci_hdr = (void *)hciReadPacket->dataBuff;
+ if(hci_hdr->type != HCI_EVENT_PKT){
+ list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); // See comment below
+ Enable_SPI_IRQ();
+ continue;
+ }
+
+ event_pckt = (void *) (hci_hdr->data);
+
+ ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE);
+ len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE);
+
+ switch (event_pckt->evt) {
+
+ case EVT_CMD_STATUS:
+ cs = (void *) ptr;
+
+ if (cs->opcode != opcode)
+ goto failed;
+
+ if (r->event != EVT_CMD_STATUS) {
+ if (cs->status) {
+ goto failed;
+ }
+ break;
+ }
+
+ r->rlen = MIN(len, r->rlen);
+ Osal_MemCpy(r->rparam, ptr, r->rlen);
+ goto done;
+
+ case EVT_CMD_COMPLETE:
+ cc = (void *) ptr;
+
+ if (cc->opcode != opcode)
+ goto failed;
+
+ ptr += EVT_CMD_COMPLETE_SIZE;
+ len -= EVT_CMD_COMPLETE_SIZE;
+
+ r->rlen = MIN(len, r->rlen);
+ Osal_MemCpy(r->rparam, ptr, r->rlen);
+ goto done;
+
+ case EVT_LE_META_EVENT:
+ me = (void *) ptr;
+
+ if (me->subevent != r->event)
+ break;
+
+ len -= 1;
+ r->rlen = MIN(len, r->rlen);
+ Osal_MemCpy(r->rparam, me->data, r->rlen);
+ goto done;
+
+ case EVT_HARDWARE_ERROR:
+ goto failed;
+
+ default:
+ break;
+ }
+
+ /* In the meantime there could be other events from the controller.
+ In this case, insert the packet in a different queue. These packets will be
+ inserted back in the main queue just before exiting from send_req().
+ */
+ if(hciReadPacket != NULL) {
+ list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket);
+ hciReadPacket = NULL;
+ }
+ /* Be sure there is at list one packet in the pool to process the expected event. */
+ if(list_is_empty(&hciReadPktPool)){ // betzw: this is a kind of steeling (should never happen?!?)
+ pListNode tmp_node;
+ list_remove_head(&hciReadPktRxQueue, &tmp_node);
+ list_insert_tail(&hciReadPktPool, tmp_node);
+#ifdef POOL_CNT
+ nr_hciReadPktPool++;
+#endif
+ }
+
+ Enable_SPI_IRQ();
+
+ }
+
+failed:
+ // Insert the packet back into the pool.
+ if(hciReadPacket != NULL) {
+ list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket);
+#ifdef POOL_CNT
+ nr_hciReadPktPool++;
+#endif
+ hciReadPacket = NULL;
+ }
+ move_list(&hciReadPktRxQueue, &hciTempQueue);
+ Enable_SPI_IRQ();
+ return -1;
+
+done:
+ // Insert the packet back into the pool.
+ if(hciReadPacket != NULL) {
+ list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket);
+#ifdef POOL_CNT
+ nr_hciReadPktPool++;
+#endif
+ hciReadPacket = NULL;
+ }
+ move_list(&hciReadPktRxQueue, &hciTempQueue);
+
+ Enable_SPI_IRQ();
+ 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 BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+int hci_disconnect(uint16_t handle, uint8_t reason)
+{
+ struct hci_request rq;
+ disconnect_cp cp;
+ uint8_t status;
+
+ cp.handle = handle;
+ cp.reason = reason;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LINK_CTL;
+ rq.ocf = OCF_DISCONNECT;
+ rq.cparam = &cp;
+ rq.clen = DISCONNECT_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version,
+ uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion)
+{
+ struct hci_request rq;
+ read_local_version_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_INFO_PARAM;
+ rq.ocf = OCF_READ_LOCAL_VERSION;
+ rq.cparam = NULL;
+ rq.clen = 0;
+ rq.rparam = &resp;
+ rq.rlen = READ_LOCAL_VERSION_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+
+ *hci_version = resp.hci_version;
+ *hci_revision = btohs(resp.hci_revision);
+ *lmp_pal_version = resp.lmp_pal_version;
+ *manufacturer_name = btohs(resp.manufacturer_name);
+ *lmp_pal_subversion = btohs(resp.lmp_pal_subversion);
+
+ return 0;
+}
+
+int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt)
+{
+ struct hci_request rq;
+ le_read_buffer_size_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_BUFFER_SIZE;
+ rq.cparam = NULL;
+ rq.clen = 0;
+ rq.rparam = &resp;
+ rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *pkt_len = resp.pkt_len;
+ *max_pkt = resp.max_pkt;
+
+ return 0;
+}
+
+int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype,
+ uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map,
+ uint8_t filter)
+{
+ struct hci_request rq;
+ le_set_adv_parameters_cp adv_cp;
+ uint8_t status;
+
+ Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
+ adv_cp.min_interval = min_interval;
+ adv_cp.max_interval = max_interval;
+ adv_cp.advtype = advtype;
+ adv_cp.own_bdaddr_type = own_bdaddr_type;
+ adv_cp.direct_bdaddr_type = direct_bdaddr_type;
+ if(direct_bdaddr != NULL)
+ Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr));
+ adv_cp.chan_map = chan_map;
+ adv_cp.filter = filter;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_SET_ADV_PARAMETERS;
+ rq.cparam = &adv_cp;
+ rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+int hci_le_set_advertising_data(uint8_t length, const uint8_t data[])
+{
+ struct hci_request rq;
+ le_set_adv_data_cp adv_cp;
+ uint8_t status;
+
+ Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
+ adv_cp.length = length;
+ Osal_MemCpy(adv_cp.data, data, MIN(31,length));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_SET_ADV_DATA;
+ rq.cparam = &adv_cp;
+ rq.clen = LE_SET_ADV_DATA_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+int hci_le_set_advertise_enable(uint8_t enable)
+{
+ struct hci_request rq;
+ le_set_advertise_enable_cp adv_cp;
+ uint8_t status;
+
+ Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
+ adv_cp.enable = enable?1:0;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE;
+ rq.cparam = &adv_cp;
+ rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+int hci_le_set_scan_parameters(uint8_t type, uint16_t interval,
+ uint16_t window, uint8_t own_bdaddr_type,
+ uint8_t filter)
+{
+ struct hci_request rq;
+ le_set_scan_parameters_cp scan_cp;
+ uint8_t status;
+
+ Osal_MemSet(&scan_cp, 0, sizeof(scan_cp));
+ scan_cp.type = type;
+ scan_cp.interval = interval;
+ scan_cp.window = window;
+ scan_cp.own_bdaddr_type = own_bdaddr_type;
+ scan_cp.filter = filter;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_SET_SCAN_PARAMETERS;
+ rq.cparam = &scan_cp;
+ rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup)
+{
+ struct hci_request rq;
+ le_set_scan_enable_cp scan_cp;
+ uint8_t status;
+
+ Osal_MemSet(&scan_cp, 0, sizeof(scan_cp));
+ scan_cp.enable = enable?1:0;
+ scan_cp.filter_dup = filter_dup;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_SET_SCAN_ENABLE;
+ rq.cparam = &scan_cp;
+ rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+int hci_le_rand(uint8_t random_number[8])
+{
+ struct hci_request rq;
+ le_rand_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_RAND;
+ rq.cparam = NULL;
+ rq.clen = 0;
+ rq.rparam = &resp;
+ rq.rlen = LE_RAND_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ Osal_MemCpy(random_number, resp.random, 8);
+
+ return 0;
+}
+
+int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[])
+{
+ struct hci_request rq;
+ le_set_scan_response_data_cp scan_resp_cp;
+ uint8_t status;
+
+ Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp));
+ scan_resp_cp.length = length;
+ Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA;
+ rq.cparam = &scan_resp_cp;
+ rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level)
+{
+ struct hci_request rq;
+ le_read_adv_channel_tx_power_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER;
+ rq.cparam = NULL;
+ rq.clen = 0;
+ rq.rparam = &resp;
+ rq.rlen = LE_RAND_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *tx_power_level = resp.level;
+
+ return 0;
+}
+
+int hci_le_set_random_address(tBDAddr bdaddr)
+{
+ struct hci_request rq;
+ le_set_random_address_cp set_rand_addr_cp;
+ uint8_t status;
+
+ Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp));
+ Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_SET_RANDOM_ADDRESS;
+ rq.cparam = &set_rand_addr_cp;
+ rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+int hci_read_bd_addr(tBDAddr bdaddr)
+{
+ struct hci_request rq;
+ read_bd_addr_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_INFO_PARAM;
+ rq.ocf = OCF_READ_BD_ADDR;
+ rq.cparam = NULL;
+ rq.clen = 0;
+ rq.rparam = &resp;
+ rq.rlen = READ_BD_ADDR_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (resp.status) {
+ return resp.status;
+ }
+ Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr));
+
+ return 0;
+}
+
+int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type,
+ const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval,
+ uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length)
+{
+ struct hci_request rq;
+ le_create_connection_cp create_cp;
+ uint8_t status;
+
+ Osal_MemSet(&create_cp, 0, sizeof(create_cp));
+ create_cp.interval = interval;
+ create_cp.window = window;
+ create_cp.initiator_filter = initiator_filter;
+ create_cp.peer_bdaddr_type = peer_bdaddr_type;
+ Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr));
+ create_cp.own_bdaddr_type = own_bdaddr_type;
+ create_cp.min_interval=min_interval;
+ create_cp.max_interval=max_interval;
+ create_cp.latency = latency;
+ create_cp.supervision_timeout=supervision_timeout;
+ create_cp.min_ce_length=min_ce_length;
+ create_cp.max_ce_length=max_ce_length;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_CREATE_CONN;
+ rq.cparam = &create_cp;
+ rq.clen = LE_CREATE_CONN_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+int hci_le_create_connection_cancel(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_CREATE_CONN_CANCEL;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16])
+{
+ struct hci_request rq;
+ le_encrypt_cp params;
+ le_encrypt_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemCpy(params.key, key, 16);
+ Osal_MemCpy(params.plaintext, plaintextData, 16);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_ENCRYPT;
+ rq.cparam = ¶ms;
+ rq.clen = LE_ENCRYPT_CP_SIZE;
+ rq.rparam = &resp;
+ rq.rlen = LE_ENCRYPT_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ Osal_MemCpy(encryptedData, resp.encdata, 16);
+
+ return 0;
+}
+
+int hci_le_ltk_request_reply(uint8_t key[16])
+{
+ struct hci_request rq;
+ le_ltk_reply_cp params;
+ le_ltk_reply_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ params.handle = 1;
+ Osal_MemCpy(params.key, key, 16);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_LTK_REPLY;
+ rq.cparam = ¶ms;
+ rq.clen = LE_LTK_REPLY_CP_SIZE;
+ rq.rparam = &resp;
+ rq.rlen = LE_LTK_REPLY_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return resp.status;
+}
+
+int hci_le_ltk_request_neg_reply()
+{
+ 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 = ¶ms;
+ rq.clen = LE_LTK_NEG_REPLY_CP_SIZE;
+ rq.rparam = &resp;
+ rq.rlen = LE_LTK_NEG_REPLY_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return resp.status;
+}
+
+int hci_le_read_white_list_size(uint8_t *size)
+{
+ struct hci_request rq;
+ le_read_white_list_size_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE;
+ rq.rparam = &resp;
+ rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *size = resp.size;
+
+ return 0;
+}
+
+int hci_le_clear_white_list()
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_CLEAR_WHITE_LIST;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ return status;
+}
+
+int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr)
+{
+ struct hci_request rq;
+ le_add_device_to_white_list_cp params;
+ uint8_t status;
+
+ params.bdaddr_type = bdaddr_type;
+ Osal_MemCpy(params.bdaddr, bdaddr, 6);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST;
+ rq.cparam = ¶ms;
+ rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ return status;
+}
+
+int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr)
+{
+ struct hci_request rq;
+ le_remove_device_from_white_list_cp params;
+ uint8_t status;
+
+ params.bdaddr_type = bdaddr_type;
+ Osal_MemCpy(params.bdaddr, bdaddr, 6);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST;
+ rq.cparam = ¶ms;
+ rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ return status;
+}
+
+int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level)
+{
+ struct hci_request rq;
+ read_transmit_power_level_cp params;
+ read_transmit_power_level_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ params.handle = *conn_handle;
+ params.type = type;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_HOST_CTL;
+ rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL;
+ rq.cparam = ¶ms;
+ rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE;
+ rq.rparam = &resp;
+ rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *conn_handle = resp.handle;
+ *tx_level = resp.level;
+
+ return 0;
+}
+
+int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi)
+{
+ struct hci_request rq;
+ read_rssi_cp params;
+ read_rssi_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ params.handle = *conn_handle;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_STATUS_PARAM;
+ rq.ocf = OCF_READ_RSSI;
+ rq.cparam = ¶ms;
+ rq.clen = READ_RSSI_CP_SIZE;
+ rq.rparam = &resp;
+ rq.rlen = READ_RSSI_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *conn_handle = resp.handle;
+ *rssi = resp.rssi;
+
+ return 0;
+}
+
+int hci_le_read_local_supported_features(uint8_t *features)
+{
+ struct hci_request rq;
+ le_read_local_supported_features_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_LOCAL_SUPPORTED_FEATURES;
+ rq.rparam = &resp;
+ rq.rlen = LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ Osal_MemCpy(features, resp.features, sizeof(resp.features));
+
+ return 0;
+}
+
+int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5])
+{
+ struct hci_request rq;
+ le_read_channel_map_cp params;
+ le_read_channel_map_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ params.handle = conn_handle;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_CHANNEL_MAP;
+ rq.cparam = ¶ms;
+ rq.clen = LE_READ_CHANNEL_MAP_CP_SIZE;
+ rq.rparam = &resp;
+ rq.rlen = LE_READ_CHANNEL_MAP_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ Osal_MemCpy(ch_map, resp.map, 5);
+
+ return 0;
+}
+
+int hci_le_read_supported_states(uint8_t states[8])
+{
+ struct hci_request rq;
+ le_read_supported_states_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_SUPPORTED_STATES;
+ rq.rparam = &resp;
+ rq.rlen = LE_READ_SUPPORTED_STATES_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ Osal_MemCpy(states, resp.states, 8);
+
+ return 0;
+}
+
+int hci_le_receiver_test(uint8_t frequency)
+{
+ struct hci_request rq;
+ le_receiver_test_cp params;
+ uint8_t status;
+
+ params.frequency = frequency;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_RECEIVER_TEST;
+ rq.cparam = ¶ms;
+ rq.clen = LE_RECEIVER_TEST_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ return status;
+}
+
+int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload)
+{
+ struct hci_request rq;
+ le_transmitter_test_cp params;
+ uint8_t status;
+
+ params.frequency = frequency;
+ params.length = length;
+ params.payload = payload;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_TRANSMITTER_TEST;
+ rq.cparam = ¶ms;
+ rq.clen = LE_TRANSMITTER_TEST_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ return status;
+}
+
+int hci_le_test_end(uint16_t *num_pkts)
+{
+ struct hci_request rq;
+ le_test_end_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_TEST_END;
+ rq.rparam = &resp;
+ rq.rlen = LE_TEST_END_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return BLE_STATUS_TIMEOUT;
+ }
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *num_pkts = resp.num_pkts;
+
+ return 0;
+}
+
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,1307 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name : bluenrg_hci.c
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 4-Oct-2013
+* Description : File with HCI commands for BlueNRG FW6.0 and above.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#include "ble_hal_types.h"
+#include "ble_osal.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_osal.h"
+#include "ble_hci_const.h"
+#include "bluenrg_aci_const.h"
+#include "bluenrg_gap_aci.h"
+#include "bluenrg_gatt_server.h"
+#include "bluenrg_gap.h"
+
+#define MIN(a,b) ((a) < (b) )? (a) : (b)
+#define MAX(a,b) ((a) > (b) )? (a) : (b)
+
+tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle)
+{
+ struct hci_request rq;
+ gap_init_cp_IDB05A1 cp;
+ gap_init_rp resp;
+
+ cp.role = role;
+ cp.privacy_enabled = privacy_enabled;
+ cp.device_name_char_len = device_name_char_len;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_INIT;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &resp;
+ rq.rlen = GAP_INIT_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *service_handle = btohs(resp.service_handle);
+ *dev_name_char_handle = btohs(resp.dev_name_char_handle);
+ *appearance_char_handle = btohs(resp.appearance_char_handle);
+
+ return 0;
+}
+tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle)
+{
+ struct hci_request rq;
+ gap_init_cp_IDB04A1 cp;
+ gap_init_rp resp;
+
+ cp.role = role;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_INIT;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &resp;
+ rq.rlen = GAP_INIT_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *service_handle = btohs(resp.service_handle);
+ *dev_name_char_handle = btohs(resp.dev_name_char_handle);
+ *appearance_char_handle = btohs(resp.appearance_char_handle);
+
+ return 0;
+}
+
+tBleStatus aci_gap_set_non_discoverable(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax,
+ uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen,
+ const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList,
+ uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax)
+{
+ struct hci_request rq;
+ uint8_t status;
+ uint8_t buffer[40];
+ uint8_t indx = 0;
+
+ if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ buffer[indx] = AdvType;
+ indx++;
+
+ AdvIntervMin = htobs(AdvIntervMin);
+ Osal_MemCpy(buffer + indx, &AdvIntervMin, 2);
+ indx += 2;
+
+ AdvIntervMax = htobs(AdvIntervMax);
+ Osal_MemCpy(buffer + indx, &AdvIntervMax, 2);
+ indx += 2;
+
+ buffer[indx] = OwnAddrType;
+ indx++;
+
+ buffer[indx] = AdvFilterPolicy;
+ indx++;
+
+ buffer[indx] = LocalNameLen;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, LocalName, LocalNameLen);
+ indx += LocalNameLen;
+
+ buffer[indx] = ServiceUUIDLen;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen);
+ indx += ServiceUUIDLen;
+
+ Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2);
+ indx += 2;
+
+ Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2);
+ indx += 2;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax,
+ uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen,
+ const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList,
+ uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax)
+{
+ struct hci_request rq;
+ uint8_t status;
+ uint8_t buffer[40];
+ uint8_t indx = 0;
+
+ if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ buffer[indx] = AdvType;
+ indx++;
+
+ AdvIntervMin = htobs(AdvIntervMin);
+ Osal_MemCpy(buffer + indx, &AdvIntervMin, 2);
+ indx += 2;
+
+ AdvIntervMax = htobs(AdvIntervMax);
+ Osal_MemCpy(buffer + indx, &AdvIntervMax, 2);
+ indx += 2;
+
+ buffer[indx] = OwnAddrType;
+ indx++;
+
+ buffer[indx] = AdvFilterPolicy;
+ indx++;
+
+ buffer[indx] = LocalNameLen;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, LocalName, LocalNameLen);
+ indx += LocalNameLen;
+
+ buffer[indx] = ServiceUUIDLen;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen);
+ indx += ServiceUUIDLen;
+
+ SlaveConnIntervMin = htobs(SlaveConnIntervMin);
+ Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2);
+ indx += 2;
+
+ SlaveConnIntervMax = htobs(SlaveConnIntervMax);
+ Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2);
+ indx += 2;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_DISCOVERABLE;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (status) {
+ return status;
+ }
+
+ return 0;
+}
+
+tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr)
+{
+ struct hci_request rq;
+ gap_set_direct_conectable_cp_IDB05A1 cp;
+ uint8_t status;
+
+ cp.own_bdaddr_type = own_addr_type;
+ cp.directed_adv_type = directed_adv_type;
+ cp.direct_bdaddr_type = initiator_addr_type;
+ Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr)
+{
+ struct hci_request rq;
+ gap_set_direct_conectable_cp_IDB04A1 cp;
+ uint8_t status;
+
+ cp.own_bdaddr_type = own_addr_type;
+ cp.direct_bdaddr_type = initiator_addr_type;
+ Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_set_io_capability(uint8_t io_capability)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gap_set_io_capability_cp cp;
+
+ cp.io_capability = io_capability;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_IO_CAPABILITY;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode,
+ uint8_t oob_enable,
+ uint8_t oob_data[16],
+ uint8_t min_encryption_key_size,
+ uint8_t max_encryption_key_size,
+ uint8_t use_fixed_pin,
+ uint32_t fixed_pin,
+ uint8_t bonding_mode)
+{
+ struct hci_request rq;
+ gap_set_auth_requirement_cp cp;
+ uint8_t status;
+
+ cp.mitm_mode = mitm_mode;
+ cp.oob_enable = oob_enable;
+ Osal_MemCpy(cp.oob_data, oob_data, 16);
+ cp.min_encryption_key_size = min_encryption_key_size;
+ cp.max_encryption_key_size = max_encryption_key_size;
+ cp.use_fixed_pin = use_fixed_pin;
+ cp.fixed_pin = htobl(fixed_pin);
+ cp.bonding_mode = bonding_mode;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (status) {
+ return status;
+ }
+
+ return 0;
+}
+
+tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable)
+{
+ struct hci_request rq;
+ gap_set_author_requirement_cp cp;
+ uint8_t status;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.authorization_enable = authorization_enable;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey)
+{
+ struct hci_request rq;
+ gap_passkey_response_cp cp;
+ uint8_t status;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.passkey = htobl(passkey);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_PASSKEY_RESPONSE;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize)
+{
+ struct hci_request rq;
+ gap_authorization_response_cp cp;
+ uint8_t status;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.authorize = authorize;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type)
+{
+ struct hci_request rq;
+ gap_set_non_connectable_cp_IDB05A1 cp;
+ uint8_t status;
+
+ cp.advertising_event_type = adv_type;
+ cp.own_address_type = own_address_type;
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_NON_CONNECTABLE;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type)
+{
+ struct hci_request rq;
+ gap_set_non_connectable_cp_IDB04A1 cp;
+ uint8_t status;
+
+ cp.advertising_event_type = adv_type;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_NON_CONNECTABLE;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy)
+{
+ struct hci_request rq;
+ gap_set_undirected_connectable_cp cp;
+ uint8_t status;
+
+ cp.own_addr_type = own_addr_type;
+ cp.adv_filter_policy = adv_filter_policy;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection)
+{
+ struct hci_request rq;
+ gap_slave_security_request_cp cp;
+ uint8_t status;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.bonding = bonding;
+ cp.mitm_protection = mitm_protection;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+
+}
+
+tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData)
+{
+ struct hci_request rq;
+ uint8_t status;
+ uint8_t buffer[32];
+ uint8_t indx = 0;
+
+ if (AdvLen > (sizeof(buffer)-1))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ buffer[indx] = AdvLen;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, AdvData, AdvLen);
+ indx += AdvLen;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_UPDATE_ADV_DATA;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_delete_ad_type(uint8_t ad_type)
+{
+ struct hci_request rq;
+ gap_delete_ad_type_cp cp;
+ uint8_t status;
+
+ cp.ad_type = ad_type;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_DELETE_AD_TYPE;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding,
+ uint8_t* oob_data, uint8_t* passkey_required)
+{
+ struct hci_request rq;
+ gap_get_security_level_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_GET_SECURITY_LEVEL;
+ rq.rparam = &resp;
+ rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *mitm_protection = resp.mitm_protection;
+ *bonding = resp.bonding;
+ *oob_data = resp.oob_data;
+ *passkey_required = resp.passkey_required;
+
+ return resp.status;
+}
+
+tBleStatus aci_gap_configure_whitelist(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_CONFIGURE_WHITELIST;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason)
+{
+ struct hci_request rq;
+ gap_terminate_cp cp;
+ uint8_t status;
+
+ cp.handle = htobs(conn_handle);
+ cp.reason = reason;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_TERMINATE;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_clear_security_database(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_CLEAR_SECURITY_DB;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle)
+{
+ struct hci_request rq;
+ gap_allow_rebond_cp_IDB05A1 cp;
+ uint8_t status;
+
+ cp.conn_handle = conn_handle;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_ALLOW_REBOND_DB;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+tBleStatus aci_gap_allow_rebond_IDB04A1(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_ALLOW_REBOND_DB;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
+ uint8_t own_address_type, uint8_t filterDuplicates)
+{
+ struct hci_request rq;
+ gap_start_limited_discovery_proc_cp cp;
+ uint8_t status;
+
+ cp.scanInterval = htobs(scanInterval);
+ cp.scanWindow = htobs(scanWindow);
+ cp.own_address_type = own_address_type;
+ cp.filterDuplicates = filterDuplicates;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
+ uint8_t own_address_type, uint8_t filterDuplicates)
+{
+ struct hci_request rq;
+ gap_start_general_discovery_proc_cp cp;
+ uint8_t status;
+
+ cp.scanInterval = htobs(scanInterval);
+ cp.scanWindow = htobs(scanWindow);
+ cp.own_address_type = own_address_type;
+ cp.filterDuplicates = filterDuplicates;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+
+tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
+ uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr,
+ uint8_t own_bdaddr_type, uint16_t conn_min_interval,
+ uint16_t conn_max_interval, uint16_t conn_latency,
+ uint16_t supervision_timeout, uint16_t min_conn_length,
+ uint16_t max_conn_length)
+{
+ struct hci_request rq;
+ gap_start_name_discovery_proc_cp cp;
+ uint8_t status;
+
+ cp.scanInterval = htobs(scanInterval);
+ cp.scanWindow = htobs(scanWindow);
+ cp.peer_bdaddr_type = peer_bdaddr_type;
+ Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6);
+ cp.own_bdaddr_type = own_bdaddr_type;
+ cp.conn_min_interval = htobs(conn_min_interval);
+ cp.conn_max_interval = htobs(conn_max_interval);
+ cp.conn_latency = htobs(conn_latency);
+ cp.supervision_timeout = htobs(supervision_timeout);
+ cp.min_conn_length = htobs(min_conn_length);
+ cp.max_conn_length = htobs(max_conn_length);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow,
+ uint8_t own_bdaddr_type, uint16_t conn_min_interval,
+ uint16_t conn_max_interval, uint16_t conn_latency,
+ uint16_t supervision_timeout, uint16_t min_conn_length,
+ uint16_t max_conn_length,
+ uint8_t num_whitelist_entries,
+ const uint8_t *addr_array)
+{
+ struct hci_request rq;
+ uint8_t status;
+ uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+ uint8_t indx = 0;
+
+ if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE)
+ return BLE_STATUS_INVALID_PARAMS;
+
+ scanInterval = htobs(scanInterval);
+ Osal_MemCpy(buffer + indx, &scanInterval, 2);
+ indx += 2;
+
+ scanWindow = htobs(scanWindow);
+ Osal_MemCpy(buffer + indx, &scanWindow, 2);
+ indx += 2;
+
+ buffer[indx] = own_bdaddr_type;
+ indx++;
+
+ conn_min_interval = htobs(conn_min_interval);
+ Osal_MemCpy(buffer + indx, &conn_min_interval, 2);
+ indx += 2;
+
+ conn_max_interval = htobs(conn_max_interval);
+ Osal_MemCpy(buffer + indx, &conn_max_interval, 2);
+ indx += 2;
+
+ conn_latency = htobs(conn_latency);
+ Osal_MemCpy(buffer + indx, &conn_latency, 2);
+ indx += 2;
+
+ supervision_timeout = htobs(supervision_timeout);
+ Osal_MemCpy(buffer + indx, &supervision_timeout, 2);
+ indx += 2;
+
+ min_conn_length = htobs(min_conn_length);
+ Osal_MemCpy(buffer + indx, &min_conn_length, 2);
+ indx += 2;
+
+ max_conn_length = htobs(max_conn_length);
+ Osal_MemCpy(buffer + indx, &max_conn_length, 2);
+ indx += 2;
+
+ buffer[indx] = num_whitelist_entries;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7));
+ indx += num_whitelist_entries * 7;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow,
+ uint8_t own_bdaddr_type, uint16_t conn_min_interval,
+ uint16_t conn_max_interval, uint16_t conn_latency,
+ uint16_t supervision_timeout, uint16_t min_conn_length,
+ uint16_t max_conn_length,
+ uint8_t use_reconn_addr,
+ const tBDAddr reconn_addr,
+ uint8_t num_whitelist_entries,
+ const uint8_t *addr_array)
+{
+ struct hci_request rq;
+ uint8_t status;
+ uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+ uint8_t indx = 0;
+
+ if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE)
+ return BLE_STATUS_INVALID_PARAMS;
+
+ scanInterval = htobs(scanInterval);
+ Osal_MemCpy(buffer + indx, &scanInterval, 2);
+ indx += 2;
+
+ scanWindow = htobs(scanWindow);
+ Osal_MemCpy(buffer + indx, &scanWindow, 2);
+ indx += 2;
+
+ buffer[indx] = own_bdaddr_type;
+ indx++;
+
+ conn_min_interval = htobs(conn_min_interval);
+ Osal_MemCpy(buffer + indx, &conn_min_interval, 2);
+ indx += 2;
+
+ conn_max_interval = htobs(conn_max_interval);
+ Osal_MemCpy(buffer + indx, &conn_max_interval, 2);
+ indx += 2;
+
+ conn_latency = htobs(conn_latency);
+ Osal_MemCpy(buffer + indx, &conn_latency, 2);
+ indx += 2;
+
+ supervision_timeout = htobs(supervision_timeout);
+ Osal_MemCpy(buffer + indx, &supervision_timeout, 2);
+ indx += 2;
+
+ min_conn_length = htobs(min_conn_length);
+ Osal_MemCpy(buffer + indx, &min_conn_length, 2);
+ indx += 2;
+
+ max_conn_length = htobs(max_conn_length);
+ Osal_MemCpy(buffer + indx, &max_conn_length, 2);
+ indx += 2;
+
+ buffer[indx] = use_reconn_addr;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, reconn_addr, 6);
+ indx += 6;
+
+ buffer[indx] = num_whitelist_entries;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7));
+ indx += num_whitelist_entries * 7;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window,
+ uint8_t own_address_type, uint8_t filter_duplicates)
+{
+ struct hci_request rq;
+ gap_start_general_conn_establish_proc_cp_IDB05A1 cp;
+ uint8_t status;
+
+ cp.scan_type = scan_type;
+ cp.scan_interval = htobs(scan_interval);
+ cp.scan_window = htobs(scan_window);
+ cp.own_address_type = own_address_type;
+ cp.filter_duplicates = filter_duplicates;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window,
+ uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr)
+{
+ struct hci_request rq;
+ gap_start_general_conn_establish_proc_cp_IDB04A1 cp;
+ uint8_t status;
+
+ cp.scan_type = scan_type;
+ cp.scan_interval = htobs(scan_interval);
+ cp.scan_window = htobs(scan_window);
+ cp.own_address_type = own_address_type;
+ cp.filter_duplicates = filter_duplicates;
+ cp.use_reconn_addr = use_reconn_addr;
+ Osal_MemCpy(cp.reconn_addr, reconn_addr, 6);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window,
+ uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries,
+ const uint8_t *addr_array)
+{
+ struct hci_request rq;
+ gap_start_selective_conn_establish_proc_cp cp;
+ uint8_t status;
+
+ if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE)
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.scan_type = scan_type;
+ cp.scan_interval = htobs(scan_interval);
+ cp.scan_window = htobs(scan_window);
+ cp.own_address_type = own_address_type;
+ cp.filter_duplicates = filter_duplicates;
+ cp.num_whitelist_entries = num_whitelist_entries;
+
+ Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC;
+ rq.cparam = &cp;
+ rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow,
+ uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr,
+ uint8_t own_bdaddr_type, uint16_t conn_min_interval,
+ uint16_t conn_max_interval, uint16_t conn_latency,
+ uint16_t supervision_timeout, uint16_t min_conn_length,
+ uint16_t max_conn_length)
+{
+ struct hci_request rq;
+ gap_create_connection_cp cp;
+ uint8_t status;
+
+ cp.scanInterval = htobs(scanInterval);
+ cp.scanWindow = htobs(scanWindow);
+ cp.peer_bdaddr_type = peer_bdaddr_type;
+ Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6);
+ cp.own_bdaddr_type = own_bdaddr_type;
+ cp.conn_min_interval = htobs(conn_min_interval);
+ cp.conn_max_interval = htobs(conn_max_interval);
+ cp.conn_latency = htobs(conn_latency);
+ cp.supervision_timeout = htobs(supervision_timeout);
+ cp.min_conn_length = htobs(min_conn_length);
+ cp.max_conn_length = htobs(max_conn_length);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_CREATE_CONNECTION;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE;
+ rq.cparam = &procedure_code;
+ rq.clen = 1;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+
+}
+
+tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval,
+ uint16_t conn_max_interval, uint16_t conn_latency,
+ uint16_t supervision_timeout, uint16_t min_conn_length,
+ uint16_t max_conn_length)
+{
+ struct hci_request rq;
+ gap_start_connection_update_cp cp;
+ uint8_t status;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.conn_min_interval = htobs(conn_min_interval);
+ cp.conn_max_interval = htobs(conn_max_interval);
+ cp.conn_latency = htobs(conn_latency);
+ cp.supervision_timeout = htobs(supervision_timeout);
+ cp.min_conn_length = htobs(min_conn_length);
+ cp.max_conn_length = htobs(max_conn_length);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_START_CONNECTION_UPDATE;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond)
+{
+ struct hci_request rq;
+ gap_send_pairing_request_cp cp;
+ uint8_t status;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.force_rebond = force_rebond;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address)
+{
+ struct hci_request rq;
+ gap_resolve_private_address_cp cp;
+ gap_resolve_private_address_rp rp;
+
+ Osal_MemCpy(cp.address, private_address, 6);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &rp;
+ rq.rlen = sizeof(rp);
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if(rp.status)
+ return rp.status;
+
+ Osal_MemCpy(actual_address, rp.address, 6);
+
+ return 0;
+}
+tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address)
+{
+ struct hci_request rq;
+ gap_resolve_private_address_cp cp;
+ uint8_t status;
+
+ Osal_MemCpy(cp.address, address, 6);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type,
+ uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries,
+ const uint8_t *addr_array)
+{
+ struct hci_request rq;
+ gap_set_broadcast_mode_cp cp;
+ uint8_t status;
+ uint8_t indx = 0;
+ uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7;
+
+ if (variable_size > sizeof(cp.var_len_data) )
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.adv_interv_min = htobs(adv_interv_min);
+ cp.adv_interv_max = htobs(adv_interv_max);
+ cp.adv_type = adv_type;
+ cp.own_addr_type = own_addr_type;
+
+ cp.var_len_data[indx] = adv_data_length;
+ indx++;
+ Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length);
+ indx += adv_data_length;
+ cp.var_len_data[indx] = num_whitelist_entries;
+ indx ++;
+ Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_BROADCAST_MODE;
+ rq.cparam = &cp;
+ rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type,
+ uint8_t own_address_type, uint8_t filter_duplicates)
+{
+ struct hci_request rq;
+ gap_start_observation_proc_cp cp;
+ uint8_t status;
+
+ cp.scan_interval = scan_interval;
+ cp.scan_window = scan_window;
+ cp.scan_type = scan_type;
+ cp.own_address_type = own_address_type;
+ cp.filter_duplicates = filter_duplicates;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_START_OBSERVATION_PROC;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address)
+{
+ struct hci_request rq;
+ gap_is_device_bonded_cp cp;
+ uint8_t status;
+
+ cp.peer_address_type = peer_address_type;
+ Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_IS_DEVICE_BONDED;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size)
+{
+ struct hci_request rq;
+ gap_get_bonded_devices_rp rp;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_GET_BONDED_DEVICES;
+ rq.rparam = &rp;
+ rq.rlen = sizeof(rp);
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (rp.status) {
+ return rp.status;
+ }
+
+ *num_devices = rp.num_addr;
+ if(device_list != NULL)
+ Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7));
+
+ return 0;
+}
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,1471 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name : bluenrg_gatt_aci.c
+* Author : AMS - AAS
+* Version : V1.0.0
+* Date : 26-Jun-2014
+* Description : File with GATT commands for BlueNRG FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#include "ble_hal_types.h"
+#include "ble_osal.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_hci_const.h"
+#include "bluenrg_aci_const.h"
+#include "bluenrg_gatt_aci.h"
+#include "bluenrg_gatt_server.h"
+#include "bluenrg_gap.h"
+
+#define MIN(a,b) ((a) < (b) )? (a) : (b)
+#define MAX(a,b) ((a) > (b) )? (a) : (b)
+
+
+tBleStatus aci_gatt_init(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_INIT;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle)
+{
+ struct hci_request rq;
+ gatt_add_serv_rp resp;
+ uint8_t buffer[19];
+ uint8_t uuid_len;
+ uint8_t indx = 0;
+
+ buffer[indx] = service_uuid_type;
+ indx++;
+
+ if(service_uuid_type == UUID_TYPE_16){
+ uuid_len = 2;
+ }
+ else {
+ uuid_len = 16;
+ }
+ Osal_MemCpy(buffer + indx, service_uuid, uuid_len);
+ indx += uuid_len;
+
+ buffer[indx] = service_type;
+ indx++;
+
+ buffer[indx] = max_attr_records;
+ indx++;
+
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_ADD_SERV;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.rparam = &resp;
+ rq.rlen = GATT_ADD_SERV_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *serviceHandle = btohs(resp.handle);
+
+ return 0;
+}
+
+tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle,
+ uint16_t included_end_handle, uint8_t included_uuid_type,
+ const uint8_t* included_uuid, uint16_t *included_handle)
+{
+ struct hci_request rq;
+ gatt_include_serv_rp resp;
+ uint8_t buffer[23];
+ uint8_t uuid_len;
+ uint8_t indx = 0;
+
+ service_handle = htobs(service_handle);
+ Osal_MemCpy(buffer, &service_handle, 2);
+ indx += 2;
+
+ included_start_handle = htobs(included_start_handle);
+ Osal_MemCpy(buffer+indx, &included_start_handle, 2);
+ indx += 2;
+
+ included_end_handle = htobs(included_end_handle);
+ Osal_MemCpy(buffer+indx, &included_end_handle, 2);
+ indx += 2;
+
+ if(included_uuid_type == UUID_TYPE_16){
+ uuid_len = 2;
+ } else {
+ uuid_len = 16;
+ }
+
+ buffer[indx] = included_uuid_type;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, included_uuid, uuid_len);
+ indx += uuid_len;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_INCLUDE_SERV;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.rparam = &resp;
+ rq.rlen = GATT_INCLUDE_SERV_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *included_handle = btohs(resp.handle);
+
+ return 0;
+}
+
+tBleStatus aci_gatt_add_char(uint16_t serviceHandle,
+ uint8_t charUuidType,
+ const uint8_t* charUuid,
+ uint8_t charValueLen,
+ uint8_t charProperties,
+ uint8_t secPermissions,
+ uint8_t gattEvtMask,
+ uint8_t encryKeySize,
+ uint8_t isVariable,
+ uint16_t* charHandle)
+{
+ struct hci_request rq;
+ gatt_add_serv_rp resp;
+ uint8_t buffer[25];
+ uint8_t uuid_len;
+ uint8_t indx = 0;
+
+ serviceHandle = htobs(serviceHandle);
+ Osal_MemCpy(buffer + indx, &serviceHandle, 2);
+ indx += 2;
+
+ buffer[indx] = charUuidType;
+ indx++;
+
+ if(charUuidType == UUID_TYPE_16){
+ uuid_len = 2;
+ }
+ else {
+ uuid_len = 16;
+ }
+ Osal_MemCpy(buffer + indx, charUuid, uuid_len);
+ indx += uuid_len;
+
+ buffer[indx] = charValueLen;
+ indx++;
+
+ buffer[indx] = charProperties;
+ indx++;
+
+ buffer[indx] = secPermissions;
+ indx++;
+
+ buffer[indx] = gattEvtMask;
+ indx++;
+
+ buffer[indx] = encryKeySize;
+ indx++;
+
+ buffer[indx] = isVariable;
+ indx++;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_ADD_CHAR;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.rparam = &resp;
+ rq.rlen = GATT_ADD_CHAR_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *charHandle = btohs(resp.handle);
+
+ return 0;
+}
+
+tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle,
+ uint16_t charHandle,
+ uint8_t descUuidType,
+ const uint8_t* uuid,
+ uint8_t descValueMaxLen,
+ uint8_t descValueLen,
+ const void* descValue,
+ uint8_t secPermissions,
+ uint8_t accPermissions,
+ uint8_t gattEvtMask,
+ uint8_t encryKeySize,
+ uint8_t isVariable,
+ uint16_t* descHandle)
+{
+ struct hci_request rq;
+ gatt_add_char_desc_rp resp;
+ uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+ uint8_t uuid_len;
+ uint8_t indx = 0;
+
+ serviceHandle = htobs(serviceHandle);
+ Osal_MemCpy(buffer + indx, &serviceHandle, 2);
+ indx += 2;
+
+ charHandle = htobs(charHandle);
+ Osal_MemCpy(buffer + indx, &charHandle, 2);
+ indx += 2;
+
+ buffer[indx] = descUuidType;
+ indx++;
+
+ if(descUuidType == UUID_TYPE_16){
+ uuid_len = 2;
+ }
+ else {
+ uuid_len = 16;
+ }
+ Osal_MemCpy(buffer + indx, uuid, uuid_len);
+ indx += uuid_len;
+
+ buffer[indx] = descValueMaxLen;
+ indx++;
+
+ buffer[indx] = descValueLen;
+ indx++;
+
+ if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE)
+ return BLE_STATUS_INVALID_PARAMS;
+
+ Osal_MemCpy(buffer + indx, descValue, descValueLen);
+ indx += descValueLen;
+
+ buffer[indx] = secPermissions;
+ indx++;
+
+ buffer[indx] = accPermissions;
+ indx++;
+
+ buffer[indx] = gattEvtMask;
+ indx++;
+
+ buffer[indx] = encryKeySize;
+ indx++;
+
+ buffer[indx] = isVariable;
+ indx++;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_ADD_CHAR_DESC;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.rparam = &resp;
+ rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (resp.status) {
+ return resp.status;
+ }
+
+ *descHandle = btohs(resp.handle);
+
+ return 0;
+}
+
+
+tBleStatus aci_gatt_update_char_value(uint16_t servHandle,
+ uint16_t charHandle,
+ uint8_t charValOffset,
+ uint8_t charValueLen,
+ const void *charValue)
+{
+ struct hci_request rq;
+ uint8_t status;
+ uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+ uint8_t indx = 0;
+
+ if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE)
+ return BLE_STATUS_INVALID_PARAMS;
+
+ servHandle = htobs(servHandle);
+ Osal_MemCpy(buffer + indx, &servHandle, 2);
+ indx += 2;
+
+ charHandle = htobs(charHandle);
+ Osal_MemCpy(buffer + indx, &charHandle, 2);
+ indx += 2;
+
+ buffer[indx] = charValOffset;
+ indx++;
+
+ buffer[indx] = charValueLen;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, charValue, charValueLen);
+ indx += charValueLen;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_UPD_CHAR_VAL;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (status) {
+ return status;
+ }
+
+ return 0;
+}
+
+tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_del_char_cp cp;
+
+ cp.service_handle = htobs(servHandle);
+ cp.char_handle = htobs(charHandle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_DEL_CHAR;
+ rq.cparam = &cp;
+ rq.clen = GATT_DEL_CHAR_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_del_service(uint16_t servHandle)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_del_serv_cp cp;
+
+ cp.service_handle = htobs(servHandle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_DEL_SERV;
+ rq.cparam = &cp;
+ rq.clen = GATT_DEL_SERV_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_del_inc_serv_cp cp;
+
+ cp.service_handle = htobs(servHandle);
+ cp.inc_serv_handle = htobs(includeServHandle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_DEL_INC_SERV;
+ rq.cparam = &cp;
+ rq.clen = GATT_DEL_INC_SERV_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_set_event_mask(uint32_t event_mask)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_set_evt_mask_cp cp;
+
+ cp.evt_mask = htobs(event_mask);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_SET_EVT_MASK;
+ rq.cparam = &cp;
+ rq.clen = GATT_SET_EVT_MASK_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_exchange_config_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_EXCHANGE_CONFIG;
+ rq.cparam = &cp;
+ rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle)
+{
+ struct hci_request rq;
+ uint8_t status;
+ att_find_info_req_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.start_handle = htobs(start_handle);
+ cp.end_handle = htobs(end_handle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_ATT_FIND_INFO_REQ;
+ rq.cparam = &cp;
+ rq.clen = ATT_FIND_INFO_REQ_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+ uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val)
+{
+ struct hci_request rq;
+ uint8_t status;
+ att_find_by_type_value_req_cp cp;
+
+ if(attr_val_len > sizeof(cp.attr_val))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.start_handle = htobs(start_handle);
+ cp.end_handle = htobs(end_handle);
+ Osal_MemCpy(cp.uuid, uuid, 2);
+ cp.attr_val_len = attr_val_len;
+ Osal_MemCpy(cp.attr_val, attr_val, attr_val_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ;
+ rq.cparam = &cp;
+ rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+ uint8_t uuid_type, uint8_t* uuid)
+{
+ struct hci_request rq;
+ uint8_t status;
+ att_read_by_type_req_cp cp;
+ uint8_t uuid_len;
+
+ if(uuid_type == UUID_TYPE_16){
+ uuid_len = 2;
+ }
+ else{
+ uuid_len = 16;
+ }
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.start_handle = htobs(start_handle);
+ cp.end_handle = htobs(end_handle);
+ cp.uuid_type = uuid_type;
+ Osal_MemCpy(cp.uuid, uuid, uuid_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_ATT_READ_BY_TYPE_REQ;
+ rq.cparam = &cp;
+ rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+ uint8_t uuid_type, uint8_t* uuid)
+{
+ struct hci_request rq;
+ uint8_t status;
+ att_read_by_group_type_req_cp cp;
+ uint8_t uuid_len;
+
+ if(uuid_type == UUID_TYPE_16){
+ uuid_len = 2;
+ }
+ else{
+ uuid_len = 16;
+ }
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.start_handle = htobs(start_handle);
+ cp.end_handle = htobs(end_handle);
+ cp.uuid_type = uuid_type;
+ Osal_MemCpy(cp.uuid, uuid, uuid_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ;
+ rq.cparam = &cp;
+ rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset,
+ uint8_t attr_val_len, uint8_t* attr_val)
+{
+ struct hci_request rq;
+ uint8_t status;
+ att_prepare_write_req_cp cp;
+
+ if(attr_val_len > sizeof(cp.attr_val))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.attr_handle = htobs(attr_handle);
+ cp.value_offset = htobs(value_offset);
+ cp.attr_val_len = attr_val_len;
+ Osal_MemCpy(cp.attr_val, attr_val, attr_val_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_ATT_PREPARE_WRITE_REQ;
+ rq.cparam = &cp;
+ rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute)
+{
+ struct hci_request rq;
+ uint8_t status;
+ att_execute_write_req_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.execute = execute;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ;
+ rq.cparam = &cp;
+ rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_disc_all_prim_services_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES;
+ rq.cparam = &cp;
+ rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_disc_prim_service_by_uuid_cp cp;
+ uint8_t uuid_len;
+
+ if(uuid_type == UUID_TYPE_16){
+ uuid_len = 2;
+ }
+ else{
+ uuid_len = 16;
+ }
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.uuid_type = uuid_type;
+ Osal_MemCpy(cp.uuid, uuid, uuid_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID;
+ rq.cparam = &cp;
+ rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle,
+ uint16_t end_service_handle)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_find_included_services_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.start_handle = htobs(start_service_handle);
+ cp.end_handle = htobs(end_service_handle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES;
+ rq.cparam = &cp;
+ rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle,
+ uint16_t end_attr_handle)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_disc_all_charac_of_serv_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.start_attr_handle = htobs(start_attr_handle);
+ cp.end_attr_handle = htobs(end_attr_handle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV;
+ rq.cparam = &cp;
+ rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle,
+ uint16_t end_handle, uint8_t charUuidType,
+ const uint8_t* charUuid)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ uint8_t buffer[23];
+ uint8_t uuid_len;
+ uint8_t indx = 0;
+
+ conn_handle = htobs(conn_handle);
+ Osal_MemCpy(buffer + indx, &conn_handle, 2);
+ indx += 2;
+
+ start_handle = htobs(start_handle);
+ Osal_MemCpy(buffer + indx, &start_handle, 2);
+ indx += 2;
+
+ end_handle = htobs(end_handle);
+ Osal_MemCpy(buffer + indx, &end_handle, 2);
+ indx += 2;
+
+ buffer[indx] = charUuidType;
+ indx++;
+
+ if(charUuidType == 0x01){
+ uuid_len = 2;
+ }
+ else {
+ uuid_len = 16;
+ }
+ Osal_MemCpy(buffer + indx, charUuid, uuid_len);
+ indx += uuid_len;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle,
+ uint16_t char_end_handle)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_disc_all_charac_descriptors_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.char_val_handle = htobs(char_val_handle);
+ cp.char_end_handle = htobs(char_end_handle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS;
+ rq.cparam = &cp;
+ rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_read_charac_val_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.attr_handle = htobs(attr_handle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_READ_CHARAC_VAL;
+ rq.cparam = &cp;
+ rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+ uint8_t uuid_type, uint8_t* uuid)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_read_using_charac_uuid_cp cp;
+ uint8_t uuid_len;
+
+ if(uuid_type == UUID_TYPE_16){
+ uuid_len = 2;
+ }
+ else{
+ uuid_len = 16;
+ }
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.start_handle = htobs(start_handle);
+ cp.end_handle = htobs(end_handle);
+ cp.uuid_type = uuid_type;
+ Osal_MemCpy(cp.uuid, uuid, uuid_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID;
+ rq.cparam = &cp;
+ rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle,
+ uint16_t val_offset)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_read_long_charac_val_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.attr_handle = htobs(attr_handle);
+ cp.val_offset = htobs(val_offset);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL;
+ rq.cparam = &cp;
+ rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles,
+ uint8_t* set_of_handles)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_read_multiple_charac_val_cp cp;
+
+ if(num_handles*2 > sizeof(cp.set_of_handles))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.num_handles = htobs(num_handles);
+ Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL;
+ rq.cparam = &cp;
+ rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+
+
+tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle,
+ uint8_t value_len, uint8_t *attr_value)
+{
+ struct hci_request rq;
+ uint8_t status;
+ uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+ uint8_t indx = 0;
+
+ if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE)
+ return BLE_STATUS_INVALID_PARAMS;
+
+ conn_handle = htobs(conn_handle);
+ Osal_MemCpy(buffer + indx, &conn_handle, 2);
+ indx += 2;
+
+ attr_handle = htobs(attr_handle);
+ Osal_MemCpy(buffer + indx, &attr_handle, 2);
+ indx += 2;
+
+ buffer[indx] = value_len;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, attr_value, value_len);
+ indx += value_len;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_WRITE_CHAR_VALUE;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle,
+ uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_write_long_charac_val_cp cp;
+
+ if(val_len > sizeof(cp.attr_val))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.attr_handle = htobs(attr_handle);
+ cp.val_offset = htobs(val_offset);
+ cp.val_len = val_len;
+ Osal_MemCpy(cp.attr_val, attr_val, val_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL;
+ rq.cparam = &cp;
+ rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle,
+ uint16_t val_offset, uint8_t val_len, uint8_t* attr_val)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_write_charac_reliable_cp cp;
+
+ if(val_len > sizeof(cp.attr_val))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.attr_handle = htobs(attr_handle);
+ cp.val_offset = htobs(val_offset);
+ cp.val_len = val_len;
+ Osal_MemCpy(cp.attr_val, attr_val, val_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE;
+ rq.cparam = &cp;
+ rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle,
+ uint16_t val_offset, uint8_t val_len, uint8_t* attr_val)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_write_charac_reliable_cp cp;
+
+ if(val_len > sizeof(cp.attr_val))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.attr_handle = htobs(attr_handle);
+ cp.val_offset = htobs(val_offset);
+ cp.val_len = val_len;
+ Osal_MemCpy(cp.attr_val, attr_val, val_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC;
+ rq.cparam = &cp;
+ rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle,
+ uint16_t val_offset)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_read_long_charac_desc_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.attr_handle = htobs(attr_handle);
+ cp.val_offset = htobs(val_offset);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC;
+ rq.cparam = &cp;
+ rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle,
+ uint8_t value_len, uint8_t *attr_value)
+{
+ struct hci_request rq;
+ uint8_t status;
+ uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+ uint8_t indx = 0;
+
+ if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE)
+ return BLE_STATUS_INVALID_PARAMS;
+
+ conn_handle = htobs(conn_handle);
+ Osal_MemCpy(buffer + indx, &conn_handle, 2);
+ indx += 2;
+
+ attr_handle = htobs(attr_handle);
+ Osal_MemCpy(buffer + indx, &attr_handle, 2);
+ indx += 2;
+
+ buffer[indx] = value_len;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, attr_value, value_len);
+ indx += value_len;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_read_long_charac_desc_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.attr_handle = htobs(attr_handle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR;
+ rq.cparam = &cp;
+ rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle,
+ uint8_t val_len, const uint8_t* attr_val)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_write_without_resp_cp cp;
+
+ if(val_len > sizeof(cp.attr_val))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.attr_handle = htobs(attr_handle);
+ cp.val_len = val_len;
+ Osal_MemCpy(cp.attr_val, attr_val, val_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE;
+ rq.cparam = &cp;
+ rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle,
+ uint8_t val_len, uint8_t* attr_val)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_signed_write_without_resp_cp cp;
+
+ if(val_len > sizeof(cp.attr_val))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.attr_handle = htobs(attr_handle);
+ cp.val_len = val_len;
+ Osal_MemCpy(cp.attr_val, attr_val, val_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE;
+ rq.cparam = &cp;
+ rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle)
+{
+ struct hci_request rq;
+ uint8_t status;
+ gatt_confirm_indication_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_CONFIRM_INDICATION;
+ rq.cparam = &cp;
+ rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_write_response(uint16_t conn_handle,
+ uint16_t attr_handle,
+ uint8_t write_status,
+ uint8_t err_code,
+ uint8_t att_val_len,
+ uint8_t *att_val)
+{
+ struct hci_request rq;
+ uint8_t status;
+ uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+ uint8_t indx = 0;
+
+ if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE)
+ return BLE_STATUS_INVALID_PARAMS;
+
+ conn_handle = htobs(conn_handle);
+ Osal_MemCpy(buffer + indx, &conn_handle, 2);
+ indx += 2;
+
+ attr_handle = htobs(attr_handle);
+ Osal_MemCpy(buffer + indx, &attr_handle, 2);
+ indx += 2;
+
+ buffer[indx] = write_status;
+ indx += 1;
+
+ buffer[indx] = err_code;
+ indx += 1;
+
+ buffer[indx] = att_val_len;
+ indx += 1;
+
+ Osal_MemCpy(buffer + indx, att_val, att_val_len);
+ indx += att_val_len;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_WRITE_RESPONSE;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (status) {
+ return status;
+ }
+
+ return 0;
+}
+
+tBleStatus aci_gatt_allow_read(uint16_t conn_handle)
+{
+ struct hci_request rq;
+ gatt_allow_read_cp cp;
+ uint8_t status;
+
+ cp.conn_handle = htobs(conn_handle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_ALLOW_READ;
+ rq.cparam = &cp;
+ rq.clen = GATT_ALLOW_READ_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle,
+ uint8_t security_permission)
+{
+ struct hci_request rq;
+ gatt_set_security_permission_cp cp;
+ uint8_t status;
+
+ cp.service_handle = htobs(service_handle);
+ cp.attr_handle = htobs(attr_handle);
+ cp.security_permission = security_permission;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION;
+ rq.cparam = &cp;
+ rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_set_desc_value(uint16_t servHandle,
+ uint16_t charHandle,
+ uint16_t charDescHandle,
+ uint16_t charDescValOffset,
+ uint8_t charDescValueLen,
+ const void *charDescValue)
+{
+ struct hci_request rq;
+ uint8_t status;
+ uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+ uint8_t indx = 0;
+
+ if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE)
+ return BLE_STATUS_INVALID_PARAMS;
+
+ servHandle = htobs(servHandle);
+ Osal_MemCpy(buffer + indx, &servHandle, 2);
+ indx += 2;
+
+ charHandle = htobs(charHandle);
+ Osal_MemCpy(buffer + indx, &charHandle, 2);
+ indx += 2;
+
+ charDescHandle = htobs(charDescHandle);
+ Osal_MemCpy(buffer + indx, &charDescHandle, 2);
+ indx += 2;
+
+ Osal_MemCpy(buffer + indx, &charDescValOffset, 2);
+ indx += 2;
+
+ buffer[indx] = charDescValueLen;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen);
+ indx += charDescValueLen;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_SET_DESC_VAL;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data)
+{
+ struct hci_request rq;
+ gatt_read_handle_val_cp cp;
+ gatt_read_handle_val_rp rp;
+
+ if(data_len > sizeof(rp.value))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.attr_handle = htobs(attr_handle);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_READ_HANDLE_VALUE;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &rp;
+ rq.rlen = sizeof(rp);
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if(rp.status)
+ return rp.status;
+
+ *data_len_out_p = btohs(rp.value_len);
+
+ Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p));
+
+ return 0;
+}
+
+tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data)
+{
+ struct hci_request rq;
+ gatt_read_handle_val_offset_cp cp;
+ gatt_read_handle_val_offset_rp rp;
+
+ if(data_len > sizeof(rp.value))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.attr_handle = htobs(attr_handle);
+ cp.offset = offset;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &rp;
+ rq.rlen = sizeof(rp);
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if(rp.status)
+ return rp.status;
+
+ *data_len_out_p = rp.value_len;
+
+ Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p));
+
+ return 0;
+}
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,183 @@
+/******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
+* File Name : bluenrg_hci.c
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 4-Oct-2013
+* Description : File with HCI commands for BlueNRG FW6.0 and above.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#include "ble_hal_types.h"
+#include "ble_osal.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_osal.h"
+#include "ble_hci_const.h"
+#include "bluenrg_aci_const.h"
+#include "bluenrg_hal_aci.h"
+#include "bluenrg_gatt_server.h"
+#include "bluenrg_gap.h"
+
+#define MIN(a,b) ((a) < (b) )? (a) : (b)
+#define MAX(a,b) ((a) > (b) )? (a) : (b)
+
+
+tBleStatus aci_hal_write_config_data(uint8_t offset,
+ uint8_t len,
+ const uint8_t *val)
+{
+ struct hci_request rq;
+ uint8_t status;
+ uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+ uint8_t indx = 0;
+
+ if ((len+2) > HCI_MAX_PAYLOAD_SIZE)
+ return BLE_STATUS_INVALID_PARAMS;
+
+ buffer[indx] = offset;
+ indx++;
+
+ buffer[indx] = len;
+ indx++;
+
+ Osal_MemCpy(buffer + indx, val, len);
+ indx += len;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_HAL_WRITE_CONFIG_DATA;
+ rq.cparam = (void *)buffer;
+ rq.clen = indx;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (status) {
+ return status;
+ }
+
+ 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;
+ hal_set_tx_power_level_cp cp;
+ uint8_t status;
+
+ cp.en_high_power = en_high_power;
+ cp.pa_level = pa_level;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL;
+ rq.cparam = &cp;
+ rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (status) {
+ return status;
+ }
+
+ return 0;
+}
+
+tBleStatus aci_hal_device_standby(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_HAL_DEVICE_STANDBY;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_hal_tone_start(uint8_t rf_channel)
+{
+ struct hci_request rq;
+ hal_tone_start_cp cp;
+ uint8_t status;
+
+ cp.rf_channel = rf_channel;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_HAL_TONE_START;
+ rq.cparam = &cp;
+ rq.clen = HAL_TONE_START_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_hal_tone_stop(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_HAL_TONE_STOP;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+
+
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,118 @@
+/******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
+* File Name : bluenrg_hci.c
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 4-Oct-2013
+* Description : File with HCI commands for BlueNRG FW6.0 and above.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#include "ble_hal_types.h"
+#include "ble_osal.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_osal.h"
+#include "ble_hci_const.h"
+#include "bluenrg_aci_const.h"
+#include "bluenrg_hal_aci.h"
+#include "bluenrg_gap.h"
+
+#define MIN(a,b) ((a) < (b) )? (a) : (b)
+#define MAX(a,b) ((a) > (b) )? (a) : (b)
+
+tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min,
+ uint16_t interval_max, uint16_t slave_latency,
+ uint16_t timeout_multiplier)
+{
+ struct hci_request rq;
+ uint8_t status;
+ l2cap_conn_param_update_req_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.interval_min = htobs(interval_min);
+ cp.interval_max = htobs(interval_max);
+ cp.slave_latency = htobs(slave_latency);
+ cp.timeout_multiplier = htobs(timeout_multiplier);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ;
+ rq.cparam = &cp;
+ rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min,
+ uint16_t interval_max, uint16_t slave_latency,
+ uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length,
+ uint8_t id, uint8_t accept)
+{
+ struct hci_request rq;
+ uint8_t status;
+ l2cap_conn_param_update_resp_cp_IDB05A1 cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.interval_min = htobs(interval_min);
+ cp.interval_max = htobs(interval_max);
+ cp.slave_latency = htobs(slave_latency);
+ cp.timeout_multiplier = htobs(timeout_multiplier);
+ cp.min_ce_length = htobs(min_ce_length);
+ cp.max_ce_length = htobs(max_ce_length);
+ cp.id = id;
+ cp.accept = accept;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min,
+ uint16_t interval_max, uint16_t slave_latency,
+ uint16_t timeout_multiplier, uint8_t id, uint8_t accept)
+{
+ struct hci_request rq;
+ uint8_t status;
+ l2cap_conn_param_update_resp_cp_IDB04A1 cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.interval_min = htobs(interval_min);
+ cp.interval_max = htobs(interval_max);
+ cp.slave_latency = htobs(slave_latency);
+ cp.timeout_multiplier = htobs(timeout_multiplier);
+ cp.id = id;
+ cp.accept = accept;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,270 @@
+/******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
+* File Name : bluenrg_hci.c
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 4-Oct-2013
+* Description : File with HCI commands for BlueNRG FW6.0 and above.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#include "ble_hal_types.h"
+#include "ble_osal.h"
+#include "ble_status.h"
+#include "ble_hal.h"
+#include "ble_osal.h"
+#include "ble_hci_const.h"
+#include "bluenrg_aci_const.h"
+#include "bluenrg_updater_aci.h"
+
+#define MIN(a,b) ((a) < (b) )? (a) : (b)
+#define MAX(a,b) ((a) > (b) )? (a) : (b)
+
+tBleStatus aci_updater_start(void)
+{
+ struct hci_request rq;
+ uint8_t status = 0;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_START;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ hci_send_req(&rq, FALSE); // No command complete is sent.
+
+ return status;
+}
+
+tBleStatus aci_updater_reboot(void)
+{
+ struct hci_request rq;
+ uint8_t status = 0;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_REBOOT;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ hci_send_req(&rq, FALSE); // No command complete is sent.
+
+ return status;
+}
+
+tBleStatus aci_get_updater_version(uint8_t *version)
+{
+ struct hci_request rq;
+ get_updater_version_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GET_UPDATER_VERSION;
+ rq.rparam = &resp;
+ rq.rlen = GET_UPDATER_VERSION_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ *version = resp.version;
+
+ return resp.status;
+}
+
+tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size)
+{
+ struct hci_request rq;
+ get_updater_bufsize_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GET_UPDATER_BUFSIZE;
+ rq.rparam = &resp;
+ rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ *buffer_size = resp.buffer_size;
+
+ return resp.status;
+}
+
+tBleStatus aci_erase_blue_flag(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_reset_blue_flag(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_updater_erase_sector(uint32_t address)
+{
+ struct hci_request rq;
+ updater_erase_sector_cp cp;
+ uint8_t status;
+
+ cp.address = htobl(address);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_ERASE_SECTOR;
+ rq.cparam = &cp;
+ rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_updater_program_data_block(uint32_t address,
+ uint16_t len,
+ const uint8_t *data)
+{
+ struct hci_request rq;
+ uint8_t status;
+ updater_prog_data_block_cp cp;
+
+ if( len > sizeof(cp.data))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.address = htobl(address);
+ cp.data_len = htobs(len);
+ Osal_MemCpy(cp.data, data, len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK;
+ rq.cparam = &cp;
+ rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_updater_read_data_block(uint32_t address,
+ uint16_t data_len,
+ uint8_t *data)
+{
+ struct hci_request rq;
+ updater_read_data_block_cp cp;
+ uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+
+ if((data_len+1) > HCI_MAX_PAYLOAD_SIZE)
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.address = htobl(address);
+ cp.data_len = htobs(data_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_READ_DATA_BLOCK;
+ rq.cparam = &cp;
+ rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE;
+ rq.rparam = buffer;
+ rq.rlen = data_len + 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ // First byte is status
+ Osal_MemCpy(data, buffer+1, data_len);
+
+ return buffer[0];
+}
+
+tBleStatus aci_updater_calc_crc(uint32_t address,
+ uint8_t num_sectors,
+ uint32_t *crc)
+{
+ struct hci_request rq;
+ updater_calc_crc_cp cp;
+ updater_calc_crc_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ cp.address = htobl(address);
+ cp.num_sectors = num_sectors;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_CALC_CRC;
+ rq.cparam = &cp;
+ rq.clen = UPDATER_CALC_CRC_CP_SIZE;
+ rq.rparam = &resp;
+ rq.rlen = UPDATER_CALC_CRC_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ *crc = btohl(resp.crc);
+
+ return resp.status;
+}
+
+tBleStatus aci_updater_hw_version(uint8_t *version)
+{
+ struct hci_request rq;
+ updater_hw_version_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_HW_VERSION;
+ rq.rparam = &resp;
+ rq.rlen = UPDATER_HW_VERSION_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ *version = resp.version;
+
+ return resp.status;
+}
+
+
+
+
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,430 @@
+
+#include "ble_hal.h"
+#include "ble_hal_types.h"
+#include "ble_status.h"
+#include "bluenrg_aci.h"
+#include "bluenrg_utils.h"
+#include "ble_hci.h"
+#include "ble_osal.h"
+#include "string.h"
+#include "stm32_bluenrg_ble.h"
+
+#define SUPPORTED_BOOTLOADER_VERSION_MIN 3
+#define SUPPORTED_BOOTLOADER_VERSION_MAX 5
+
+#define BASE_ADDRESS 0x10010000
+
+#define FW_OFFSET (2*1024) // 2 KB
+#define FW_OFFSET_MS 0
+#define FULL_STACK_SIZE (66*1024) // 66 KB
+#define BOOTLOADER_SIZE (2*1024) // 2 kB
+#define SECTOR_SIZE (2*1024) // 2 KB
+#define DATA_SIZE 64 // 64 bytes
+
+// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 +
+// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0
+#define CRC_POLY 0x04C11DB7 // the poly without the x**32
+
+#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC
+
+#define IFR_SIZE 192
+#define IFR_BASE_ADDRESS 0x10020000
+#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data
+
+#if BLUENRG_MS
+#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET
+#else
+#define IFR_WRITE_OFFSET_BEGIN 0
+#endif
+
+
+#define BLUE_FLAG_OFFSET 0x8C0
+#define MAX_ERASE_RETRIES 2
+#define MAX_WRITE_RETRIES 2
+#define MIN_WRITE_BLOCK_SIZE 4
+
+#define RETRY_COMMAND(func, num_ret, error) \
+{ \
+ uint8_t num_retries; \
+ num_retries = 0; \
+ error = 0; \
+ while (num_retries++ < num_ret) { \
+ if (func == BLE_STATUS_SUCCESS) \
+ break; \
+ if (num_retries == num_ret) \
+ error = BLE_UTIL_ACI_ERROR; \
+ } \
+}
+
+typedef struct{
+ uint8_t cold_ana_act_config_table[64];
+}cold_table_TypeDef;
+
+/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size,
+ they are extended with 0xFF until sector size is reached
+*/
+static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes)
+{
+ uint32_t i, j, a1;
+ uint32_t crc, value;
+
+ crc = 0;
+ for (i = 0; i < SECTOR_SIZE; i += 4) {
+ uint8_t *dataw = (uint8_t *) &value;
+
+ dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF;
+ dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF;
+ dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF;
+ dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF;
+
+ crc = crc ^ value;
+ for (j = 0; j < 32; j ++) {
+ a1 = (crc >> 31) & 0x1;
+ crc = (crc << 1) ^ (a1 * CRC_POLY);
+ }
+ }
+
+ return crc;
+}
+
+int program_device(const uint8_t *fw_image, uint32_t fw_size)
+{
+ uint8_t version, num_erase_retries=0, status, data_size;
+ uint8_t number_sectors, module;
+ uint32_t address, j;
+ uint32_t crc, crc2, crc_size;
+ uint32_t fw_offset = FW_OFFSET;
+
+ BlueNRG_HW_Bootloader();
+ HCI_Process(); // To receive the EVT_INITIALIZED
+
+ if(aci_get_updater_version(&version))
+ return BLE_UTIL_ACI_ERROR;
+
+ if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX)
+ return BLE_UTIL_UNSUPPORTED_VERSION;
+
+ if(aci_updater_hw_version(&version))
+ return BLE_UTIL_ACI_ERROR;
+
+ if(version==0x31){
+ // It does not contain bootloader inside first sector. It may contain code.
+ fw_offset = FW_OFFSET_MS;
+ }
+
+ if (fw_size != FULL_STACK_SIZE)
+ return BLE_UTIL_WRONG_IMAGE_SIZE;
+
+ if (fw_size % MIN_WRITE_BLOCK_SIZE)
+ return BLE_UTIL_WRONG_IMAGE_SIZE;
+
+ /* Calculate the number of sectors necessary to contain the fw image.*/
+ number_sectors = ((fw_size + SECTOR_SIZE - 1) / SECTOR_SIZE);
+
+ /***********************************************************************
+ * Erase BLUE flag
+ ************************************************************************/
+ RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status);
+ if (status != BLE_STATUS_SUCCESS)
+ return status;
+
+ /***********************************************************************
+ * Erase and Program sectors
+ ************************************************************************/
+ for(unsigned int i = fw_offset; i < (number_sectors * SECTOR_SIZE); i += SECTOR_SIZE) {
+ num_erase_retries = 0;
+ while (num_erase_retries++ < MAX_ERASE_RETRIES) {
+ aci_updater_erase_sector(BASE_ADDRESS + i);
+ if ((i/SECTOR_SIZE) < (unsigned int)(number_sectors-1))
+ data_size = DATA_SIZE;
+ else
+ data_size = MIN_WRITE_BLOCK_SIZE;
+ for (j=i; ((j<SECTOR_SIZE+i)&&(j<fw_size)); j += data_size) {
+ RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, data_size, fw_image+j), MAX_WRITE_RETRIES, status);
+ if (status != BLE_STATUS_SUCCESS)
+ break;
+ }
+ if (status == BLE_STATUS_SUCCESS)
+ break;
+ }
+ if (num_erase_retries == MAX_ERASE_RETRIES)
+ return BLE_UTIL_ACI_ERROR;
+ }
+
+ /***********************************************************************
+ * Verify firmware
+ ************************************************************************/
+ module = fw_size % SECTOR_SIZE;
+ crc_size = SECTOR_SIZE;
+ for(int i = fw_offset; i < (number_sectors*SECTOR_SIZE); i += SECTOR_SIZE){
+ address = BASE_ADDRESS + i;
+ if(aci_updater_calc_crc(address, 1, &crc))
+ return BLE_UTIL_ACI_ERROR;
+
+ if ((module != 0) && ((i/SECTOR_SIZE) == (number_sectors-1)))
+ crc_size = module;
+
+ crc2 = updater_calc_crc(fw_image+i,crc_size);
+ if(crc!=crc2)
+ return BLE_UTIL_CRC_ERROR;
+ }
+
+ /***********************************************************************
+ * Write BLUE flag
+ ************************************************************************/
+ RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status);
+ if (status != BLE_STATUS_SUCCESS)
+ return status;
+
+ BlueNRG_RST();
+ HCI_Process(); // To receive the EVT_INITIALIZED
+
+ return BLE_STATUS_SUCCESS;
+}
+
+int read_IFR(uint8_t *data)
+{
+ uint8_t version, offset;
+ tBleStatus ret;
+
+ offset = 0;
+ aci_updater_start();
+ if(aci_get_updater_version(&version))
+ return BLE_UTIL_ACI_ERROR;
+
+ if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX)
+ return BLE_UTIL_UNSUPPORTED_VERSION;
+
+ /***********************************************************************
+ * Reading last 3 IFR 64-byte blocks
+ ************************************************************************/
+ for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += DATA_SIZE){
+ ret = aci_updater_read_data_block(BASE_ADDRESS+i, DATA_SIZE, (data+offset));
+ offset += DATA_SIZE;
+ if(ret) return BLE_UTIL_ACI_ERROR;
+ }
+
+ BlueNRG_RST();
+ HCI_Process(); // To receive the EVT_INITIALIZED
+
+ return BLE_STATUS_SUCCESS;
+
+}
+
+void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config)
+{
+ IFR_config->stack_mode = data[0];
+ IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28);
+ IFR_config->master_sca = data[30];
+ IFR_config->hs_startup_time = LE_TO_HOST_16(data+32);
+ IFR_config->year = BCD_TO_INT(data[41]);
+ IFR_config->month = BCD_TO_INT(data[42]);
+ IFR_config->day = BCD_TO_INT(data[43]);
+}
+
+int IFR_validate(IFR_config2_TypeDef *IFR_config)
+{
+#if BLUENRG_MS
+ if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4)
+#else
+ if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3)
+#endif
+ return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode
+ if(IFR_config->master_sca > 7)
+ return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA
+ if(IFR_config->month > 12 || IFR_config->month < 1)
+ return BLE_UTIL_PARSE_ERROR; // Invalid date
+ if(IFR_config->day > 31 || IFR_config->day < 1)
+ return BLE_UTIL_PARSE_ERROR; // Invalid date
+ if(IFR_config->month > 12 || IFR_config->month < 1)
+ return BLE_UTIL_PARSE_ERROR; // Invalid date
+
+ return BLE_STATUS_SUCCESS;
+}
+
+/* TODO: Function to generate data from given options. */
+
+void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64])
+{
+ data[0] = IFR_config->stack_mode;
+ HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm);
+ data[30] = IFR_config->master_sca;
+ HOST_TO_LE_16(data+32, IFR_config->hs_startup_time);
+ data[41] = INT_TO_BCD(IFR_config->year);
+ data[42] = INT_TO_BCD(IFR_config->month);
+ data[43] = INT_TO_BCD(IFR_config->day);
+}
+
+
+int program_IFR(const IFR_config_TypeDef *ifr_image)
+{
+ uint8_t version, num_erase_retries;
+ tBleStatus ret;
+#if BLUENRG_MS
+ const uint8_t *ifr_data = (uint8_t *)ifr_image;
+#else
+ uint8_t ifr_data[SECTOR_SIZE];
+#endif
+ uint8_t hwVersion;
+ uint16_t fwVersion;
+
+ if(getBlueNRGVersion(&hwVersion, &fwVersion))
+ return BLE_UTIL_ACI_ERROR;
+
+ BlueNRG_HW_Bootloader();
+ HCI_Process(); // To receive the EVT_INITIALIZED
+
+ if(aci_get_updater_version(&version))
+ return BLE_UTIL_ACI_ERROR;
+
+ if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX)
+ return BLE_UTIL_UNSUPPORTED_VERSION;
+
+#ifndef BLUENRG_MS
+ /***********************************************************************
+ * READ IFR data
+ ************************************************************************/
+ for(int i = 0; i < SECTOR_SIZE; i += DATA_SIZE){
+ ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_data+i);
+ if(ret != BLE_STATUS_SUCCESS){
+ return ret;
+ }
+ }
+#endif
+
+ /***********************************************************************
+ * Erase & Flashing IFR sectors
+ ************************************************************************/
+#ifndef BLUENRG_MS
+ Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE);
+#endif
+ num_erase_retries = 0;
+ while (num_erase_retries++ < MAX_ERASE_RETRIES) {
+ aci_updater_erase_sector(IFR_BASE_ADDRESS);
+ for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += DATA_SIZE, j += DATA_SIZE) {
+ RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret);
+ if (ret != BLE_STATUS_SUCCESS)
+ break;
+ }
+ if (ret == BLE_STATUS_SUCCESS)
+ break;
+ }
+ if (num_erase_retries == MAX_ERASE_RETRIES)
+ return BLE_UTIL_ACI_ERROR;
+
+ /***********************************************************************
+ * Verify IFR
+ ************************************************************************/
+ {
+ uint8_t ifr_updated[DATA_SIZE];
+ for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += DATA_SIZE, j += DATA_SIZE){
+ ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_updated);
+ if(ret != BLE_STATUS_SUCCESS){
+ return ret;
+ }
+ if (memcmp(ifr_updated, ifr_data+j, DATA_SIZE) != 0)
+ return BLE_UTIL_WRONG_VERIFY;
+ }
+ }
+
+ BlueNRG_RST();
+ HCI_Process(); // To receive the EVT_INITIALIZED
+
+ return BLE_STATUS_SUCCESS;
+}
+
+uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data)
+{
+ uint8_t ifr_updated[DATA_SIZE];
+ uint8_t version, ret = BLE_STATUS_SUCCESS;
+
+ aci_updater_start();
+ if(aci_get_updater_version(&version))
+ return BLE_UTIL_ACI_ERROR;
+ for(int i = 0; i < IFR_SIZE; i += DATA_SIZE){
+ ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, DATA_SIZE, ifr_updated);
+ if(ret != BLE_STATUS_SUCCESS){
+ return ret;
+ }
+ if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, DATA_SIZE) != 0)
+ {
+ ret = BLE_UTIL_WRONG_VERIFY;
+ break;
+ }
+ }
+
+ BlueNRG_RST();
+ HCI_Process(); // To receive the EVT_INITIALIZED
+
+ return ret;
+}
+
+uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion)
+{
+ uint8_t status;
+ uint8_t hci_version, lmp_pal_version;
+ uint16_t hci_revision, manufacturer_name, lmp_pal_subversion;
+
+ status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version,
+ &manufacturer_name, &lmp_pal_subversion);
+
+ if (status == BLE_STATUS_SUCCESS) {
+ *hwVersion = hci_revision >> 8;
+ *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number
+ *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number
+ *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number
+ }
+
+ return status;
+}
+
+uint8_t getBlueNRGUpdaterVersion(uint8_t *version)
+{
+
+ BlueNRG_HW_Bootloader();
+ HCI_Process(); // To receive the EVT_INITIALIZED
+
+ if(aci_get_updater_version(version))
+ return BLE_UTIL_ACI_ERROR;
+
+ if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX)
+ return BLE_UTIL_UNSUPPORTED_VERSION;
+
+ BlueNRG_RST();
+ HCI_Process(); // To receive the EVT_INITIALIZED
+
+ return BLE_STATUS_SUCCESS;
+}
+
+uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version)
+{
+
+ BlueNRG_HW_Bootloader();
+ HCI_Process(); // To receive the EVT_INITIALIZED
+
+ if(aci_updater_hw_version(version))
+ return BLE_UTIL_ACI_ERROR;
+
+ BlueNRG_RST();
+ HCI_Process(); // To receive the EVT_INITIALIZED
+
+ return BLE_STATUS_SUCCESS;
+}
+
+uint8_t isHWBootloader_Patched(void)
+{
+ uint8_t status, version;
+ uint32_t crc, address = 0x10010000;
+
+ if(aci_get_updater_version(&version))
+ return BLE_UTIL_ACI_ERROR;
+
+ RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status);
+ if (status != BLE_STATUS_SUCCESS)
+ return 0;
+
+ if (crc == BOOTLOADER_CRC_NOT_PATCHED)
+ return 0;
+
+ return 1;
+}
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#include "ble_clock.h"
+#include "ble_gp_timer.h"
+
+/*---------------------------------------------------------------------------*/
+/**
+ * Set a timer.
+ *
+ * This function sets a timer for a time sometime in the
+ * future. The function timer_expired() will evaluate to true after
+ * the timer has expired.
+ *
+ * @param[in] t A pointer to the timer
+ * @param[in] interval The interval before the timer expires.
+ *
+ */
+void
+Timer_Set(struct timer *t, tClockTime interval)
+{
+ t->interval = interval;
+ t->start = Clock_Time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Reset the timer with the same interval.
+ *
+ * This function resets the timer with the same interval that was
+ * given to the timer_set() function. The start point of the interval
+ * is the exact time that the timer last expired. Therefore, this
+ * function will cause the timer to be stable over time, unlike the
+ * timer_restart() function.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa timer_restart()
+ */
+void
+Timer_Reset(struct timer *t)
+{
+ t->start += t->interval;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Restart the timer from the current point in time
+ *
+ * This function restarts a timer with the same interval that was
+ * given to the timer_set() function. The timer will start at the
+ * current time.
+ *
+ * \note A periodic timer will drift if this function is used to reset
+ * it. For preioric timers, use the timer_reset() function instead.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa timer_reset()
+ */
+void
+Timer_Restart(struct timer *t)
+{
+ t->start = Clock_Time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Check if a timer has expired.
+ *
+ * This function tests if a timer has expired and returns true or
+ * false depending on its status.
+ *
+ * \param t A pointer to the timer
+ *
+ * \return Non-zero if the timer has expired, zero otherwise.
+ *
+ */
+int
+Timer_Expired(struct timer *t)
+{
+ /* Note: Can not return diff >= t->interval so we add 1 to diff and return
+ t->interval < diff - required to avoid an internal error in mspgcc. */
+ tClockTime diff = (Clock_Time() - t->start) + 1;
+ return t->interval < diff;
+
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * The time until the timer expires
+ *
+ * This function returns the time until the timer expires.
+ *
+ * \param t A pointer to the timer
+ *
+ * \return The time until the timer expires
+ *
+ */
+tClockTime
+Timer_Remaining(struct timer *t)
+{
+ return t->start + t->interval - Clock_Time();
+}
+/*---------------------------------------------------------------------------*/
+#ifdef __DMA_LP__
+
+tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime,
+ TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb,
+ uint8_t *timerID)
+{
+ TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot,
+ (pf_TIMER_TimerCallBack_t) timercb);
+ TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE);
+
+ return (BLE_STATUS_SUCCESS);
+}
+
+/*---------------------------------------------------------------------------*/
+tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID)
+{
+ TIMER_Delete(timerID);
+
+ return (BLE_STATUS_SUCCESS);
+}
+
+#endif /* __DMA_LP__ */
+/*---------------------------------------------------------------------------*/
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,119 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name : ble_list.c
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 19-July-2012
+* Description : Circular Linked List Implementation.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/******************************************************************************
+ * Include Files
+******************************************************************************/
+#include <ble_hal_types.h>
+#include "ble_list.h"
+
+/******************************************************************************
+ * Function Definitions
+******************************************************************************/
+void list_init_head (tListNode * listHead)
+{
+ listHead->next = listHead;
+ listHead->prev = listHead;
+}
+
+uint8_t list_is_empty (tListNode * listHead)
+{
+ return ((listHead->next == listHead)? TRUE:FALSE);
+}
+
+void list_insert_head (tListNode * listHead, tListNode * node)
+{
+ node->next = listHead->next;
+ node->prev = listHead;
+ listHead->next = node;
+ (node->next)->prev = node;
+}
+
+
+void list_insert_tail (tListNode * listHead, tListNode * node)
+{
+ node->next = listHead;
+ node->prev = listHead->prev;
+ listHead->prev = node;
+ (node->prev)->next = node;
+}
+
+
+void list_remove_node (tListNode * node)
+{
+ (node->prev)->next = node->next;
+ (node->next)->prev = node->prev;
+}
+
+
+void list_remove_head (tListNode * listHead, tListNode ** node )
+{
+ *node = listHead->next;
+ list_remove_node (listHead->next);
+ (*node)->next = NULL;
+ (*node)->prev = NULL;
+}
+
+
+void list_remove_tail (tListNode * listHead, tListNode ** node )
+{
+ *node = listHead->prev;
+ list_remove_node (listHead->prev);
+ (*node)->next = NULL;
+ (*node)->prev = NULL;
+}
+
+
+void list_insert_node_after (tListNode * node, tListNode * ref_node)
+{
+ node->next = ref_node->next;
+ node->prev = ref_node;
+ ref_node->next = node;
+ (node->next)->prev = node;
+}
+
+
+void list_insert_node_before (tListNode * node, tListNode * ref_node)
+{
+ node->next = ref_node;
+ node->prev = ref_node->prev;
+ ref_node->prev = node;
+ (node->prev)->next = node;
+}
+
+
+int list_get_size (tListNode * listHead)
+{
+ int size = 0;
+ tListNode * temp = listHead->next;
+ while (temp != listHead)
+ {
+ size++;
+ temp = temp->next;
+ }
+ return (size);
+}
+
+void list_get_next_node (tListNode * ref_node, tListNode ** node)
+{
+ *node = ref_node->next;
+}
+
+
+void list_get_prev_node (tListNode * ref_node, tListNode ** node)
+{
+ *node = ref_node->prev;
+}
+
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,72 @@
+/**
+******************************************************************************
+* @file ble_osal.c
+* @author AMS - HEA&RF BU / CL
+* @version V1.0.0
+* @date 04-July-2014
+* @brief Implementation of OS abstraction layer functions used by the
+* library.
+******************************************************************************
+* @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include <ble_osal.h>
+
+ /**
+ * @brief Osal_MemCpy
+ * @param dest: Pointer to the destination buffer
+ * @param src : Pointer to the source buffer
+ * @param size: Number of bytes to copy from the source to the destination
+ * buffer
+ * @retval Pointer to the destination buffer
+ */
+void* Osal_MemCpy(void *dest, const void *src, unsigned int size)
+{
+ return(memcpy(dest,src,size));
+}
+
+/**
+ * @brief Osal_MemSet
+ * @param ptr : Pointer to block of memory to fill
+ * @param value: Value to assign to each byte of the memory block
+ * @param size : Number of bytes to be set to "value"
+ * @retval Pointer to the filled block of memory
+ */
+void* Osal_MemSet(void *ptr, int value, unsigned int size)
+{
+ return(memset(ptr,value,size));
+}
+
+/******************************************************************************
+ * local Functions
+ *****************************************************************************/
+
+ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,36 @@
+
+#include "ble_clock.h"
+#ifdef YOTTA_CFG_MBED_OS
+ #include "mbed-drivers/wait_api.h"
+ #include "mbed-drivers/rtc_time.h"
+#else
+ #include "wait_api.h"
+ #include "rtc_time.h"
+#endif
+
+const uint32_t CLOCK_SECOND = 1000;
+
+/*---------------------------------------------------------------------------*/
+
+void Clock_Init(void)
+{
+ //Not Used
+}
+
+/*---------------------------------------------------------------------------*/
+
+tClockTime Clock_Time(void)
+{
+ return clock();
+}
+
+/*---------------------------------------------------------------------------*/
+/**
+ * Wait for a multiple of 1 ms.
+ *
+ */
+void Clock_Wait(uint32_t i)
+{
+ wait_ms(i);
+}
+/*---------------------------------------------------------------------------*/
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/platform/btle.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,707 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/**
+ ******************************************************************************
+ * @file btle.cpp
+ * @author STMicroelectronics
+ * @brief Implementation BlueNRG Init and helper functions.
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
+ */
+
+
+#include "btle.h"
+#include "ble/Gap.h"
+#include "ble/GapEvents.h"
+#include "BlueNRGGap.h"
+#include "BlueNRGGattServer.h"
+#include "BlueNRGGattClient.h"
+#include "ble_utils.h"
+
+#include "x_nucleo_idb0xa1_targets.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* C File Includes ------------------------------------------------------------------*/
+#include <stdio.h>
+#include <string.h>
+#include "ble_hci.h"
+#include "ble_hci_const.h"
+#include "bluenrg_aci.h"
+#include "bluenrg_hal_aci.h"
+#include "bluenrg_gap.h"
+#include "bluenrg_utils.h"
+
+#include "ble_hal_types.h"
+#include "ble_hal.h"
+#include "ble_gp_timer.h"
+#include "ble_osal.h"
+#include "ble_sm.h"
+#include "ble_debug.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#define IDB04A1 0
+#define IDB05A1 1
+
+/* See file 'x_nucleo_idb0xa1_targets.h' for details regarding the IDB0XA1 STACK_MODE */
+#define STACK_MODE IDB0XA1_STACK_MODE
+
+void HCI_Input(tHciDataPacket * hciReadPacket);
+
+uint16_t g_gap_service_handle = 0;
+uint16_t g_appearance_char_handle = 0;
+uint16_t g_device_name_char_handle = 0;
+uint16_t g_preferred_connection_parameters_char_handle = 0;
+
+/* Private variables ---------------------------------------------------------*/
+volatile uint8_t set_connectable = 1;
+
+static char versionString[32];
+uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */
+
+/**************************************************************************/
+/*!
+ @brief Init the BTLE stack with the specified role
+ @returns void
+*/
+/**************************************************************************/
+void btleInit(void)
+{
+ PRINTF("btleInit>>\n\r");
+
+ int ret;
+ uint8_t hwVersion;
+ uint16_t fwVersion;
+ uint16_t service_handle, dev_name_char_handle, appearance_char_handle;
+
+ /* Reset BlueNRG SPI interface */
+ BlueNRG_RST();
+
+ /* get the BlueNRG HW and FW versions */
+ getBlueNRGVersion(&hwVersion, &fwVersion);
+
+ /*
+ * Reset BlueNRG again otherwise we won't
+ * be able to change its MAC address.
+ * aci_hal_write_config_data() must be the first
+ * command after reset otherwise it will fail.
+ */
+ BlueNRG_RST();
+
+ if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */
+ bnrg_expansion_board = IDB05A1;
+ }
+
+ /* set BLE version string */
+ setVersionString(hwVersion, fwVersion);
+
+ if (bnrg_expansion_board == IDB05A1) {
+ uint8_t stackMode = STACK_MODE;
+ ret = aci_hal_write_config_data(CONFIG_DATA_ROLE,
+ CONFIG_DATA_ROLE_LEN,
+ &stackMode);
+ }
+
+ ret = aci_gatt_init();
+ if(ret != BLE_STATUS_SUCCESS){
+ PRINTF("GATT_Init failed.\n");
+ }
+ if (bnrg_expansion_board == IDB05A1) {
+ ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1,
+ 0,
+ 0x18,
+ &service_handle,
+ &dev_name_char_handle,
+ &appearance_char_handle);
+ } else {
+ // IDB04A1 is configured as peripheral by default
+ ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle);
+ }
+
+ // read the default static address and inject it into the GAP object
+ {
+ Gap::Address_t BLE_address_BE = { 0 };
+ uint8_t data_len_out;
+ aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS_IDB05A1, BDADDR_SIZE, &data_len_out, BLE_address_BE);
+ // FIXME error handling of this function
+ BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE);
+ }
+
+ if(ret != BLE_STATUS_SUCCESS){
+ PRINTF("GAP_Init failed.\n");
+ }
+
+ //FIXME: Security and passkey set by default
+ ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED,
+ OOB_AUTH_DATA_ABSENT,
+ NULL,
+ 7,
+ 16,
+ USE_FIXED_PIN_FOR_PAIRING,
+ 123456,
+ BONDING);
+ if (ret != BLE_STATUS_SUCCESS) {
+ PRINTF("Auth Req set failed.\n");
+ }
+
+ aci_hal_set_tx_power_level(1,4);
+
+ g_gap_service_handle = service_handle;
+ g_appearance_char_handle = appearance_char_handle;
+ g_device_name_char_handle = dev_name_char_handle;
+ //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API
+ /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0,
+ strlen(name), (tHalUint8 *)name);*/
+
+ signalEventsToProcess();
+ // update the peripheral preferred conenction parameters handle
+ // This value is hardcoded at the moment.
+ g_preferred_connection_parameters_char_handle = 10;
+
+ return;
+}
+
+/**************************************************************************/
+/*!
+ @brief mbedOS
+
+ @param[in] void
+
+ @returns
+*/
+/**************************************************************************/
+int btle_handler_pending = 0;
+
+void btle_handler(void)
+{
+ btle_handler_pending = 0;
+ BlueNRGGap::getInstance().Process();
+ HCI_Process();
+}
+
+/* set BLE Version string */
+void setVersionString(uint8_t hwVersion, uint16_t fwVersion)
+{
+ if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) {
+ snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u",
+ hwVersion>>4, (hwVersion&0x0F),
+ fwVersion>>8, (fwVersion&0x00F0)>>4);
+ } else {
+ snprintf(versionString, sizeof(versionString), "ST (unknown spec)");
+ }
+}
+
+/* get BLE Version string */
+const char* getVersionString(void)
+{
+ return versionString;
+}
+
+tBleStatus btleStartRadioScan(uint8_t scan_type,
+ uint16_t scan_interval,
+ uint16_t scan_window,
+ uint8_t own_address_type)
+{
+ tBleStatus ret;
+
+ // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED
+ if(bnrg_expansion_board == IDB05A1) {
+ PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window);
+ PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type);
+ ret = aci_gap_start_observation_procedure(scan_interval,
+ scan_window,
+ scan_type,
+ own_address_type,
+ 0); // 1 to filter duplicates
+ } else {
+ ret = BLE_STATUS_INVALID_CID;
+ }
+
+ return ret;
+
+}
+
+/*!
+ @brief Not Used
+
+ @param[in] void
+
+ @returns
+*/
+void SPI_Poll(void)
+{
+ //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN);
+ return;
+}
+
+void Attribute_Modified_CB(evt_blue_aci *blue_evt)
+{
+ uint16_t conn_handle;
+ uint16_t attr_handle;
+ uint8_t data_length;
+ uint8_t *att_data;
+ uint8_t offset;
+
+ if (bnrg_expansion_board == IDB05A1) {
+ evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data;
+ conn_handle = evt->conn_handle;
+ attr_handle = evt->attr_handle;
+ data_length = evt->data_length;
+ att_data = evt->att_data;
+ offset = evt->offset;
+ } else {
+ evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data;
+ conn_handle = evt->conn_handle;
+ attr_handle = evt->attr_handle;
+ data_length = evt->data_length;
+ att_data = evt->att_data;
+ offset = 0;
+ }
+
+ //Extract the GattCharacteristic from p_characteristics[] and find the properties mask
+ GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle);
+ if(p_char!=NULL) {
+ GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
+ BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE;
+ PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]);
+ PRINTF("getProperties 0x%x\n\r",p_char->getProperties());
+
+ if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) {
+ currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE;
+ }
+
+ if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) {
+ currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE;
+ }
+ PRINTF("currentHandle %d\n\r", currentHandle);
+ if((p_char->getProperties() &
+ (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) &&
+ currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) {
+
+ GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1;
+
+ PRINTF("*****NOTIFICATION CASE\n\r");
+ //Now Check if data written in Enable or Disable
+ if((uint16_t)att_data[0]==1) {
+ //PRINTF("Notify ENABLED\n\r");
+ BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle);
+ } else {
+ //PRINTF("Notify DISABLED\n\r");
+ BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle);
+ }
+ return;
+ }
+
+ //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event
+ if((p_char->getProperties() &
+ (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) &&
+ currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) {
+
+ PRINTF("*****WRITE CASE\n\r");
+
+ GattWriteCallbackParams writeParams;
+ writeParams.connHandle = conn_handle;
+ writeParams.handle = p_char->getValueAttribute().getHandle();
+ writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG?
+ writeParams.len = data_length;
+ writeParams.data = att_data;
+ writeParams.offset = offset;
+
+ //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle);
+ //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data
+ if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) {
+ BlueNRGGattServer::getInstance().write(
+ p_char->getValueAttribute().getHandle(),
+ (uint8_t*)att_data,
+ data_length,
+ false
+ );
+ }
+
+ BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams);
+ } else {
+ PRINTF("*****WRITE DESCRIPTOR CASE\n\r");
+
+ GattWriteCallbackParams writeParams;
+ writeParams.connHandle = conn_handle;
+ writeParams.handle = attr_handle;
+ writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG?
+ writeParams.len = data_length;
+ writeParams.data = att_data;
+ writeParams.offset = offset;
+
+ BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams);
+ }
+ }
+
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /**************************************************************************/
+ /*!
+ @brief Handle HCI Stack Event
+
+ @param[in] pckt
+ Event Packet sent by the stack to be decoded
+
+ @returns
+ */
+ /**************************************************************************/
+ extern void HCI_Event_CB(void *pckt) {
+ hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt;
+ hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data;
+
+ if(hci_pckt->type != HCI_EVENT_PKT)
+ return;
+
+ switch(event_pckt->evt){
+
+ case EVT_DISCONN_COMPLETE:
+ {
+ PRINTF("EVT_DISCONN_COMPLETE\n");
+
+ evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data;
+
+ BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason);
+ }
+ break;
+
+ case EVT_LE_META_EVENT:
+ {
+ PRINTF("EVT_LE_META_EVENT\n");
+
+ evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data;
+
+ switch(evt->subevent){
+
+ case EVT_LE_CONN_COMPLETE:
+ {
+ PRINTF("EVT_LE_CONN_COMPLETE\n");
+ Gap::Address_t ownAddr;
+ Gap::AddressType_t ownAddrType;
+ BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr);
+
+ Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC;
+ Gap::Role_t role;
+
+ evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data;
+
+ BlueNRGGap::getInstance().setConnectionHandle(cc->handle);
+ BlueNRGGap::ConnectionParams_t connectionParams = {
+ /* minConnectionInterval = */ cc->interval,
+ /* maxConnectionInterval = */ cc->interval,
+ /* slaveLatency = */ cc->latency,
+ /* connectionSupervisionTimeout = */ cc->supervision_timeout
+ };
+
+ BlueNRGGap::getInstance().setConnectionInterval(cc->interval);
+
+ switch (cc->peer_bdaddr_type) {
+ case PUBLIC_ADDR:
+ peerAddrType = BLEProtocol::AddressType::PUBLIC;
+ break;
+ case STATIC_RANDOM_ADDR:
+ peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC;
+ break;
+ case RESOLVABLE_PRIVATE_ADDR:
+ peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE;
+ break;
+ case NON_RESOLVABLE_PRIVATE_ADDR:
+ peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE;
+ break;
+ }
+ //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role);
+ switch (cc->role) {
+ case 0: //master
+ role = Gap::CENTRAL;
+ break;
+ case 1:
+ role = Gap::PERIPHERAL;
+ break;
+ default:
+ role = Gap::PERIPHERAL;
+ break;
+ }
+
+ BlueNRGGap::getInstance().setGapRole(role);
+
+ BlueNRGGap::getInstance().processConnectionEvent(cc->handle,
+ role,
+ peerAddrType,
+ cc->peer_bdaddr,
+ ownAddrType,
+ ownAddr,
+ &connectionParams);
+ }
+ break;
+
+ case EVT_LE_ADVERTISING_REPORT:
+ PRINTF("EVT_LE_ADVERTISING_REPORT\n\r");
+ /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */
+ // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT)
+ // Formally the structure related to both events are identical except that for the ADV REPORT
+ // there is one more field (number of reports) which is not forwarded to upper layer.
+ // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT.
+ le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1);
+ PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type);
+
+ BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND,
+ pr->evt_type,
+ pr->bdaddr_type,
+ pr->bdaddr,
+ &pr->data_length,
+ &pr->data_RSSI[0],
+ &pr->data_RSSI[pr->data_length]);
+ break;
+ }
+ }
+ break;
+
+ case EVT_VENDOR:
+ {
+ evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data;
+ //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode);
+
+ switch(blue_evt->ecode){
+
+ case EVT_BLUE_GATT_WRITE_PERMIT_REQ:
+ {
+ PRINTF("EVT_BLUE_GATT_WRITE_PERMIT_REQ\r\n");
+ evt_gatt_write_permit_req* write_req = (evt_gatt_write_permit_req*)blue_evt->data;
+
+ // ask the local server if the write operation is authorized
+ uint8_t err_code = BlueNRGGattServer::getInstance().Write_Request_CB(
+ write_req->conn_handle,
+ write_req->attr_handle,
+ write_req->data_length,
+ write_req->data
+ );
+ uint8_t write_status = err_code == 0 ? 0 : 1;
+
+ // reply to the shield
+ aci_gatt_write_response(
+ write_req->conn_handle,
+ write_req->attr_handle,
+ write_status,
+ err_code,
+ write_req->data_length,
+ write_req->data
+ );
+ }
+ break;
+
+ case EVT_BLUE_GATT_READ_PERMIT_REQ:
+ {
+ PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r");
+ evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data;
+ PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle);
+ BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle);
+ }
+ break;
+
+ case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED:
+ {
+ PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r");
+ /* this callback is invoked when a GATT attribute is modified
+ extract callback data and pass to suitable handler function */
+ Attribute_Modified_CB(blue_evt);
+ }
+ break;
+
+ //Any cases for Data Sent Notifications?
+ case EVT_BLUE_GATT_NOTIFICATION:
+ //This is only relevant for Client Side Event
+ PRINTF("EVT_BLUE_GATT_NOTIFICATION");
+ break;
+ case EVT_BLUE_GATT_INDICATION:
+ //This is only relevant for Client Side Event
+ PRINTF("EVT_BLUE_GATT_INDICATION");
+ break;
+
+ case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP:
+ {
+ PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r");
+ evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data;
+ BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle,
+ pr->event_data_length,
+ pr->attribute_data_length,
+ pr->attribute_data_list);
+ }
+ break;
+ case EVT_BLUE_ATT_READ_BY_TYPE_RESP:
+ {
+ PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r");
+ evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data;
+ BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle,
+ pr->event_data_length,
+ pr->handle_value_pair_length,
+ pr->handle_value_pair);
+ }
+ break;
+ case EVT_BLUE_ATT_READ_RESP:
+ {
+ PRINTF("EVT_BLUE_ATT_READ_RESP\n\r");
+ evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data;
+ BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle,
+ pr->event_data_length,
+ pr->attribute_value);
+ }
+ break;
+ case EVT_BLUE_ATT_EXEC_WRITE_RESP:
+ {
+ PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r");
+ evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data;
+ BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle,
+ pr->event_data_length);
+ }
+ break;
+ case EVT_BLUE_ATT_PREPARE_WRITE_RESP:
+ {
+ PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r");
+ evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data;
+ BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle,
+ pr->event_data_length,
+ pr->attribute_handle,
+ pr->offset,
+ pr->part_attr_value);
+ }
+ break;
+ case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP:
+ {
+ PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r");
+ evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data;
+ BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle,
+ pr->event_data_length,
+ pr->attr_handle,
+ pr->attr_value);
+ }
+ break;
+ case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP:
+ {
+ PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r");
+ evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data;
+ BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle,
+ pr->event_data_length,
+ pr->handles_info_list);
+ }
+ break;
+ case EVT_BLUE_ATT_FIND_INFORMATION_RESP:
+ {
+ PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r");
+ evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data;
+ BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle,
+ pr->event_data_length,
+ pr->format,
+ pr->handle_uuid_pair);
+ }
+ break;
+ case EVT_BLUE_GATT_PROCEDURE_COMPLETE:
+ {
+ evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data;
+ PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code);
+ BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code);
+ }
+ break;
+
+ case EVT_BLUE_L2CAP_CONN_UPD_REQ:
+ {
+ PRINTF("EVT_BLUE_L2CAP_CONN_UPD_REQ\r\n");
+ evt_l2cap_conn_upd_req *evt = (evt_l2cap_conn_upd_req*)blue_evt->data;
+ if(bnrg_expansion_board == IDB05A1) {
+ // we assume the application accepts the request from the slave
+ aci_l2cap_connection_parameter_update_response_IDB05A1(evt->conn_handle,
+ evt->interval_min,
+ evt->interval_max,
+ evt->slave_latency,
+ evt->timeout_mult,
+ CONN_L1, CONN_L2,
+ evt->identifier,
+ 0x0000);
+ }
+ }
+ break;
+
+ case EVT_BLUE_L2CAP_CONN_UPD_RESP:
+ {
+ PRINTF("EVT_BLUE_L2CAP_CONN_UPD_RESP\r\n");
+ }
+ break;
+
+ case EVT_LE_CONN_UPDATE_COMPLETE:
+ {
+ PRINTF("EVT_LE_CONN_UPDATE_COMPLETE\r\n");
+ }
+ break;
+
+ case EVT_BLUE_GAP_DEVICE_FOUND:
+ {
+ evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data;
+ PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type);
+
+ BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND,
+ pr->evt_type,
+ pr->bdaddr_type,
+ pr->bdaddr,
+ &pr->data_length,
+ &pr->data_RSSI[0],
+ &pr->data_RSSI[pr->data_length]);
+ }
+ break;
+
+ case EVT_BLUE_GAP_PROCEDURE_COMPLETE:
+ {
+ evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data;
+ //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code);
+
+ switch(pr->procedure_code) {
+ case GAP_OBSERVATION_PROC_IDB05A1:
+
+ BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ return ;
+ }
+
+
+#ifdef __cplusplus
+}
+#endif
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,219 @@
+/**
+ ******************************************************************************
+ * @file stm32_bluenrg_ble.cpp
+ * @author CL
+ * @version V1.0.0
+ * @date 15-June-2015
+ * @brief
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "BlueNRGGap.h"
+#include "BlueNRGDevice.h"
+//#include "Utils.h"
+#include "btle.h"
+
+// FIXME: find a better way to get the instance of the BlueNRG device
+extern BlueNRGDevice bluenrgDeviceInstance;
+
+
+////////////////////////////////////////
+// Start of C function wrappers
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stm32_bluenrg_ble.h"
+#include "ble_gp_timer.h"
+#include "ble_debug.h"
+
+
+void BlueNRG_RST(void)
+{
+ bluenrgDeviceInstance.reset();
+}
+
+uint8_t BlueNRG_DataPresent(void)
+{
+ return (bluenrgDeviceInstance.dataPresent());
+}
+
+
+/**
+ * @brief This function is a utility to print the log time
+* in the format HH:MM:SS:MSS (DK GUI time format)
+ * @param None
+ * @retval None
+ */
+void print_csv_time(void){
+#ifdef PRINT_CSV_FORMAT
+ uint32_t ms = 0;//ms_counter;
+ PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000);
+#endif
+}
+
+/**
+ * @brief Writes data to a serial interface.
+ * @param data1 : 1st buffer
+ * @param data2 : 2nd buffer
+ * @param n_bytes1: number of bytes in 1st buffer
+ * @param n_bytes2: number of bytes in 2nd buffer
+ * @retval None
+ */
+void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1,
+ int32_t n_bytes2)
+{
+ struct timer t;
+
+ Timer_Set(&t, CLOCK_SECOND/10);
+
+#ifdef PRINT_CSV_FORMAT
+ print_csv_time();
+ for (int i=0; i<n_bytes1; i++) {
+ PRINT_CSV(" %02x", ((uint8_t *)data1)[i]);
+ }
+ for (int i=0; i<n_bytes2; i++) {
+ PRINT_CSV(" %02x", ((uint8_t *)data2)[i]);
+ }
+ PRINT_CSV("\n");
+#endif
+
+ while(1){
+ if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break;
+ if(Timer_Expired(&t)){
+ break;
+ }
+ }
+}
+
+
+/**
+ * @brief Activate internal bootloader using pin.
+ * @param None
+ * @retval None
+ */
+void BlueNRG_HW_Bootloader(void)
+{
+ // Reset BlueNRG SPI interface
+ BlueNRG_RST();
+
+ // Send an ACI command to reboot BlueNRG in bootloader mode
+ // The safest way to get in bootloader mode is keeping high
+ // the interrupt pin during reset, but this would require many
+ // changes to the current mbed driver
+ aci_updater_start();
+}
+
+/**
+ * @brief Reads from BlueNRG SPI buffer and store data into local buffer.
+ * @param buffer : Buffer where data from SPI are stored
+ * @param buff_size: Buffer size
+ * @retval int32_t : Number of read bytes
+ */
+int32_t BlueNRG_SPI_Read_All(uint8_t *buffer,
+ uint8_t buff_size)
+{
+ int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size);
+
+ return ret;
+}
+
+/**
+ * @brief Writes data from local buffer to SPI.
+ * @param data1 : First data buffer to be written
+ * @param data2 : Second data buffer to be written
+ * @param Nb_bytes1: Size of first data buffer to be written
+ * @param Nb_bytes2: Size of second data buffer to be written
+ * @retval Number of read bytes
+ */
+int32_t BlueNRG_SPI_Write(uint8_t* data1,
+ uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2)
+{
+ int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2);
+
+ return ret;
+}
+
+/**
+ * @brief Enable SPI IRQ.
+ * @param None
+ * @retval None
+ */
+void Enable_SPI_IRQ(void)
+{
+ bluenrgDeviceInstance.enable_irq();
+}
+
+void signalEventsToProcess(void) {
+ if(btle_handler_pending == 0) {
+ btle_handler_pending = 1;
+ bluenrgDeviceInstance.signalEventsToProcess(BLE::DEFAULT_INSTANCE);
+ }
+}
+
+/**
+ * @brief Disable SPI IRQ.
+ * @param None
+ * @retval None
+ */
+void Disable_SPI_IRQ(void)
+{
+ bluenrgDeviceInstance.disable_irq();
+}
+
+/**
+ * @brief Clear Pending SPI IRQ.
+ * @param None
+ * @retval None
+ */
+void Clear_SPI_IRQ(void)
+{
+}
+
+/**
+ * @brief Clear EXTI (External Interrupt) line for SPI IRQ.
+ * @param None
+ * @retval None
+ */
+void Clear_SPI_EXTI_Flag(void)
+{
+}
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+// End of C function wrappers
+////////////////////////////////////////
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,118 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <ble_payload.h>
+
+Payload::Payload() {
+ stringLength = 0;
+ payloadUnitCount = 0;
+ payload = NULL;
+}
+
+Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) {
+ // initialize private data members
+ stringLength = string_ength;
+ payloadUnitCount = 0;
+ payload = NULL;
+
+ int index = 0;
+ while( index!=stringLength) {
+ int len=tokenString[index];
+ index=index+1+len;
+ payloadUnitCount++;
+ }
+
+ UnitPayload *obj = new UnitPayload[payloadUnitCount];
+ int i=0;
+ int c=0;
+ int j,k;
+
+ while(i<payloadUnitCount)
+ {
+ obj[i].length=tokenString[c];
+ obj[i].id=tokenString[c+1];
+
+ obj[i].data = new uint8_t[obj[i].length];
+ for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++)
+ {
+ obj[i].data[k]=tokenString[j];
+
+ }
+
+ c=c+obj[i].length+1;
+ i++;
+
+ }
+ payload = obj;
+}
+
+uint8_t Payload::getPayloadUnitCount() {
+ return payloadUnitCount;
+}
+
+uint8_t Payload::getIDAtIndex(int index) {
+ return payload[index].get_id();
+}
+
+uint8_t Payload::getLengthAtIndex(int index) {
+ return payload[index].get_length();
+}
+
+uint8_t* Payload::getDataAtIndex(int index) {
+ return payload[index].get_data();
+}
+
+int8_t Payload::getInt8AtIndex(int index) {
+ uint8_t* str = payload[index].get_data();
+ int8_t value = (int8_t)str[0];
+ return value;
+}
+
+uint16_t Payload::getUint16AtIndex(int index) {
+ uint16_t* str = (uint16_t*)payload[index].get_data();
+ uint16_t value = str[0];
+ return value;
+}
+
+uint8_t* Payload::getSerializedAdDataAtIndex(int index) {
+ uint8_t length = payload[index].get_length();
+ uint8_t* data = payload[index].get_data();
+ uint8_t id = payload[index].get_id();
+ uint8_t *serializedAdData = new uint8_t[length];
+
+ serializedAdData[0] = id;
+ for(int i=0; i<length-1; i++) {
+ serializedAdData[i+1] = data[i];
+ }
+ return serializedAdData;
+}
+
+Payload::~Payload() {
+ int i = 0;
+
+ if(payload) {
+ while(i<payloadUnitCount) {
+ if(payload->data) {
+ delete[] payload->data;
+ payload->data = NULL;
+ }
+ }
+ delete[] payload;
+ payload = NULL;
+ }
+
+}
+
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,93 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "ble_utils.h"
+
+/**************************************************************************/
+/*!
+ @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power
+
+*/
+/**************************************************************************/
+tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) {
+ tBleStatus ret = BLE_STATUS_SUCCESS;
+
+ if(dBMLevel==-18) {
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 0;
+ }
+ else if(dBMLevel==-15) {
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 1;
+ }
+ else if(dBMLevel==-14) {
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 0;
+ }
+ else if(dBMLevel==-12) {
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 2;
+ }
+ else if(dBMLevel==-11) {
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 1;
+ }
+ else if(dBMLevel==-9) {
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 3;
+ }
+ else if(dBMLevel==-8) {
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 2;
+ }
+ else if(dBMLevel==-6) {
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 4;
+ }
+ else if(dBMLevel==-5) {
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 3;
+ }
+ else if(dBMLevel==-2) {
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 4;
+ }
+ else if(dBMLevel==0) {
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 6;
+ }
+ else if(dBMLevel==2) {
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 5;
+ }
+ else if(dBMLevel==4) {
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 6;
+ }
+ else if(dBMLevel==5) {
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 7;
+ }
+ else if(dBMLevel==8) {
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 7;
+ }
+ else {
+ ret = ERR_INVALID_HCI_CMD_PARAMS;
+ }
+
+ return ret;
+}
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/BlueNRGDevice.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/BlueNRGDevice.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,111 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/**
+ ******************************************************************************
+ * @file BlueNRGDevice.h
+ * @author STMicroelectronics
+ * @brief Header file for BLEDeviceInstanceBase based BlueNRGDevice
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
+ */
+
+#ifndef __BLUENRG_DEVICE_H__
+#define __BLUENRG_DEVICE_H__
+
+#define BLUENRG
+#define DEBUG_BLUENRG_USER
+
+#include "btle.h"
+
+#ifdef YOTTA_CFG_MBED_OS
+ #include "mbed-drivers/mbed.h"
+#else
+ #include "mbed.h"
+#endif
+#include "ble/blecommon.h"
+#include "ble/BLEInstanceBase.h"
+#include "ble/BLE.h"
+#include "BlueNRGGap.h"
+#include "BlueNRGGattServer.h"
+#include "BlueNRGGattClient.h"
+
+
+class BlueNRGDevice : public BLEInstanceBase
+{
+
+public:
+ BlueNRGDevice(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, PinName irq);
+ virtual ~BlueNRGDevice(void);
+
+ virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback);
+ virtual ble_error_t shutdown(void);
+ virtual const char *getVersion(void);
+ virtual Gap& getGap();
+ virtual const Gap& getGap() const;
+ virtual GattServer& getGattServer();
+ virtual const GattServer& getGattServer() const;
+ virtual void waitForEvent(void);
+
+ virtual GattClient& getGattClient() {
+ return BlueNRGGattClient::getInstance();
+ }
+
+ virtual SecurityManager& getSecurityManager() {
+ return *sm;
+ }
+
+ virtual const SecurityManager& getSecurityManager() const {
+ return *sm;
+ }
+ void reset(void);
+ virtual bool hasInitialized(void) const {
+ return isInitialized;
+ }
+
+ uint8_t getUpdaterHardwareVersion(uint8_t *hw_version);
+ int updateFirmware(const uint8_t *fw_image, uint32_t fw_size);
+ bool dataPresent();
+ int32_t spiRead(uint8_t *buffer, uint8_t buff_size);
+ int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2);
+ void disable_irq();
+ void enable_irq();
+
+ virtual void processEvents();
+
+private:
+ bool isInitialized;
+
+ SPI spi_;
+ DigitalOut nCS_;
+ DigitalOut rst_;
+ InterruptIn irq_;
+
+ //FIXME: TBI (by now just placeholders to let build
+ /*** betzw: placeholders ***/
+ SecurityManager *sm;
+};
+
+#endif
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/BlueNRGDiscoveredCharacteristic.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/BlueNRGDiscoveredCharacteristic.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,46 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__
+#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__
+
+#include "ble/DiscoveredCharacteristic.h"
+
+class BlueNRGGattClient; /* forward declaration */
+
+class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic {
+public:
+
+ void setup(BlueNRGGattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ DiscoveredCharacteristic::Properties_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn,
+ GattAttribute::Handle_t lastHandleIn);
+
+ void setup(BlueNRGGattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ UUID uuidIn,
+ DiscoveredCharacteristic::Properties_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn,
+ GattAttribute::Handle_t lastHandleIn);
+
+
+ void setLastHandle(GattAttribute::Handle_t lastHandleIn);
+};
+
+#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/BlueNRGGap.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/BlueNRGGap.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,214 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/**
+ ******************************************************************************
+ * @file BlueNRGGap.h
+ * @author STMicroelectronics
+ * @brief Header file for BlueNRG BLE_API Gap Class
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
+ */
+
+#ifndef __BLUENRG_GAP_H__
+#define __BLUENRG_GAP_H__
+
+#ifdef YOTTA_CFG_MBED_OS
+ #include "mbed-drivers/mbed.h"
+#else
+ #include "mbed.h"
+#endif
+#include "ble/blecommon.h"
+#include "btle.h"
+#include "ble/GapAdvertisingParams.h"
+#include "ble/GapAdvertisingData.h"
+#include "ble/Gap.h"
+
+#define BLE_CONN_HANDLE_INVALID 0x0
+#define BDADDR_SIZE 6
+
+#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020)
+#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000)
+#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0)
+
+// Scanning and Connection Params used by Central for creating connection
+#define GAP_OBSERVATION_PROC (0x80)
+
+#define SCAN_P (0x0010)
+#define SCAN_L (0x0010)
+#define SUPERV_TIMEOUT (0xC80)
+#define CONN_P(x) ((int)((x)/1.25f))
+#define CONN_L(x) ((int)((x)/0.625f))
+#define CONN_P1 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C)
+#define CONN_P2 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C)
+#define CONN_L1 (0x0008)
+#define CONN_L2 (0x0008)
+#define GUARD_INT 5 //msec
+#define MIN_INT_CONN 0x0006 //=>7.5msec
+#define MAX_INT_CONN 0x0C80 //=>4000msec
+#define DEF_INT_CONN 0x0140 //=>400msec (default value for connection interval)
+
+/**************************************************************************/
+/*!
+ \brief
+
+*/
+/**************************************************************************/
+class BlueNRGGap : public Gap
+{
+public:
+ static BlueNRGGap &getInstance() {
+ static BlueNRGGap m_instance;
+ return m_instance;
+ }
+
+ enum Reason_t {
+ DEVICE_FOUND,
+ DISCOVERY_COMPLETE
+ };
+
+ /* Functions that must be implemented from Gap */
+ virtual ble_error_t setAddress(addr_type_t type, const BLEProtocol::AddressBytes_t address);
+ virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address);
+ virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &);
+ virtual ble_error_t startAdvertising(const GapAdvertisingParams &);
+ virtual ble_error_t stopAdvertising(void);
+ virtual ble_error_t stopScan();
+ virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);}
+ virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);}
+ virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);}
+ virtual ble_error_t disconnect(DisconnectionReason_t reason);
+ virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason);
+ virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params);
+ virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params);
+ virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params);
+
+ virtual ble_error_t setDeviceName(const uint8_t *deviceName);
+ virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP);
+ virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance);
+ virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP);
+
+ virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode);
+ virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode);
+ virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const;
+ virtual ScanningPolicyMode_t getScanningPolicyMode(void) const;
+
+ virtual ble_error_t setTxPower(int8_t txPower);
+ virtual void getPermittedTxPowerValues(const int8_t **, size_t *);
+
+ virtual ble_error_t connect(const Address_t peerAddr,
+ Gap::AddressType_t peerAddrType,
+ const ConnectionParams_t *connectionParams,
+ const GapScanningParams *scanParams);
+
+ virtual ble_error_t reset(void);
+
+ void Discovery_CB(Reason_t reason,
+ uint8_t adv_type,
+ uint8_t addr_type,
+ uint8_t *addr,
+ uint8_t *data_length,
+ uint8_t *data,
+ uint8_t *RSSI);
+ ble_error_t createConnection(void);
+
+ void setConnectionHandle(uint16_t con_handle);
+ uint16_t getConnectionHandle(void);
+
+ bool getIsSetAddress();
+
+ Timeout getAdvTimeout(void) const {
+ return advTimeout;
+ }
+ uint8_t getAdvToFlag(void) {
+ return AdvToFlag;
+ }
+ void setAdvToFlag(void);
+
+ void Process(void);
+
+ GapScanningParams* getScanningParams(void);
+
+ virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams);
+
+ void setConnectionInterval(uint16_t interval);
+ void setGapRole(Role_t role);
+
+private:
+ uint16_t m_connectionHandle;
+ Role_t gapRole;
+ AddressType_t addr_type;
+ Address_t _peerAddr;
+ AddressType_t _peerAddrType;
+ uint8_t bdaddr[BDADDR_SIZE];
+ bool _scanning;
+ bool _connecting;
+ bool isSetAddress;
+ uint8_t deviceAppearance[2];
+
+ 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 advInterval;
+ uint16_t slaveConnIntervMin;
+ uint16_t slaveConnIntervMax;
+ uint16_t conn_min_interval;
+ uint16_t conn_max_interval;
+ void setAdvParameters(void);
+ void setConnectionParameters(void);
+
+ Gap::AdvertisingPolicyMode_t advertisingPolicyMode;
+ Gap::ScanningPolicyMode_t scanningPolicyMode;
+
+ Whitelist_t whitelistAddresses;
+
+ ble_error_t updateAdvertisingData(void);
+
+ BlueNRGGap() {
+ m_connectionHandle = BLE_CONN_HANDLE_INVALID;
+ addr_type = BLEProtocol::AddressType::RANDOM_STATIC;
+
+ /* Set the whitelist policy filter modes to IGNORE_WHITELIST */
+ advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST;
+ scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST;
+
+ isSetAddress = false;
+ memset(deviceAppearance, 0, sizeof(deviceAppearance));
+ }
+
+ BlueNRGGap(BlueNRGGap const &);
+ void operator=(BlueNRGGap const &);
+
+ GapAdvertisingData _advData;
+ GapAdvertisingData _scanResponse;
+};
+
+#endif // ifndef __BLUENRG_GAP_H__
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/BlueNRGGattClient.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/BlueNRGGattClient.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,185 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/**
+ ******************************************************************************
+ * @file 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>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ */
+
+#ifndef __BLUENRG_GATT_CLIENT_H__
+#define __BLUENRG_GATT_CLIENT_H__
+
+#ifdef YOTTA_CFG_MBED_OS
+ #include "mbed-drivers/mbed.h"
+#else
+ #include "mbed.h"
+#endif
+#include "ble/blecommon.h"
+#include "btle.h"
+#include "ble/GattClient.h"
+#include "ble/DiscoveredService.h"
+#include "ble/CharacteristicDescriptorDiscovery.h"
+#include "BlueNRGDiscoveredCharacteristic.h"
+
+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__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/BlueNRGGattServer.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/BlueNRGGattServer.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,125 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/**
+ ******************************************************************************
+ * @file BlueNRGGattServer.cpp
+ * @author STMicroelectronics
+ * @brief Header file for BLE_API GattServer Class
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
+ */
+
+#ifndef __BLUENRG_GATT_SERVER_H__
+#define __BLUENRG_GATT_SERVER_H__
+
+#ifdef YOTTA_CFG_MBED_OS
+ #include "mbed-drivers/mbed.h"
+#else
+ #include "mbed.h"
+#endif
+#include "ble/blecommon.h"
+#include "btle.h"
+#include "ble/GattService.h"
+#include "ble/GattServer.h"
+#include <vector>
+#include <map>
+
+#define BLE_TOTAL_CHARACTERISTICS 10
+
+using namespace std;
+
+class BlueNRGGattServer : public GattServer
+{
+public:
+ static BlueNRGGattServer &getInstance() {
+ static BlueNRGGattServer m_instance;
+ return m_instance;
+ }
+
+ enum HandleEnum_t {
+ CHAR_HANDLE = 0,
+ CHAR_VALUE_HANDLE,
+ CHAR_DESC_HANDLE
+ };
+
+ /* Functions that must be implemented from GattServer */
+ virtual ble_error_t addService(GattService &);
+ virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
+ virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
+ virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false);
+ virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false);
+ virtual ble_error_t initializeGATTDatabase(void);
+
+ virtual bool isOnDataReadAvailable() const {
+ return true;
+ }
+
+ virtual ble_error_t reset(void);
+
+ /* BlueNRG Functions */
+ void eventCallback(void);
+ //void hwCallback(void *pckt);
+ ble_error_t Read_Request_CB(uint16_t attributeHandle);
+ uint8_t Write_Request_CB(
+ uint16_t connection_handle, uint16_t attr_handle,
+ uint8_t data_length, const uint8_t* data
+ );
+ GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle);
+ void HCIDataWrittenEvent(const GattWriteCallbackParams *params);
+ void HCIDataReadEvent(const GattReadCallbackParams *params);
+ void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle);
+ void HCIDataSentEvent(unsigned count);
+
+private:
+
+ // compute the number of attribute record needed by a service
+ static uint16_t computeAttributesRecord(GattService& service);
+
+
+ static const int MAX_SERVICE_COUNT = 10;
+ uint8_t serviceCount;
+ uint8_t characteristicCount;
+ uint16_t servHandle, charHandle;
+
+ std::map<uint16_t, uint16_t> bleCharHandleMap; // 1st argument is characteristic, 2nd argument is service
+ GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS];
+ uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS];
+
+ BlueNRGGattServer() {
+ serviceCount = 0;
+ characteristicCount = 0;
+ };
+
+ BlueNRGGattServer(BlueNRGGattServer const &);
+ void operator=(BlueNRGGattServer const &);
+
+ static const int CHAR_DESC_TYPE_16_BIT=0x01;
+ static const int CHAR_DESC_TYPE_128_BIT=0x02;
+ static const int CHAR_DESC_SECURITY_PERMISSION=0x00;
+ static const int CHAR_DESC_ACCESS_PERMISSION=0x03;
+ static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00;
+};
+
+#endif
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_clock.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_clock.h Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __CLOCK_H__ +#define __CLOCK_H__ + +#include <ble_hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __CLOCK_H__ */ +
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_compiler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_compiler.h Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,34 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#define PACKED __attribute__((packed)) +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_debug.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_debug.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,73 @@
+/**
+ ******************************************************************************
+ * @file ble_debug.h
+ * @author CL
+ * @version V1.0.0
+ * @date 04-July-2014
+ * @brief This file defines print functions for debug purposes.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© 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 __DEBUG_H
+#define __DEBUG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+
+/* Exported macro ------------------------------------------------------------*/
+//#define DEBUG
+#ifdef DEBUG
+#include <stdio.h>
+#define PRINTF(...) printf(__VA_ARGS__)
+#else
+#define PRINTF(...)
+#endif
+
+/* Print the data travelling over the SPI in the .csv format for the GUI*/
+//#define PRINT_CSV_FORMAT
+#ifdef PRINT_CSV_FORMAT
+#include <stdio.h>
+#define PRINT_CSV(...) printf(__VA_ARGS__)
+#else
+#define PRINT_CSV(...)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DEBUG_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_gp_timer.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_gp_timer.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,105 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name : gp_timer.h
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 19-July-2012
+* Description : General purpose timer library.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __GP_TIMER_H__
+#define __GP_TIMER_H__
+
+#include "ble_clock.h"
+#include "ble_status.h"
+#ifdef __DMA_LP__
+#include "stm32xx_timerserver.h"
+#endif /* __DMA_LP__ */
+
+/**
+ * timer
+ *
+ * A structure that represents a timer. Use Timer_Set() to set the timer.
+ *
+ */
+struct timer {
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+ tClockTime start;
+ tClockTime interval;
+
+#endif
+};
+
+typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void);
+
+/**
+ * Timer_Set
+ *
+ * @param[in] t Pointer to a timer structure
+ * @param[in] interval timeout value
+ *
+ * This function sets the timeout value of a timer.
+ *
+ */
+void Timer_Set(struct timer *t, tClockTime interval);
+
+/**
+ * Timer_Reset
+ *
+ * @param[in] t Pointer to a timer structure
+ *
+ * This function resets the timer with the same interval given
+ * with Timer_Set, starting from the time it previously expired.
+ *
+ */
+void Timer_Reset(struct timer *t);
+
+/**
+ * Timer_Restart
+ *
+ * @param[in] t Pointer to a timer structure
+ *
+ * This function resets the timer with the same interval given
+ * with Timer_Set, starting from the current time.
+ *
+ */
+void Timer_Restart(struct timer *t);
+
+/**
+ * Timer_Expired
+ *
+ * @param[in] t Pointer to a timer structure
+ *
+ * This function returns TRUE if timer is expired, FALSE otherwise.
+ *
+ */
+int Timer_Expired(struct timer *t);
+
+/**
+ * Timer_Expired
+ *
+ * @param[in] t Pointer to a timer structure
+ *
+ * This function returns the time needed for expiration.
+ *
+ * @return Time before timer's expiration.
+ */
+tClockTime Timer_Remaining(struct timer *t);
+
+#ifdef __DMA_LP__
+tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime,
+ TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb,
+ uint8_t *timerID);
+
+tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID);
+#endif /* __DMA_LP__ */
+
+#endif /* __GP_TIMER_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_hal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_hal.h Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,108 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __HAL_H__ +#define __HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void signalEventsToProcess(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __HAL_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_hal_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_hal_types.h Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __HAL_TYPES_H__ +#define __HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __HAL_TYPES_H__ */ +
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_hci.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_hci.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,241 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name : hci.h
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 19-July-2012
+* Description : Constants and functions for HCI layer. See Bluetooth Core
+* v 4.0, Vol. 2, Part E.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __HCI_H_
+#define __HCI_H_
+
+#include "ble_hal_types.h"
+#include "ble_link_layer.h"
+#include <ble_list.h>
+
+#define HCI_READ_PACKET_SIZE 128 //71
+
+/*** Data types ***/
+
+/* structure used to read received data */
+typedef struct _tHciDataPacket
+{
+ tListNode currentNode;
+ uint8_t dataBuff[HCI_READ_PACKET_SIZE];
+ uint8_t data_len;
+} tHciDataPacket;
+
+typedef enum
+{
+ BUSY,
+ AVAILABLE
+} HCI_CMD_STATUS_t;
+
+/**
+ * @defgroup HCI_Error_codes HCI Error codes
+ * @{
+ */
+#define HCI_UNKNOWN_COMMAND 0x01
+#define HCI_NO_CONNECTION 0x02
+#define HCI_HARDWARE_FAILURE 0x03
+#define HCI_PAGE_TIMEOUT 0x04
+#define HCI_AUTHENTICATION_FAILURE 0x05
+#define HCI_PIN_OR_KEY_MISSING 0x06
+#define HCI_MEMORY_FULL 0x07
+#define HCI_CONNECTION_TIMEOUT 0x08
+#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09
+#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a
+#define HCI_ACL_CONNECTION_EXISTS 0x0b
+#define HCI_COMMAND_DISALLOWED 0x0c
+#define HCI_REJECTED_LIMITED_RESOURCES 0x0d
+#define HCI_REJECTED_SECURITY 0x0e
+#define HCI_REJECTED_PERSONAL 0x0f
+#define HCI_HOST_TIMEOUT 0x10
+#define HCI_UNSUPPORTED_FEATURE 0x11
+#define HCI_INVALID_PARAMETERS 0x12
+#define HCI_OE_USER_ENDED_CONNECTION 0x13
+#define HCI_OE_LOW_RESOURCES 0x14
+#define HCI_OE_POWER_OFF 0x15
+#define HCI_CONNECTION_TERMINATED 0x16
+#define HCI_REPEATED_ATTEMPTS 0x17
+#define HCI_PAIRING_NOT_ALLOWED 0x18
+#define HCI_UNKNOWN_LMP_PDU 0x19
+#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a
+#define HCI_SCO_OFFSET_REJECTED 0x1b
+#define HCI_SCO_INTERVAL_REJECTED 0x1c
+#define HCI_AIR_MODE_REJECTED 0x1d
+#define HCI_INVALID_LMP_PARAMETERS 0x1e
+#define HCI_UNSPECIFIED_ERROR 0x1f
+#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20
+#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21
+#define HCI_LMP_RESPONSE_TIMEOUT 0x22
+#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23
+#define HCI_LMP_PDU_NOT_ALLOWED 0x24
+#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25
+#define HCI_UNIT_LINK_KEY_USED 0x26
+#define HCI_QOS_NOT_SUPPORTED 0x27
+#define HCI_INSTANT_PASSED 0x28
+#define HCI_PAIRING_NOT_SUPPORTED 0x29
+#define HCI_TRANSACTION_COLLISION 0x2a
+#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c
+#define HCI_QOS_REJECTED 0x2d
+#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e
+#define HCI_INSUFFICIENT_SECURITY 0x2f
+#define HCI_PARAMETER_OUT_OF_RANGE 0x30
+#define HCI_ROLE_SWITCH_PENDING 0x32
+#define HCI_SLOT_VIOLATION 0x34
+#define HCI_ROLE_SWITCH_FAILED 0x35
+#define HCI_EIR_TOO_LARGE 0x36
+#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37
+#define HCI_HOST_BUSY_PAIRING 0x38
+#define HCI_CONN_REJ_NO_CH_FOUND 0x39
+#define HCI_CONTROLLER_BUSY 0x3A
+#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B
+#define HCI_DIRECTED_ADV_TIMEOUT 0x3C
+#define HCI_CONN_TERM_MIC_FAIL 0x3D
+#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E
+#define HCI_MAC_CONN_FAILED 0x3F
+/**
+ * @}
+ */
+
+
+/*
+ * HCI library functions.
+ * Each function returns 0 in case of success, otherwise one of the error codes.
+ */
+
+int hci_reset(void);
+
+int hci_disconnect(uint16_t handle, uint8_t reason);
+
+int hci_le_set_advertise_enable(uint8_t enable);
+
+int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype,
+ uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map,
+ uint8_t filter);
+
+int hci_le_set_scan_parameters(uint8_t type, uint16_t interval,
+ uint16_t window, uint8_t own_bdaddr_type,
+ uint8_t filter);
+
+int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup);
+
+int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]);
+
+int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]);
+
+int hci_le_rand(uint8_t random_number[8]);
+
+int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level);
+
+int hci_acl_data(const uint8_t * data, uint16_t len);
+
+int hci_le_set_random_address(tBDAddr bdaddr);
+
+int hci_read_bd_addr(tBDAddr bdaddr);
+
+int hci_le_read_white_list_size(uint8_t *size);
+
+int hci_le_clear_white_list(void);
+
+int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr);
+
+int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr);
+
+int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]);
+
+int hci_le_ltk_request_reply(uint8_t key[16]);
+
+int hci_le_ltk_request_neg_reply(void);
+
+int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt);
+
+int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type,
+ const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval,
+ uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length);
+
+int hci_le_create_connection_cancel(void);
+
+int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t *tx_level);
+
+int hci_read_rssi(uint16_t *conn_handle, int8_t *rssi);
+
+int hci_le_read_local_supported_features(uint8_t *features);
+
+int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]);
+
+int hci_le_read_supported_states(uint8_t states[8]);
+
+int hci_le_receiver_test(uint8_t frequency);
+
+int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload);
+
+int hci_le_test_end(uint16_t *num_pkts);
+
+int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version,
+ uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion);
+
+/**
+ * This function must be used to pass the packet received from the HCI
+ * interface to the BLE Stack HCI state machine.
+ *
+ * @param[in] hciReadPacket The packet that is received from HCI interface.
+ *
+ */
+void HCI_Input(tHciDataPacket *hciReadPacket);
+
+/**
+ * Initialization function. Must be done before any data can be received from
+ * BLE controller.
+ */
+void HCI_Init(void);
+
+/**
+ * Callback used to pass events to application.
+ *
+ * @param[in] pckt The event.
+ *
+ */
+extern void HCI_Event_CB(void *pckt);
+
+/**
+ * Processing function that must be called after an event is received from
+ * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if
+ * necessary.
+*/
+void HCI_Process(void);
+
+/**
+ * @brief Check if queue of HCI event is empty or not.
+ * @note This funtion can be used to check if the event queue from BlueNRG is empty. This
+ * is useful when checking if it is safe to go to sleep.
+ * @return TRUE if event queue is empty. FALSE otherwhise.
+ */
+BOOL HCI_Queue_Empty(void);
+/**
+ * Iterrupt service routine that must be called when the BlueNRG
+ * reports a packet received or an event to the host through the
+ * BlueNRG interrupt line.
+ */
+#ifdef __DMA_LP__
+void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len);
+void HCI_Process_Notification_Request(void);
+void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status);
+void HCI_Wait_For_Response(void);
+#else
+void HCI_Isr(void);
+#endif /* __DMA_LP__ */
+
+extern tListNode hciReadPktPool;
+extern tListNode hciReadPktRxQueue;
+
+#endif /* __HCI_H_ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_hci_const.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_hci_const.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,563 @@
+/******************************************************************************
+*
+* File Description
+* ---------------------
+* This file defines constants and functions for HCI layer.
+* See Bluetooth Core v 4.0, Vol. 2, Part E.
+*
+*******************************************************************************/
+
+#ifndef __HCI_INTERNAL_H_
+#define __HCI_INTERNAL_H_
+
+#include "ble_compiler.h"
+#include "ble_hal_types.h"
+#include "ble_clock.h"
+#include "ble_link_layer.h"
+#include "ble_hci.h"
+
+#define DEFAULT_TIMEOUT (CLOCK_SECOND/10)
+
+/**
+ * Maximum payload of HCI commands that can be sent. Change this value if needed.
+ * This value can be up to 255.
+ */
+#define HCI_MAX_PAYLOAD_SIZE 128
+
+/* HCI Packet types */
+#define HCI_COMMAND_PKT 0x01
+#define HCI_ACLDATA_PKT 0x02
+#define HCI_SCODATA_PKT 0x03
+#define HCI_EVENT_PKT 0x04
+#define HCI_VENDOR_PKT 0xff
+
+typedef __packed struct _hci_uart_pckt{
+ uint8_t type;
+ uint8_t data[VARIABLE_SIZE];
+} PACKED hci_uart_pckt;
+#define HCI_HDR_SIZE 1
+
+typedef __packed struct _hci_command_hdr{
+ uint16_t opcode; /* OCF & OGF */
+ uint8_t plen;
+} PACKED hci_command_hdr;
+#define HCI_COMMAND_HDR_SIZE 3
+
+typedef __packed struct _hci_event_pckt{
+ uint8_t evt;
+ uint8_t plen;
+ uint8_t data[VARIABLE_SIZE];
+} PACKED hci_event_pckt;
+#define HCI_EVENT_HDR_SIZE 2
+
+typedef __packed struct _hci_acl_hdr{
+ uint16_t handle; /* Handle & Flags(PB, BC) */
+ uint16_t dlen;
+} PACKED hci_acl_hdr;
+#define HCI_ACL_HDR_SIZE 4
+
+/* Link Control */
+#define OGF_LINK_CTL 0x01
+
+#define OCF_DISCONNECT 0x0006
+typedef __packed struct _disconnect_cp{
+ uint16_t handle;
+ uint8_t reason;
+} PACKED disconnect_cp;
+#define DISCONNECT_CP_SIZE 3
+
+/* Host Controller and Baseband */
+#define OGF_HOST_CTL 0x03
+
+#define OCF_SET_EVENT_MASK 0x0001
+#define OCF_RESET 0x0003
+
+#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D
+typedef __packed struct _read_transmit_power_level_cp{
+ uint16_t handle;
+ uint8_t type;
+} PACKED read_transmit_power_level_cp;
+#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3
+typedef __packed struct _read_transmit_power_level_rp{
+ uint8_t status;
+ uint16_t handle;
+ int8_t level;
+} PACKED read_transmit_power_level_rp;
+#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4
+
+#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031
+#define OCF_HOST_BUFFER_SIZE 0x0033
+#define OCF_HOST_NUM_COMP_PKTS 0x0035
+
+/* Informational Parameters */
+#define OGF_INFO_PARAM 0x04
+
+#define OCF_READ_LOCAL_VERSION 0x0001
+typedef __packed struct _read_local_version_rp{
+ uint8_t status;
+ uint8_t hci_version;
+ uint16_t hci_revision;
+ uint8_t lmp_pal_version;
+ uint16_t manufacturer_name;
+ uint16_t lmp_pal_subversion;
+} PACKED read_local_version_rp;
+#define READ_LOCAL_VERSION_RP_SIZE 9
+
+#define OCF_READ_LOCAL_COMMANDS 0x0002
+#define OCF_READ_LOCAL_FEATURES 0x0003
+
+#define OCF_READ_BD_ADDR 0x0009
+typedef __packed struct _read_bd_addr_rp{
+ uint8_t status;
+ tBDAddr bdaddr;
+} PACKED read_bd_addr_rp;
+#define READ_BD_ADDR_RP_SIZE 7
+
+/* Status params */
+#define OGF_STATUS_PARAM 0x05
+
+#define OCF_READ_RSSI 0x0005
+typedef __packed struct _read_rssi_cp{
+ uint16_t handle;
+} PACKED read_rssi_cp;
+#define READ_RSSI_CP_SIZE 2
+typedef __packed struct _read_rssi_rp{
+ uint8_t status;
+ uint16_t handle;
+ int8_t rssi;
+} PACKED read_rssi_rp;
+#define READ_RSSI_RP_SIZE 4
+
+
+/* LE commands */
+#define OGF_LE_CTL 0x08
+
+#define OCF_LE_SET_EVENT_MASK 0x0001
+typedef __packed struct _le_set_event_mask_cp{
+ uint8_t mask[8];
+} PACKED le_set_event_mask_cp;
+#define LE_SET_EVENT_MASK_CP_SIZE 8
+
+#define OCF_LE_READ_BUFFER_SIZE 0x0002
+typedef __packed struct _le_read_buffer_size_rp{
+ uint8_t status;
+ uint16_t pkt_len;
+ uint8_t max_pkt;
+} PACKED le_read_buffer_size_rp;
+#define LE_READ_BUFFER_SIZE_RP_SIZE 4
+
+#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003
+typedef __packed struct _le_read_local_supported_features_rp{
+ uint8_t status;
+ uint8_t features[8];
+} PACKED le_read_local_supported_features_rp;
+#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9
+
+#define OCF_LE_SET_RANDOM_ADDRESS 0x0005
+typedef __packed struct _le_set_random_address_cp{
+ tBDAddr bdaddr;
+} PACKED le_set_random_address_cp;
+#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6
+
+#define OCF_LE_SET_ADV_PARAMETERS 0x0006
+typedef __packed struct _le_set_adv_parameters_cp{
+ uint16_t min_interval;
+ uint16_t max_interval;
+ uint8_t advtype;
+ uint8_t own_bdaddr_type;
+ uint8_t direct_bdaddr_type;
+ tBDAddr direct_bdaddr;
+ uint8_t chan_map;
+ uint8_t filter;
+} PACKED le_set_adv_parameters_cp;
+#define LE_SET_ADV_PARAMETERS_CP_SIZE 15
+
+#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007
+typedef __packed struct _le_read_adv_channel_tx_power_rp{
+ uint8_t status;
+ int8_t level;
+} PACKED le_read_adv_channel_tx_power_rp;
+#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2
+
+#define OCF_LE_SET_ADV_DATA 0x0008
+typedef __packed struct _le_set_adv_data_cp{
+ uint8_t length;
+ uint8_t data[31];
+} PACKED le_set_adv_data_cp;
+#define LE_SET_ADV_DATA_CP_SIZE 32
+
+#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009
+typedef __packed struct _le_set_scan_response_data_cp{
+ uint8_t length;
+ uint8_t data[31];
+} PACKED le_set_scan_response_data_cp;
+#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32
+
+#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A
+typedef __packed struct _le_set_advertise_enable_cp{
+ uint8_t enable;
+} PACKED le_set_advertise_enable_cp;
+#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1
+
+#define OCF_LE_SET_SCAN_PARAMETERS 0x000B
+typedef __packed struct _le_set_scan_parameters_cp{
+ uint8_t type;
+ uint16_t interval;
+ uint16_t window;
+ uint8_t own_bdaddr_type;
+ uint8_t filter;
+} PACKED le_set_scan_parameters_cp;
+#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7
+
+#define OCF_LE_SET_SCAN_ENABLE 0x000C
+typedef __packed struct _le_set_scan_enable_cp{
+ uint8_t enable;
+ uint8_t filter_dup;
+} PACKED le_set_scan_enable_cp;
+#define LE_SET_SCAN_ENABLE_CP_SIZE 2
+
+#define OCF_LE_CREATE_CONN 0x000D
+typedef __packed struct _le_create_connection_cp{
+ uint16_t interval;
+ uint16_t window;
+ uint8_t initiator_filter;
+ uint8_t peer_bdaddr_type;
+ tBDAddr peer_bdaddr;
+ uint8_t own_bdaddr_type;
+ uint16_t min_interval;
+ uint16_t max_interval;
+ uint16_t latency;
+ uint16_t supervision_timeout;
+ uint16_t min_ce_length;
+ uint16_t max_ce_length;
+} PACKED le_create_connection_cp;
+#define LE_CREATE_CONN_CP_SIZE 25
+
+#define OCF_LE_CREATE_CONN_CANCEL 0x000E
+
+#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F
+typedef __packed struct _le_read_white_list_size_rp{
+ uint8_t status;
+ uint8_t size;
+} PACKED le_read_white_list_size_rp;
+#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2
+
+#define OCF_LE_CLEAR_WHITE_LIST 0x0010
+
+#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011
+typedef __packed struct _le_add_device_to_white_list_cp{
+ uint8_t bdaddr_type;
+ tBDAddr bdaddr;
+} PACKED le_add_device_to_white_list_cp;
+#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7
+
+#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012
+typedef __packed struct _le_remove_device_from_white_list_cp{
+ uint8_t bdaddr_type;
+ tBDAddr bdaddr;
+} PACKED le_remove_device_from_white_list_cp;
+#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7
+
+#define OCF_LE_CONN_UPDATE 0x0013
+typedef __packed struct _le_connection_update_cp{
+ uint16_t handle;
+ uint16_t min_interval;
+ uint16_t max_interval;
+ uint16_t latency;
+ uint16_t supervision_timeout;
+ uint16_t min_ce_length;
+ uint16_t max_ce_length;
+} PACKED le_connection_update_cp;
+#define LE_CONN_UPDATE_CP_SIZE 14
+
+#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014
+typedef __packed struct _le_set_host_channel_classification_cp{
+ uint8_t map[5];
+} PACKED le_set_host_channel_classification_cp;
+#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5
+
+#define OCF_LE_READ_CHANNEL_MAP 0x0015
+typedef __packed struct _le_read_channel_map_cp{
+ uint16_t handle;
+} PACKED le_read_channel_map_cp;
+#define LE_READ_CHANNEL_MAP_CP_SIZE 2
+
+typedef __packed struct _le_read_channel_map_rp{
+ uint8_t status;
+ uint16_t handle;
+ uint8_t map[5];
+} PACKED le_read_channel_map_rp;
+#define LE_READ_CHANNEL_MAP_RP_SIZE 8
+
+#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016
+typedef __packed struct _le_read_remote_used_features_cp{
+ uint16_t handle;
+} PACKED le_read_remote_used_features_cp;
+#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2
+
+#define OCF_LE_ENCRYPT 0x0017
+typedef __packed struct _le_encrypt_cp{
+ uint8_t key[16];
+ uint8_t plaintext[16];
+} PACKED le_encrypt_cp;
+#define LE_ENCRYPT_CP_SIZE 32
+
+typedef __packed struct _le_encrypt_rp{
+ uint8_t status;
+ uint8_t encdata[16];
+} PACKED le_encrypt_rp;
+#define LE_ENCRYPT_RP_SIZE 17
+
+#define OCF_LE_RAND 0x0018
+typedef __packed struct _le_rand_rp{
+ uint8_t status;
+ uint8_t random[8];
+} PACKED le_rand_rp;
+#define LE_RAND_RP_SIZE 9
+
+#define OCF_LE_START_ENCRYPTION 0x0019
+typedef __packed struct _le_start_encryption_cp{
+ uint16_t handle;
+ uint8_t random[8];
+ uint16_t diversifier;
+ uint8_t key[16];
+} PACKED le_start_encryption_cp;
+#define LE_START_ENCRYPTION_CP_SIZE 28
+
+#define OCF_LE_LTK_REPLY 0x001A
+typedef __packed struct _le_ltk_reply_cp{
+ uint16_t handle;
+ uint8_t key[16];
+} PACKED le_ltk_reply_cp;
+#define LE_LTK_REPLY_CP_SIZE 18
+
+typedef __packed struct _le_ltk_reply_rp{
+ uint8_t status;
+ uint16_t handle;
+} PACKED le_ltk_reply_rp;
+#define LE_LTK_REPLY_RP_SIZE 3
+
+#define OCF_LE_LTK_NEG_REPLY 0x001B
+typedef __packed struct _le_ltk_neg_reply_cp{
+ uint16_t handle;
+} PACKED le_ltk_neg_reply_cp;
+#define LE_LTK_NEG_REPLY_CP_SIZE 2
+
+typedef __packed struct _le_ltk_neg_reply_rp{
+ uint8_t status;
+ uint16_t handle;
+} PACKED le_ltk_neg_reply_rp;
+#define LE_LTK_NEG_REPLY_RP_SIZE 3
+
+#define OCF_LE_READ_SUPPORTED_STATES 0x001C
+typedef __packed struct _le_read_supported_states_rp{
+ uint8_t status;
+ uint8_t states[8];
+} PACKED le_read_supported_states_rp;
+#define LE_READ_SUPPORTED_STATES_RP_SIZE 9
+
+#define OCF_LE_RECEIVER_TEST 0x001D
+typedef __packed struct _le_receiver_test_cp{
+ uint8_t frequency;
+} PACKED le_receiver_test_cp;
+#define LE_RECEIVER_TEST_CP_SIZE 1
+
+#define OCF_LE_TRANSMITTER_TEST 0x001E
+typedef __packed struct _le_transmitter_test_cp{
+ uint8_t frequency;
+ uint8_t length;
+ uint8_t payload;
+} PACKED le_transmitter_test_cp;
+#define LE_TRANSMITTER_TEST_CP_SIZE 3
+
+#define OCF_LE_TEST_END 0x001F
+typedef __packed struct _le_test_end_rp{
+ uint8_t status;
+ uint16_t num_pkts;
+} PACKED le_test_end_rp;
+#define LE_TEST_END_RP_SIZE 3
+
+/* Vendor specific commands */
+#define OGF_VENDOR_CMD 0x3f
+
+
+/*------------- Events -------------*/
+#define EVT_CONN_COMPLETE 0x03
+typedef __packed struct _evt_conn_complete{
+ uint8_t status;
+ uint16_t handle;
+ tBDAddr bdaddr;
+ uint8_t link_type;
+ uint8_t encr_mode;
+} PACKED evt_conn_complete;
+#define EVT_CONN_COMPLETE_SIZE 13
+
+#define EVT_DISCONN_COMPLETE 0x05
+typedef __packed struct _evt_disconn_complete{
+ uint8_t status;
+ uint16_t handle;
+ uint8_t reason;
+} PACKED evt_disconn_complete;
+#define EVT_DISCONN_COMPLETE_SIZE 4
+
+#define EVT_ENCRYPT_CHANGE 0x08
+typedef __packed struct _evt_encrypt_change{
+ uint8_t status;
+ uint16_t handle;
+ uint8_t encrypt;
+} PACKED evt_encrypt_change;
+#define EVT_ENCRYPT_CHANGE_SIZE 5
+
+#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C
+
+#define EVT_CMD_COMPLETE 0x0E
+typedef __packed struct _evt_cmd_complete{
+ uint8_t ncmd;
+ uint16_t opcode;
+} PACKED evt_cmd_complete;
+#define EVT_CMD_COMPLETE_SIZE 3
+
+#define EVT_CMD_STATUS 0x0F
+typedef __packed struct _evt_cmd_status{
+ uint8_t status;
+ uint8_t ncmd;
+ uint16_t opcode;
+} PACKED evt_cmd_status;
+#define EVT_CMD_STATUS_SIZE 4
+
+#define EVT_HARDWARE_ERROR 0x10
+typedef __packed struct _evt_hardware_error{
+ uint8_t code;
+} PACKED evt_hardware_error;
+#define EVT_HARDWARE_ERROR_SIZE 1
+
+#define EVT_NUM_COMP_PKTS 0x13
+typedef __packed struct _evt_num_comp_pkts{
+ uint8_t num_hndl;
+ /* variable length part */
+} PACKED evt_num_comp_pkts;
+#define EVT_NUM_COMP_PKTS_SIZE 1
+
+/* variable length part of evt_num_comp_pkts. */
+typedef __packed struct _evt_num_comp_pkts_param{
+ uint16_t hndl;
+ uint16_t num_comp_pkts;
+} PACKED evt_num_comp_pkts_param;
+#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1
+
+#define EVT_DATA_BUFFER_OVERFLOW 0x1A
+typedef __packed struct _evt_data_buffer_overflow{
+ uint8_t link_type;
+} PACKED evt_data_buffer_overflow;
+#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1
+
+#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30
+typedef __packed struct _evt_encryption_key_refresh_complete{
+ uint8_t status;
+ uint16_t handle;
+} PACKED evt_encryption_key_refresh_complete;
+#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3
+
+#define EVT_LE_META_EVENT 0x3E
+typedef __packed struct _evt_le_meta_event{
+ uint8_t subevent;
+ uint8_t data[VARIABLE_SIZE];
+} PACKED evt_le_meta_event;
+#define EVT_LE_META_EVENT_SIZE 1
+
+#define EVT_LE_CONN_COMPLETE 0x01
+typedef __packed struct _evt_le_connection_complete{
+ uint8_t status;
+ uint16_t handle;
+ uint8_t role;
+ uint8_t peer_bdaddr_type;
+ tBDAddr peer_bdaddr;
+ uint16_t interval;
+ uint16_t latency;
+ uint16_t supervision_timeout;
+ uint8_t master_clock_accuracy;
+} PACKED evt_le_connection_complete;
+#define EVT_LE_CONN_COMPLETE_SIZE 18
+
+#define EVT_LE_ADVERTISING_REPORT 0x02
+typedef __packed struct _le_advertising_info{
+ uint8_t evt_type;
+ uint8_t bdaddr_type;
+ tBDAddr bdaddr;
+ uint8_t data_length;
+ uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer).
+} PACKED le_advertising_info;
+#define LE_ADVERTISING_INFO_SIZE 9
+
+#define EVT_LE_CONN_UPDATE_COMPLETE 0x03
+typedef __packed struct _evt_le_connection_update_complete{
+ uint8_t status;
+ uint16_t handle;
+ uint16_t interval;
+ uint16_t latency;
+ uint16_t supervision_timeout;
+} PACKED evt_le_connection_update_complete;
+#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9
+
+#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04
+typedef __packed struct _evt_le_read_remote_used_features_complete{
+ uint8_t status;
+ uint16_t handle;
+ uint8_t features[8];
+} PACKED evt_le_read_remote_used_features_complete;
+#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11
+
+#define EVT_LE_LTK_REQUEST 0x05
+typedef __packed struct _evt_le_long_term_key_request{
+ uint16_t handle;
+ uint8_t random[8];
+ uint16_t ediv;
+} PACKED evt_le_long_term_key_request;
+#define EVT_LE_LTK_REQUEST_SIZE 12
+
+/**
+* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR,
+* application can use @ref evt_blue_aci structure to parse the packet.
+*/
+#define EVT_VENDOR 0xFF
+
+
+/* Command opcode pack/unpack */
+#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10))
+#define cmd_opcode_ogf(op) (op >> 10)
+#define cmd_opcode_ocf(op) (op & 0x03ff)
+
+
+struct hci_request {
+ uint16_t ogf;
+ uint16_t ocf;
+ int event;
+ void *cparam;
+ int clen;
+ void *rparam;
+ int rlen;
+};
+
+void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param);
+
+typedef enum {
+ WAITING_TYPE,
+ WAITING_OPCODE1,
+ WAITING_OPCODE2,
+ WAITING_EVENT_CODE,
+ WAITING_HANDLE,
+ WAITING_HANDLE_FLAG,
+ WAITING_PARAM_LEN,
+ WAITING_DATA_LEN1,
+ WAITING_DATA_LEN2,
+ WAITING_PAYLOAD
+}hci_state;
+
+typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len);
+
+/* HCI library functions. */
+void hci_init(void);
+
+int hci_send_req(struct hci_request *r, BOOL async);
+
+#endif /* __HCI_INTERNAL_H_ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_link_layer.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_link_layer.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,161 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name : link_layer.h
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 19-July-2012
+* Description : Header file for BlueNRG's link layer. It contains
+* definition of functions for link layer, most of which are
+* mapped to HCI commands.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef _LINK_LAYER_H
+#define _LINK_LAYER_H
+
+#include <ble_status.h>
+
+/**
+ *@addtogroup GAP GAP
+ *@brief API for GAP layer.
+ *@{
+ */
+
+/**
+ *@name Advertising filter
+ *Advertising policy for filtering (white list related)
+ *@{
+ */
+#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */
+#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */
+#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */
+#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */
+/**
+ * @}
+ */
+
+
+/**
+ * Bluetooth 48 bit address (in little-endian order).
+ */
+typedef uint8_t tBDAddr[6];
+
+
+/**
+ *@name Bluetooth address types
+ * Bluetooth address types
+ *@{
+ */
+#define PUBLIC_ADDR (0)
+#define RANDOM_ADDR (1)
+#define STATIC_RANDOM_ADDR (1)
+#define RESOLVABLE_PRIVATE_ADDR (2)
+#define NON_RESOLVABLE_PRIVATE_ADDR (3)
+/**
+ * @}
+ */
+
+/**
+ *@name Directed advertising types
+ * Type of advertising during directed advertising
+ *@{
+ */
+#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1)
+#define LOW_DUTY_CYCLE_DIRECTED_ADV (4)
+/**
+ * @}
+ */
+
+/**
+ * @name Advertising type
+ * @{
+ */
+
+/**
+ * undirected scannable and connectable
+ */
+#define ADV_IND (0x00)
+
+/**
+ * directed non scannable
+ */
+#define ADV_DIRECT_IND (0x01)
+
+/**
+ * scannable non connectable
+ */
+#define ADV_SCAN_IND (0x02)
+
+/**
+ * non-connectable and no scan response (used for passive scan)
+ */
+#define ADV_NONCONN_IND (0x03)
+
+/**
+ * scan response
+ */
+#define SCAN_RSP (0x04)
+
+/**
+ * @}
+ */
+
+/* 0X05-0XFF RESERVED */
+
+/**
+ * @name Advertising ranges
+ * @{
+ */
+
+/**
+ * lowest allowed interval value for connectable types(20ms)..multiple of 625us
+ */
+#define ADV_INTERVAL_LOWEST_CONN (0X0020)
+
+/**
+ * highest allowed interval value (10.24s)..multiple of 625us.
+ */
+#define ADV_INTERVAL_HIGHEST (0X4000)
+
+/**
+ * lowest allowed interval value for non connectable types
+ * (100ms)..multiple of 625us.
+ */
+#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0)
+
+/**
+ * @}
+ */
+
+/**
+ * @name Advertising channels
+ * @{
+ */
+#define ADV_CH_37 0x01
+#define ADV_CH_38 0x02
+#define ADV_CH_39 0x04
+/**
+ * @}
+ */
+
+/**
+ * @name Scan_types Scan types
+ * @{
+ */
+#define PASSIVE_SCAN 0
+#define ACTIVE_SCAN 1
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#endif /* _LINK_LAYER_H */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_list.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_list.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,47 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name : list.h
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 19-July-2012
+* Description : Header file for linked list library.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef _LIST_H_
+#define _LIST_H_
+
+typedef struct _tListNode {
+ struct _tListNode * next;
+ struct _tListNode * prev;
+}tListNode, *pListNode;
+
+void list_init_head (tListNode * listHead);
+
+uint8_t list_is_empty (tListNode * listHead);
+
+void list_insert_head (tListNode * listHead, tListNode * node);
+
+void list_insert_tail (tListNode * listHead, tListNode * node);
+
+void list_remove_node (tListNode * node);
+
+void list_remove_head (tListNode * listHead, tListNode ** node );
+
+void list_remove_tail (tListNode * listHead, tListNode ** node );
+
+void list_insert_node_after (tListNode * node, tListNode * ref_node);
+
+void list_insert_node_before (tListNode * node, tListNode * ref_node);
+
+int list_get_size (tListNode * listHead);
+
+void list_get_next_node (tListNode * ref_node, tListNode ** node);
+
+void list_get_prev_node (tListNode * ref_node, tListNode ** node);
+
+#endif /* _LIST_H_ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_osal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_osal.h Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __OSAL_H__ +#define __OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __OSAL_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_sm.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_sm.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,158 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name : sm.h
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 19-July-2012
+* Description : Header file for BlueNRG's security manager.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __SM_H__
+#define __SM_H__
+
+/******************************************************************************
+* Macros
+*****************************************************************************/
+
+/**
+ *@addtogroup GAP GAP
+ *@brief API for GAP layer.
+ *@{
+ */
+
+/* IO capabilities */
+/**
+ * @anchor IO_capabilities
+ * @name IO capabilities
+ * @{
+ */
+#define IO_CAP_DISPLAY_ONLY (0x00)
+#define IO_CAP_DISPLAY_YES_NO (0x01)
+#define IO_CAP_KEYBOARD_ONLY (0x02)
+#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03)
+#define IO_CAP_KEYBOARD_DISPLAY (0x04)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Auth_req
+ * @name Authentication requirements
+ * @{
+ */
+#define BONDING (0x01)
+#define NO_BONDING (0x00)
+/**
+ * @}
+ */
+
+/**
+ * @anchor MITM_req
+ * @name MITM protection requirements
+ * @{
+ */
+#define MITM_PROTECTION_NOT_REQUIRED (0x00)
+#define MITM_PROTECTION_REQUIRED (0x01)
+/**
+ * @}
+ */
+
+/**
+ * @anchor OOB_Data
+ * @name Out-Of-Band data
+ * @{
+ */
+#define OOB_AUTH_DATA_ABSENT (0x00)
+#define OOB_AUTH_DATA_PRESENT (0x01)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Author_req
+ * @name Authorization requirements
+ * @{
+ */
+#define AUTHORIZATION_NOT_REQUIRED (0x00)
+#define AUTHORIZATION_REQUIRED (0x01)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Conn_authorization
+ * @name Connection authorization
+ * @{
+ */
+#define CONNECTION_AUTHORIZED (0x01)
+#define CONNECTION_REJECTED (0x02)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Use_fixed_pin
+ * @name Use fixed pin
+ * @{
+ */
+#define USE_FIXED_PIN_FOR_PAIRING (0x0)
+#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01)
+/**
+ * @}
+ */
+
+/**
+ * @anchor link_security_status
+ * @name Link security status
+ * @{
+ */
+#define SM_LINK_AUTHENTICATED (0x01)
+#define SM_LINK_AUTHORIZED (0x02)
+#define SM_LINK_ENCRYPTED (0x04)
+/**
+ * @}
+ */
+
+/**
+ * @anchor SMP_pairing_failed_codes
+ * @name SMP pairing failed reason codes
+ * @{
+ */
+#define PASSKEY_ENTRY_FAILED (0x01)
+#define OOB_NOT_AVAILABLE (0x02)
+#define AUTH_REQ_CANNOT_BE_MET (0x03)
+#define CONFIRM_VALUE_FAILED (0x04)
+#define PAIRING_NOT_SUPPORTED (0x05)
+#define INSUFF_ENCRYPTION_KEY_SIZE (0x06)
+#define CMD_NOT_SUPPORTED (0x07)
+#define UNSPECIFIED_REASON (0x08)
+#define VERY_EARLY_NEXT_ATTEMPT (0x09)
+#define SM_INVALID_PARAMS (0x0A)
+/**
+ * @}
+ */
+
+/**
+ * @anchor pairing_failed_codes
+ * @name Pairing failed error codes
+ * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event
+ * @{
+ */
+#define SM_PAIRING_SUCCESS (0x00)
+#define SM_PAIRING_TIMEOUT (0x01)
+#define SM_PAIRING_FAILED (0x02)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* __SM_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_status.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/ble_status.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,115 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name : ble_status.h
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 19-July-2012
+* Description : Header file with BLE Stack status codes.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef __BLE_STATUS_H__
+#define __BLE_STATUS_H__
+
+#include <ble_hal_types.h>
+
+
+/** @defgroup ble_status Bluetooth Status/Error Codes
+ * @{
+ */
+
+typedef uint8_t tBleStatus;
+
+/* Error Codes as specified by the specification
+ * according to the spec the error codes range
+ * from 0x00 to 0x3F
+ */
+#define ERR_CMD_SUCCESS (0x00)
+#define BLE_STATUS_SUCCESS (0x00)
+#define ERR_UNKNOWN_HCI_COMMAND (0x01)
+#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02)
+
+#define ERR_AUTH_FAILURE (0x05)
+#define ERR_PIN_OR_KEY_MISSING (0x06)
+#define ERR_MEM_CAPACITY_EXCEEDED (0x07)
+#define ERR_CONNECTION_TIMEOUT (0x08)
+
+#define ERR_COMMAND_DISALLOWED (0x0C)
+
+#define ERR_UNSUPPORTED_FEATURE (0x11)
+#define ERR_INVALID_HCI_CMD_PARAMS (0x12)
+#define ERR_RMT_USR_TERM_CONN (0x13)
+#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14)
+#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15)
+#define ERR_LOCAL_HOST_TERM_CONN (0x16)
+
+#define ERR_UNSUPP_RMT_FEATURE (0x1A)
+
+#define ERR_INVALID_LMP_PARAM (0x1E)
+#define ERR_UNSPECIFIED_ERROR (0x1F)
+
+#define ERR_LL_RESP_TIMEOUT (0x22)
+#define ERR_LMP_PDU_NOT_ALLOWED (0x24)
+
+#define ERR_INSTANT_PASSED (0x28)
+
+#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29)
+#define ERR_CONTROLLER_BUSY (0x3A)
+
+#define ERR_DIRECTED_ADV_TIMEOUT (0x3C)
+
+#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D)
+
+#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E)
+
+
+#define BLE_STATUS_FAILED (0x41)
+#define BLE_STATUS_INVALID_PARAMS (0x42)
+#define BLE_STATUS_BUSY (0x43)
+#define BLE_STATUS_INVALID_LEN_PDU (0x44)
+#define BLE_STATUS_PENDING (0x45)
+#define BLE_STATUS_NOT_ALLOWED (0x46)
+#define BLE_STATUS_ERROR (0x47)
+#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48)
+
+#define FLASH_READ_FAILED (0x49)
+#define FLASH_WRITE_FAILED (0x4A)
+#define FLASH_ERASE_FAILED (0x4B)
+
+#define BLE_STATUS_INVALID_CID (0x50)
+
+#define TIMER_NOT_VALID_LAYER (0x54)
+#define TIMER_INSUFFICIENT_RESOURCES (0x55)
+
+#define BLE_STATUS_CSRK_NOT_FOUND (0x5A)
+#define BLE_STATUS_IRK_NOT_FOUND (0x5B)
+#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C)
+#define BLE_STATUS_SEC_DB_FULL (0x5D)
+#define BLE_STATUS_DEV_NOT_BONDED (0x5E)
+#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F)
+
+#define BLE_STATUS_INVALID_HANDLE (0x60)
+#define BLE_STATUS_INVALID_PARAMETER (0x61)
+#define BLE_STATUS_OUT_OF_HANDLE (0x62)
+#define BLE_STATUS_INVALID_OPERATION (0x63)
+#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64)
+#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65)
+#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66)
+
+ /*
+ * Library Error Codes
+ */
+#define BLE_STATUS_TIMEOUT (0xFF)
+#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0)
+#define BLE_STATUS_NULL_PARAM (0xF1)
+
+/**
+ * @}
+ */
+
+
+#endif /* __BLE_STATUS_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_aci.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_aci.h Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_aci_const.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_aci_const.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,780 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name : bluenrg_aci_const.h
+* Author : AMS - AAS
+* Version : V1.0.0
+* Date : 26-Jun-2014
+* Description : Header file with ACI definitions for BlueNRG FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_ACI_CONST_H_
+#define __BLUENRG_ACI_CONST_H_
+
+#include "ble_compiler.h"
+#include "ble_link_layer.h"
+#include "ble_hci_const.h"
+#include "bluenrg_gatt_server.h"
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+#define OCF_HAL_WRITE_CONFIG_DATA 0x000C
+
+#define OCF_HAL_READ_CONFIG_DATA 0x000D
+typedef __packed struct _hal_read_config_data_cp{
+ uint8_t offset;
+} PACKED hal_read_config_data_cp;
+#define HAL_READ_CONFIG_DATA_RP_SIZE 1
+typedef __packed struct _hal_read_config_data_rp{
+ uint8_t status;
+ uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE];
+} PACKED hal_read_config_data_rp;
+
+#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F
+typedef __packed struct _hal_set_tx_power_level_cp{
+ uint8_t en_high_power;
+ uint8_t pa_level;
+} PACKED hal_set_tx_power_level_cp;
+#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2
+
+#define OCF_HAL_DEVICE_STANDBY 0x0013
+
+#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014
+typedef __packed struct _hal_le_tx_test_packet_number_rp{
+ uint8_t status;
+ uint32_t number_of_packets;
+} PACKED hal_le_tx_test_packet_number_rp;
+
+#define OCF_HAL_TONE_START 0x0015
+typedef __packed struct _hal_tone_start_cp{
+ uint8_t rf_channel;
+} PACKED hal_tone_start_cp;
+#define HAL_TONE_START_CP_SIZE 1
+
+#define OCF_HAL_TONE_STOP 0x0016
+
+#define OCF_UPDATER_START 0x0020
+#define OCF_UPDATER_REBOOT 0x0021
+
+#define OCF_GET_UPDATER_VERSION 0x0022
+typedef __packed struct _get_updater_version_rp{
+ uint8_t status;
+ uint8_t version;
+} PACKED get_updater_version_rp;
+#define GET_UPDATER_VERSION_RP_SIZE 2
+
+#define OCF_GET_UPDATER_BUFSIZE 0x0023
+typedef __packed struct _get_updater_bufsize_rp{
+ uint8_t status;
+ uint8_t buffer_size;
+} PACKED get_updater_bufsize_rp;
+#define GET_UPDATER_BUFSIZE_RP_SIZE 2
+
+#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024
+
+#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025
+
+#define OCF_UPDATER_ERASE_SECTOR 0x0026
+typedef __packed struct _updater_erase_sector_cp{
+ uint32_t address;
+} PACKED updater_erase_sector_cp;
+#define UPDATER_ERASE_SECTOR_CP_SIZE 4
+
+#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027
+#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6
+typedef __packed struct _updater_prog_data_block_cp{
+ uint32_t address;
+ uint16_t data_len;
+ uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE];
+} PACKED updater_prog_data_block_cp;
+
+#define OCF_UPDATER_READ_DATA_BLOCK 0x0028
+typedef __packed struct _updater_read_data_block_cp{
+ uint32_t address;
+ uint16_t data_len;
+} PACKED updater_read_data_block_cp;
+#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6
+typedef __packed struct _updater_read_data_block_rp{
+ uint8_t status;
+ uint8_t data[VARIABLE_SIZE];
+} PACKED updater_read_data_block_rp;
+#define GET_UPDATER_BUFSIZE_RP_SIZE 2
+
+#define OCF_UPDATER_CALC_CRC 0x0029
+typedef __packed struct _updater_calc_crc_cp{
+ uint32_t address;
+ uint8_t num_sectors;
+} PACKED updater_calc_crc_cp;
+#define UPDATER_CALC_CRC_CP_SIZE 5
+typedef __packed struct _updater_calc_crc_rp{
+ uint8_t status;
+ uint32_t crc;
+} PACKED updater_calc_crc_rp;
+#define UPDATER_CALC_CRC_RP_SIZE 5
+
+#define OCF_UPDATER_HW_VERSION 0x002A
+typedef __packed struct _updater_hw_version_rp{
+ uint8_t status;
+ uint8_t version;
+} PACKED updater_hw_version_rp;
+#define UPDATER_HW_VERSION_RP_SIZE 2
+
+#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081
+
+#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082
+
+#define OCF_GAP_SET_DISCOVERABLE 0x0083
+
+#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084
+typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{
+ uint8_t own_bdaddr_type;
+ uint8_t directed_adv_type;
+ uint8_t direct_bdaddr_type;
+ tBDAddr direct_bdaddr;
+} PACKED gap_set_direct_conectable_cp_IDB05A1;
+
+typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{
+ uint8_t own_bdaddr_type;
+ uint8_t direct_bdaddr_type;
+ tBDAddr direct_bdaddr;
+} PACKED gap_set_direct_conectable_cp_IDB04A1;
+#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8
+
+#define OCF_GAP_SET_IO_CAPABILITY 0x0085
+typedef __packed struct _gap_set_io_capability_cp{
+ uint8_t io_capability;
+} PACKED gap_set_io_capability_cp;
+#define GAP_SET_IO_CAPABILITY_CP_SIZE 1
+
+#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086
+typedef __packed struct _gap_set_auth_requirement_cp{
+ uint8_t mitm_mode;
+ uint8_t oob_enable;
+ uint8_t oob_data[16];
+ uint8_t min_encryption_key_size;
+ uint8_t max_encryption_key_size;
+ uint8_t use_fixed_pin;
+ uint32_t fixed_pin;
+ uint8_t bonding_mode;
+} PACKED gap_set_auth_requirement_cp;
+#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26
+
+#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087
+typedef __packed struct _gap_set_author_requirement_cp{
+ uint16_t conn_handle;
+ uint8_t authorization_enable;
+} PACKED gap_set_author_requirement_cp;
+#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3
+
+#define OCF_GAP_PASSKEY_RESPONSE 0x0088
+typedef __packed struct _gap_passkey_response_cp{
+ uint16_t conn_handle;
+ uint32_t passkey;
+} PACKED gap_passkey_response_cp;
+#define GAP_PASSKEY_RESPONSE_CP_SIZE 6
+
+#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089
+typedef __packed struct _gap_authorization_response_cp{
+ uint16_t conn_handle;
+ uint8_t authorize;
+} PACKED gap_authorization_response_cp;
+#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3
+
+#define OCF_GAP_INIT 0x008A
+typedef __packed struct _gap_init_cp_IDB05A1{
+ uint8_t role;
+ uint8_t privacy_enabled;
+ uint8_t device_name_char_len;
+} PACKED gap_init_cp_IDB05A1;
+#define GAP_INIT_CP_SIZE_IDB05A1 3
+
+typedef __packed struct _gap_init_cp_IDB04A1{
+ uint8_t role;
+} PACKED gap_init_cp_IDB04A1;
+#define GAP_INIT_CP_SIZE_IDB04A1 1
+typedef __packed struct _gap_init_rp{
+ uint8_t status;
+ uint16_t service_handle;
+ uint16_t dev_name_char_handle;
+ uint16_t appearance_char_handle;
+} PACKED gap_init_rp;
+#define GAP_INIT_RP_SIZE 7
+
+#define OCF_GAP_SET_NON_CONNECTABLE 0x008B
+typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{
+ uint8_t advertising_event_type;
+ uint8_t own_address_type;
+#endif
+} PACKED gap_set_non_connectable_cp_IDB05A1;
+
+typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{
+ uint8_t advertising_event_type;
+} PACKED gap_set_non_connectable_cp_IDB04A1;
+
+#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C
+typedef __packed struct _gap_set_undirected_connectable_cp{
+ uint8_t adv_filter_policy;
+ uint8_t own_addr_type;
+} PACKED gap_set_undirected_connectable_cp;
+#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2
+
+#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D
+typedef __packed struct _gap_slave_security_request_cp{
+ uint16_t conn_handle;
+ uint8_t bonding;
+ uint8_t mitm_protection;
+} PACKED gap_slave_security_request_cp;
+#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4
+
+#define OCF_GAP_UPDATE_ADV_DATA 0x008E
+
+#define OCF_GAP_DELETE_AD_TYPE 0x008F
+typedef __packed struct _gap_delete_ad_type_cp{
+ uint8_t ad_type;
+} PACKED gap_delete_ad_type_cp;
+#define GAP_DELETE_AD_TYPE_CP_SIZE 1
+
+#define OCF_GAP_GET_SECURITY_LEVEL 0x0090
+typedef __packed struct _gap_get_security_level_rp{
+ uint8_t status;
+ uint8_t mitm_protection;
+ uint8_t bonding;
+ uint8_t oob_data;
+ uint8_t passkey_required;
+} PACKED gap_get_security_level_rp;
+#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5
+
+#define OCF_GAP_SET_EVT_MASK 0x0091
+typedef __packed struct _gap_set_evt_mask_cp{
+ uint16_t evt_mask;
+} PACKED gap_set_evt_mask_cp;
+#define GAP_SET_EVT_MASK_CP_SIZE 2
+
+#define OCF_GAP_CONFIGURE_WHITELIST 0x0092
+
+#define OCF_GAP_TERMINATE 0x0093
+typedef __packed struct _gap_terminate_cp{
+ uint16_t handle;
+ uint8_t reason;
+} PACKED gap_terminate_cp;
+#define GAP_TERMINATE_CP_SIZE 3
+
+#define OCF_GAP_CLEAR_SECURITY_DB 0x0094
+
+#define OCF_GAP_ALLOW_REBOND_DB 0x0095
+
+typedef __packed struct _gap_allow_rebond_cp_IDB05A1{
+ uint16_t conn_handle;
+} PACKED gap_allow_rebond_cp_IDB05A1;
+
+#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096
+typedef __packed struct _gap_start_limited_discovery_proc_cp{
+ uint16_t scanInterval;
+ uint16_t scanWindow;
+ uint8_t own_address_type;
+ uint8_t filterDuplicates;
+} PACKED gap_start_limited_discovery_proc_cp;
+#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6
+
+#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097
+typedef __packed struct _gap_start_general_discovery_proc_cp{
+ uint16_t scanInterval;
+ uint16_t scanWindow;
+ uint8_t own_address_type;
+ uint8_t filterDuplicates;
+} PACKED gap_start_general_discovery_proc_cp;
+#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6
+
+#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098
+typedef __packed struct _gap_start_name_discovery_proc_cp{
+ uint16_t scanInterval;
+ uint16_t scanWindow;
+ uint8_t peer_bdaddr_type;
+ tBDAddr peer_bdaddr;
+ uint8_t own_bdaddr_type;
+ uint16_t conn_min_interval;
+ uint16_t conn_max_interval;
+ uint16_t conn_latency;
+ uint16_t supervision_timeout;
+ uint16_t min_conn_length;
+ uint16_t max_conn_length;
+} PACKED gap_start_name_discovery_proc_cp;
+#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24
+
+#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099
+
+#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A
+typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{
+ uint8_t scan_type;
+ uint16_t scan_interval;
+ uint16_t scan_window;
+ uint8_t own_address_type;
+ uint8_t filter_duplicates;
+} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1;
+
+typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{
+ uint8_t scan_type;
+ uint16_t scan_interval;
+ uint16_t scan_window;
+ uint8_t own_address_type;
+ uint8_t filter_duplicates;
+ uint8_t use_reconn_addr;
+ tBDAddr reconn_addr;
+} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1;
+
+#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B
+#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8
+typedef __packed struct _gap_start_selective_conn_establish_proc_cp{
+ uint8_t scan_type;
+ uint16_t scan_interval;
+ uint16_t scan_window;
+ uint8_t own_address_type;
+ uint8_t filter_duplicates;
+ uint8_t num_whitelist_entries;
+ uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE];
+} PACKED gap_start_selective_conn_establish_proc_cp;
+
+#define OCF_GAP_CREATE_CONNECTION 0x009C
+typedef __packed struct _gap_create_connection_cp{
+ uint16_t scanInterval;
+ uint16_t scanWindow;
+ uint8_t peer_bdaddr_type;
+ tBDAddr peer_bdaddr;
+ uint8_t own_bdaddr_type;
+ uint16_t conn_min_interval;
+ uint16_t conn_max_interval;
+ uint16_t conn_latency;
+ uint16_t supervision_timeout;
+ uint16_t min_conn_length;
+ uint16_t max_conn_length;
+} PACKED gap_create_connection_cp;
+#define GAP_CREATE_CONNECTION_CP_SIZE 24
+
+#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D
+
+#define OCF_GAP_START_CONNECTION_UPDATE 0x009E
+typedef __packed struct _gap_start_connection_update_cp{
+ uint16_t conn_handle;
+ uint16_t conn_min_interval;
+ uint16_t conn_max_interval;
+ uint16_t conn_latency;
+ uint16_t supervision_timeout;
+ uint16_t min_conn_length;
+ uint16_t max_conn_length;
+} PACKED gap_start_connection_update_cp;
+#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14
+
+#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F
+typedef __packed struct _gap_send_pairing_request_cp{
+ uint16_t conn_handle;
+ uint8_t force_rebond;
+} PACKED gap_send_pairing_request_cp;
+#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3
+
+#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0
+typedef __packed struct _gap_resolve_private_address_cp{
+ tBDAddr address;
+} PACKED gap_resolve_private_address_cp;
+#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6
+typedef __packed struct _gap_resolve_private_address_rp{
+ uint8_t status;
+ tBDAddr address;
+} PACKED gap_resolve_private_address_rp;
+
+#define OCF_GAP_SET_BROADCAST_MODE 0x00A1
+#define GAP_SET_BROADCAST_MODE_CP_SIZE 6
+typedef __packed struct _gap_set_broadcast_mode_cp{
+ uint16_t adv_interv_min;
+ uint16_t adv_interv_max;
+ uint8_t adv_type;
+ uint8_t own_addr_type;
+ uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE];
+} PACKED gap_set_broadcast_mode_cp;
+
+#define OCF_GAP_START_OBSERVATION_PROC 0x00A2
+typedef __packed struct _gap_start_observation_proc_cp{
+ uint16_t scan_interval;
+ uint16_t scan_window;
+ uint8_t scan_type;
+ uint8_t own_address_type;
+ uint8_t filter_duplicates;
+} PACKED gap_start_observation_proc_cp;
+
+#define OCF_GAP_GET_BONDED_DEVICES 0x00A3
+typedef __packed struct _gap_get_bonded_devices_rp{
+ uint8_t status;
+ uint8_t num_addr;
+ uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1];
+} PACKED gap_get_bonded_devices_rp;
+
+#define OCF_GAP_IS_DEVICE_BONDED 0x00A4
+typedef __packed struct _gap_is_device_bonded_cp{
+ uint8_t peer_address_type;
+ tBDAddr peer_address;
+} PACKED gap_is_device_bonded_cp;
+
+
+#define OCF_GATT_INIT 0x0101
+
+#define OCF_GATT_ADD_SERV 0x0102
+typedef __packed struct _gatt_add_serv_rp{
+ uint8_t status;
+ uint16_t handle;
+} PACKED gatt_add_serv_rp;
+#define GATT_ADD_SERV_RP_SIZE 3
+
+#define OCF_GATT_INCLUDE_SERV 0x0103
+typedef __packed struct _gatt_include_serv_rp{
+ uint8_t status;
+ uint16_t handle;
+} PACKED gatt_include_serv_rp;
+#define GATT_INCLUDE_SERV_RP_SIZE 3
+
+#define OCF_GATT_ADD_CHAR 0x0104
+typedef __packed struct _gatt_add_char_rp{
+ uint8_t status;
+ uint16_t handle;
+} PACKED gatt_add_char_rp;
+#define GATT_ADD_CHAR_RP_SIZE 3
+
+#define OCF_GATT_ADD_CHAR_DESC 0x0105
+typedef __packed struct _gatt_add_char_desc_rp{
+ uint8_t status;
+ uint16_t handle;
+} PACKED gatt_add_char_desc_rp;
+#define GATT_ADD_CHAR_DESC_RP_SIZE 3
+
+#define OCF_GATT_UPD_CHAR_VAL 0x0106
+
+#define OCF_GATT_DEL_CHAR 0x0107
+typedef __packed struct _gatt_del_char_cp{
+ uint16_t service_handle;
+ uint16_t char_handle;
+} PACKED gatt_del_char_cp;
+#define GATT_DEL_CHAR_CP_SIZE 4
+
+#define OCF_GATT_DEL_SERV 0x0108
+typedef __packed struct _gatt_del_serv_cp{
+ uint16_t service_handle;
+} PACKED gatt_del_serv_cp;
+#define GATT_DEL_SERV_CP_SIZE 2
+
+#define OCF_GATT_DEL_INC_SERV 0x0109
+typedef __packed struct _gatt_del_inc_serv_cp{
+ uint16_t service_handle;
+ uint16_t inc_serv_handle;
+} PACKED gatt_del_inc_serv_cp;
+#define GATT_DEL_INC_SERV_CP_SIZE 4
+
+#define OCF_GATT_SET_EVT_MASK 0x010A
+typedef __packed struct _gatt_set_evt_mask_cp{
+ uint32_t evt_mask;
+} PACKED gatt_set_evt_mask_cp;
+#define GATT_SET_EVT_MASK_CP_SIZE 4
+
+#define OCF_GATT_EXCHANGE_CONFIG 0x010B
+typedef __packed struct _gatt_exchange_config_cp{
+ uint16_t conn_handle;
+} PACKED gatt_exchange_config_cp;
+#define GATT_EXCHANGE_CONFIG_CP_SIZE 2
+
+#define OCF_ATT_FIND_INFO_REQ 0x010C
+typedef __packed struct _att_find_info_req_cp{
+ uint16_t conn_handle;
+ uint16_t start_handle;
+ uint16_t end_handle;
+} PACKED att_find_info_req_cp;
+#define ATT_FIND_INFO_REQ_CP_SIZE 6
+
+#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D
+#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9
+typedef __packed struct _att_find_by_type_value_req_cp{
+ uint16_t conn_handle;
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint8_t uuid[2];
+ uint8_t attr_val_len;
+ uint8_t attr_val[ATT_MTU - 7];
+} PACKED att_find_by_type_value_req_cp;
+
+#define OCF_ATT_READ_BY_TYPE_REQ 0x010E
+#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID
+typedef __packed struct _att_read_by_type_req_cp{
+ uint16_t conn_handle;
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint8_t uuid_type;
+ uint8_t uuid[16];
+} PACKED att_read_by_type_req_cp;
+
+#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F
+#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID
+typedef __packed struct _att_read_by_group_type_req_cp{
+ uint16_t conn_handle;
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint8_t uuid_type;
+ uint8_t uuid[16];
+} PACKED att_read_by_group_type_req_cp;
+
+#define OCF_ATT_PREPARE_WRITE_REQ 0x0110
+#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val
+typedef __packed struct _att_prepare_write_req_cp{
+ uint16_t conn_handle;
+ uint16_t attr_handle;
+ uint16_t value_offset;
+ uint8_t attr_val_len;
+ uint8_t attr_val[ATT_MTU-5];
+} PACKED att_prepare_write_req_cp;
+
+#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111
+typedef __packed struct _att_execute_write_req_cp{
+ uint16_t conn_handle;
+ uint8_t execute;
+} PACKED att_execute_write_req_cp;
+#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3
+
+#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112
+typedef __packed struct _gatt_disc_all_prim_serivces_cp{
+ uint16_t conn_handle;
+} PACKED gatt_disc_all_prim_services_cp;
+#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2
+
+#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113
+typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{
+ uint16_t conn_handle;
+ uint8_t uuid_type;
+ uint8_t uuid[16];
+} PACKED gatt_disc_prim_service_by_uuid_cp;
+#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid
+
+#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114
+typedef __packed struct _gatt_disc_find_included_services_cp{
+ uint16_t conn_handle;
+ uint16_t start_handle;
+ uint16_t end_handle;
+} PACKED gatt_find_included_services_cp;
+#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6
+
+#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115
+typedef __packed struct _gatt_disc_all_charac_of_serv_cp{
+ uint16_t conn_handle;
+ uint16_t start_attr_handle;
+ uint16_t end_attr_handle;
+} PACKED gatt_disc_all_charac_of_serv_cp;
+#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6
+
+#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116
+
+#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117
+typedef __packed struct _gatt_disc_all_charac_descriptors_cp{
+ uint16_t conn_handle;
+ uint16_t char_val_handle;
+ uint16_t char_end_handle;
+} PACKED gatt_disc_all_charac_descriptors_cp;
+#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6
+
+#define OCF_GATT_READ_CHARAC_VAL 0x0118
+typedef __packed struct _gatt_read_charac_val_cp{
+ uint16_t conn_handle;
+ uint16_t attr_handle;
+} PACKED gatt_read_charac_val_cp;
+#define GATT_READ_CHARAC_VAL_CP_SIZE 4
+
+#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109
+typedef __packed struct _gatt_read_using_charac_uuid_cp{
+ uint16_t conn_handle;
+ uint16_t start_handle;
+ uint16_t end_handle;
+ uint8_t uuid_type;
+ uint8_t uuid[16];
+} PACKED gatt_read_using_charac_uuid_cp;
+#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID
+
+#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A
+typedef __packed struct _gatt_read_long_charac_val_cp{
+ uint16_t conn_handle;
+ uint16_t attr_handle;
+ uint16_t val_offset;
+} PACKED gatt_read_long_charac_val_cp;
+#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6
+
+#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B
+#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles
+typedef __packed struct _gatt_read_multiple_charac_val_cp{
+ uint16_t conn_handle;
+ uint8_t num_handles;
+ uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE];
+} PACKED gatt_read_multiple_charac_val_cp;
+
+#define OCF_GATT_WRITE_CHAR_VALUE 0x011C
+
+#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D
+#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles
+typedef __packed struct _gatt_write_long_charac_val_cp{
+ uint16_t conn_handle;
+ uint16_t attr_handle;
+ uint16_t val_offset;
+ uint8_t val_len;
+ uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE];
+} PACKED gatt_write_long_charac_val_cp;
+
+#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E
+#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles
+typedef __packed struct _gatt_write_charac_reliable_cp{
+ uint16_t conn_handle;
+ uint16_t attr_handle;
+ uint16_t val_offset;
+ uint8_t val_len;
+ uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE];
+} PACKED gatt_write_charac_reliable_cp;
+
+#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F
+#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles
+typedef __packed struct _gatt_write_long_charac_desc_cp{
+ uint16_t conn_handle;
+ uint16_t attr_handle;
+ uint16_t val_offset;
+ uint8_t val_len;
+ uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE];
+} PACKED gatt_write_long_charac_desc_cp;
+
+#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120
+typedef __packed struct _gatt_read_long_charac_desc_cp{
+ uint16_t conn_handle;
+ uint16_t attr_handle;
+ uint16_t val_offset;
+} PACKED gatt_read_long_charac_desc_cp;
+#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6
+
+#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121
+
+#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122
+typedef __packed struct _gatt_read_charac_desc_cp{
+ uint16_t conn_handle;
+ uint16_t attr_handle;
+} PACKED gatt_read_charac_desc_cp;
+#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4
+
+#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123
+#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val
+typedef __packed struct _gatt_write_without_resp_cp{
+ uint16_t conn_handle;
+ uint16_t attr_handle;
+ uint8_t val_len;
+ uint8_t attr_val[ATT_MTU - 3];
+} PACKED gatt_write_without_resp_cp;
+
+#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124
+#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val
+typedef __packed struct _gatt_signed_write_without_resp_cp{
+ uint16_t conn_handle;
+ uint16_t attr_handle;
+ uint8_t val_len;
+ uint8_t attr_val[ATT_MTU - 13];
+} PACKED gatt_signed_write_without_resp_cp;
+
+#define OCF_GATT_CONFIRM_INDICATION 0x0125
+typedef __packed struct _gatt_confirm_indication_cp{
+ uint16_t conn_handle;
+} PACKED gatt_confirm_indication_cp;
+#define GATT_CONFIRM_INDICATION_CP_SIZE 2
+
+#define OCF_GATT_WRITE_RESPONSE 0x0126
+
+#define OCF_GATT_ALLOW_READ 0x0127
+typedef __packed struct _gatt_allow_read_cp{
+ uint16_t conn_handle;
+} PACKED gatt_allow_read_cp;
+#define GATT_ALLOW_READ_CP_SIZE 2
+
+#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128
+typedef __packed struct _gatt_set_security_permission_cp{
+ uint16_t service_handle;
+ uint16_t attr_handle;
+ uint8_t security_permission;
+} PACKED gatt_set_security_permission_cp;
+#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5
+
+#define OCF_GATT_SET_DESC_VAL 0x0129
+
+#define OCF_GATT_READ_HANDLE_VALUE 0x012A
+typedef __packed struct _gatt_read_handle_val_cp{
+ uint16_t attr_handle;
+} PACKED gatt_read_handle_val_cp;
+#define GATT_READ_HANDLE_VALUE_RP_SIZE 3
+typedef __packed struct _gatt_read_handle_val_rp{
+ uint8_t status;
+ uint16_t value_len;
+ uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE];
+} PACKED gatt_read_handle_val_rp;
+
+#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B
+typedef __packed struct _gatt_read_handle_val_offset_cp{
+ uint16_t attr_handle;
+ uint8_t offset;
+} PACKED gatt_read_handle_val_offset_cp;
+#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2
+typedef __packed struct _gatt_read_handle_val_offset_rp{
+ uint8_t status;
+ uint8_t value_len;
+ uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE];
+} PACKED gatt_read_handle_val_offset_rp;
+
+#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181
+typedef __packed struct _l2cap_conn_param_update_req_cp{
+ uint16_t conn_handle;
+ uint16_t interval_min;
+ uint16_t interval_max;
+ uint16_t slave_latency;
+ uint16_t timeout_multiplier;
+} PACKED l2cap_conn_param_update_req_cp;
+#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10
+
+#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182
+typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{
+ uint16_t conn_handle;
+ uint16_t interval_min;
+ uint16_t interval_max;
+ uint16_t slave_latency;
+ uint16_t timeout_multiplier;
+ uint16_t min_ce_length;
+ uint16_t max_ce_length;
+ uint8_t id;
+ uint8_t accept;
+} PACKED l2cap_conn_param_update_resp_cp_IDB05A1;
+
+typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{
+ uint16_t conn_handle;
+ uint16_t interval_min;
+ uint16_t interval_max;
+ uint16_t slave_latency;
+ uint16_t timeout_multiplier;
+ uint8_t id;
+ uint8_t accept;
+} PACKED l2cap_conn_param_update_resp_cp_IDB04A1;
+
+/**
+ * @defgroup BlueNRG_Events BlueNRG events (vendor specific)
+ * @{
+ */
+
+/**
+ * Vendor specific event for BlueNRG.
+ */
+typedef __packed struct _evt_blue_aci{
+ uint16_t ecode; /**< One of the BlueNRG event codes. */
+ uint8_t data[VARIABLE_SIZE];
+} PACKED evt_blue_aci;
+
+
+/**
+ * @}
+ */
+
+#endif /* __BLUENRG_ACI_CONST_H_ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,230 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name : bluenrg_gap.h
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 19-July-2012
+* Description : Header file for BlueNRG's GAP layer.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#ifndef __BNRG_GAP_H__
+#define __BNRG_GAP_H__
+
+#include <ble_link_layer.h>
+
+/**
+ *@addtogroup GAP GAP
+ *@brief API for GAP layer.
+ *@{
+ */
+
+/**
+ * @name GAP UUIDs
+ * @{
+ */
+#define GAP_SERVICE_UUID (0x1800)
+#define DEVICE_NAME_UUID (0x2A00)
+#define APPEARANCE_UUID (0x2A01)
+#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02)
+#define RECONNECTION_ADDR_UUID (0x2A03)
+#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04)
+/**
+ * @}
+ */
+
+/**
+ * @name Characteristic value lengths
+ * @{
+ */
+#define DEVICE_NAME_CHARACTERISTIC_LEN (8)
+#define APPEARANCE_CHARACTERISTIC_LEN (2)
+#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1)
+#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6)
+#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8)
+/**
+ * @}
+ */
+
+/*------------- AD types for adv data and scan response data ----------------*/
+
+/**
+ * @defgroup AD_Types AD Types
+ * @brief AD Types
+ * @{
+ */
+
+/* FLAGS AD type */
+#define AD_TYPE_FLAGS (0x01)
+/* flag bits */
+/**
+ * @anchor Flags_AD_Type_bits
+ * @name Flags AD Type bits
+ * @brief Bits in Flags AD Type
+ * @{
+ */
+#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01)
+#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02)
+#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04)
+#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08)
+#define FLAG_BIT_LE_BR_EDR_HOST (0x10)
+/**
+ * @}
+ */
+
+/**
+ * @name Service UUID AD types
+ * @{
+ */
+#define AD_TYPE_16_BIT_SERV_UUID (0x02)
+#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03)
+#define AD_TYPE_32_BIT_SERV_UUID (0x04)
+#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05)
+#define AD_TYPE_128_BIT_SERV_UUID (0x06)
+#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07)
+/**
+ * @}
+ */
+
+/* LOCAL NAME AD types */
+/**
+ * @name Local name AD types
+ * @{
+ */
+#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08)
+#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09)
+/**
+ * @}
+ */
+
+/* TX power level AD type*/
+#define AD_TYPE_TX_POWER_LEVEL (0x0A)
+
+/* Class of device */
+#define AD_TYPE_CLASS_OF_DEVICE (0x0D)
+
+/* security manager TK value AD type */
+#define AD_TYPE_SEC_MGR_TK_VALUE (0x10)
+
+/* security manager OOB flags */
+#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11)
+
+/* slave connection interval AD type */
+#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12)
+
+/* service solicitation UUID list Ad types*/
+/**
+ * @name Service solicitation UUID list AD types
+ * @{
+ */
+#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14)
+#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F)
+#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15)
+/**
+ * @}
+ */
+
+/* service data AD type */
+#define AD_TYPE_SERVICE_DATA (0x16)
+
+/* manufaturer specific data AD type */
+#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF)
+
+/* appearance AD type */
+#define AD_TYPE_APPEARANCE (0x19)
+
+/* advertising interval AD type */
+#define AD_TYPE_ADVERTISING_INTERVAL (0x1A)
+
+/**
+ * @}
+ */
+
+#define MAX_ADV_DATA_LEN (31)
+
+#define DEVICE_NAME_LEN (7)
+#define BD_ADDR_SIZE (6)
+
+/**
+ * @name Privacy flag values
+ * @{
+ */
+#define PRIVACY_ENABLED (0x01)
+#define PRIVACY_DISABLED (0x00)
+/**
+ * @}
+ */
+
+/**
+ * @name Intervals
+ * Intervals in terms of 625 micro sec
+ * @{
+ */
+#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/
+#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/
+#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/
+#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/
+#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/
+#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/
+#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/
+#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/
+/**
+ * @}
+ */
+
+/**
+ * @name Timeout values
+ * @{
+ */
+#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */
+#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */
+/**
+ * @}
+ */
+
+/**
+ * @anchor gap_roles
+ * @name GAP Roles
+ * @{
+*/
+#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01)
+#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02)
+#define GAP_CENTRAL_ROLE_IDB05A1 (0x04)
+#define GAP_OBSERVER_ROLE_IDB05A1 (0x08)
+
+#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01)
+#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02)
+#define GAP_CENTRAL_ROLE_IDB04A1 (0x03)
+#define GAP_OBSERVER_ROLE_IDB04A1 (0x04)
+/**
+ * @}
+ */
+
+/**
+ * @anchor gap_procedure_codes
+ * @name GAP procedure codes
+ * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event
+ * and aci_gap_terminate_gap_procedure() command.
+ * @{
+ */
+#define GAP_LIMITED_DISCOVERY_PROC (0x01)
+#define GAP_GENERAL_DISCOVERY_PROC (0x02)
+#define GAP_NAME_DISCOVERY_PROC (0x04)
+#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08)
+#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10)
+#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20)
+#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40)
+#define GAP_OBSERVATION_PROC_IDB05A1 (0x80)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* __BNRG_GAP_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap_aci.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap_aci.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,1218 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name : bluenrg_gap_aci.h
+* Author : AMS - AAS
+* Version : V1.0.0
+* Date : 26-Jun-2014
+* Description : Header file with GAP commands for BlueNRG FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_GAP_ACI_H__
+#define __BLUENRG_GAP_ACI_H__
+
+/**
+ *@addtogroup GAP GAP
+ *@brief GAP layer.
+ *@{
+ */
+
+/**
+ *@defgroup GAP_Functions GAP functions
+ *@brief API for GAP layer.
+ *@{
+ */
+
+/**
+ * @brief Initialize the GAP layer.
+ * @note Register the GAP service with the GATT.
+ * All the standard GAP characteristics will also be added:
+ * @li Device Name
+ * @li Appearance
+ * @li Peripheral Preferred Connection Parameters (peripheral role only)
+ * @code
+
+ tBleStatus ret;
+ uint16_t service_handle, dev_name_char_handle, appearance_char_handle;
+
+ ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle);
+ if(ret){
+ PRINTF("GAP_Init failed.\n");
+ reboot();
+ }
+ const char *name = "BlueNRG";
+ ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name);
+ if(ret){
+ PRINTF("aci_gatt_update_char_value failed.\n");
+ }
+ * @endcode
+ * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles".
+ * @param privacy_enabled Enable (1) or disable (0) privacy.
+ * @param device_name_char_len Length of the device name characteristic
+ * @param[out] service_handle Handle of the GAP service.
+ * @param[out] dev_name_char_handle Device Name Characteristic handle
+ * @param[out] appearance_char_handle Appearance Characteristic handle
+ * @retval tBleStatus Value indicating success or error code.
+ */
+tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled,
+ uint8_t device_name_char_len,
+ uint16_t* service_handle,
+ uint16_t* dev_name_char_handle,
+ uint16_t* appearance_char_handle);
+/**
+ * @brief Initialize the GAP layer.
+ * @note Register the GAP service with the GATT.
+ * All the standard GAP characteristics will also be added:
+ * @li Device Name
+ * @li Appearance
+ * @li Peripheral Privacy Flag (peripheral role only)
+ * @li Reconnection Address (peripheral role only)
+ * @li Peripheral Preferred Connection Parameters (peripheral role only)
+ * @code
+
+ tBleStatus ret;
+ uint16_t service_handle, dev_name_char_handle, appearance_char_handle;
+
+ ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle);
+ if(ret){
+ PRINTF("GAP_Init failed.\n");
+ reboot();
+ }
+ const char *name = "BlueNRG";
+ ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name);
+ if(ret){
+ PRINTF("aci_gatt_update_char_value failed.\n");
+ }
+ * @endcode
+ * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles".
+ * @param[out] service_handle Handle of the GAP service.
+ * @param[out] dev_name_char_handle Device Name Characteristic handle
+ * @param[out] appearance_char_handle Appearance Characteristic handle
+ * @retval tBleStatus Value indicating success or error code.
+ */
+tBleStatus aci_gap_init_IDB04A1(uint8_t role,
+ uint16_t* service_handle,
+ uint16_t* dev_name_char_handle,
+ uint16_t* appearance_char_handle);
+
+/**
+ * @brief Set the Device in non-discoverable mode.
+ * @note This command will disable the LL advertising.
+ * @retval tBleStatus Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_non_discoverable(void);
+
+/**
+ * @brief Put the device in limited discoverable mode
+ * (as defined in GAP specification volume 3, section 9.2.3).
+ * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds.
+ * The advertising can be disabled at any time by issuing
+ * aci_gap_set_non_discoverable() command.
+ * The AdvIntervMin and AdvIntervMax parameters are optional. If both
+ * are set to 0, the GAP will use default values (250 ms and 500 ms respectively).
+ * Host can set the Local Name, a Service UUID list and the Slave Connection
+ * Minimum and Maximum. If provided, these data will be inserted into the
+ * advertising packet payload as AD data. These parameters are optional
+ * in this command. These values can be also set using aci_gap_update_adv_data()
+ * separately.
+ * The total size of data in advertising packet cannot exceed 31 bytes.
+ * With this command, the BLE Stack will also add automatically the following
+ * standard AD types:
+ * @li AD Flags
+ * @li TX Power Level
+ *
+ * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates
+ * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event.
+ *
+ * Example:
+ * @code
+ *
+ * #define ADV_INTERVAL_MIN_MS 100
+ * #define ADV_INTERVAL_MAX_MS 200
+ *
+ * tBleStatus ret;
+ *
+ * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'};
+ * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12};
+ *
+ * ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625,
+ * (ADV_INTERVAL_MAX_MS*1000)/0.625,
+ * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE,
+ * sizeof(local_name), local_name,
+ * sizeof(serviceUUIDList), serviceUUIDList,
+ * 0, 0);
+ * @endcode
+ *
+ * @param AdvType One of the advertising types:
+ * @arg @ref ADV_IND Connectable undirected advertising
+ * @arg @ref ADV_SCAN_IND Scannable undirected advertising
+ * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising
+ * @param AdvIntervMin Minimum advertising interval.
+ * Range: 0x0020 to 0x4000
+ * Default: 250 ms
+ * Time = N * 0.625 msec
+ * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND).
+ * @param AdvIntervMax Maximum advertising interval.
+ * Range: 0x0020 to 0x4000
+ * Default: 500 ms
+ * Time = N * 0.625 msec
+ * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND).
+ * @param OwnAddrType Type of our address used during advertising
+ * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR).
+ * @param AdvFilterPolicy Filter policy:
+ * @arg NO_WHITE_LIST_USE
+ * @arg WHITE_LIST_FOR_ONLY_SCAN
+ * @arg WHITE_LIST_FOR_ONLY_CONN
+ * @arg WHITE_LIST_FOR_ALL
+ * @param LocalNameLen Length of LocalName array.
+ * @param LocalName Array containing the Local Name AD data. First byte is the AD type:
+ * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME.
+ * @param ServiceUUIDLen Length of ServiceUUIDList array.
+ * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3,
+ * Section 11.1.1 of GAP Specification. First byte is the AD Type.
+ * @arg @ref AD_TYPE_16_BIT_SERV_UUID
+ * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST
+ * @arg @ref AD_TYPE_128_BIT_SERV_UUID
+ * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST
+ * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral.
+ * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000,
+ * Slave Connection Interval Range AD structure will be added in advertising
+ * data.
+ * Connection interval is defined in the following manner:
+ * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms
+ * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80
+ * Value of 0xFFFF indicates no specific minimum.
+ * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral.
+ * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000,
+ * Slave Connection Interval Range AD structure will be added in advertising
+ * data.
+ * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms
+ * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80
+ * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min.
+ * Value of 0xFFFF indicates no specific maximum.
+ *
+ * @retval tBleStatus Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax,
+ uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen,
+ const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList,
+ uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax);
+/**
+ * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4).
+ * @note The device will be discoverable until the Host issue 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 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.
+ * The total size of data in advertising packet cannot exceed 31 bytes.
+ * With this command, the BLE Stack will also add automatically the following standard AD types:
+ * @li AD Flags
+ * @li TX Power Level
+ *
+ * Usage example:
+ *
+ * @code
+ *
+ * #define ADV_INTERVAL_MIN_MS 800
+ * #define ADV_INTERVAL_MAX_MS 900
+ * #define CONN_INTERVAL_MIN_MS 100
+ * #define CONN_INTERVAL_MAX_MS 300
+ *
+ * tBleStatus ret;
+ *
+ * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'};
+ * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12};
+ *
+ * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625,
+ * (ADV_INTERVAL_MAX_MS*1000)/625,
+ * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE,
+ * sizeof(local_name), local_name,
+ * 0, NULL,
+ * (CONN_INTERVAL_MIN_MS*1000)/1250,
+ * (CONN_INTERVAL_MAX_MS*1000)/1250);
+ * @endcode
+ *
+ * @param AdvType One of the advertising types:
+ * @arg @ref ADV_IND Connectable undirected advertising
+ * @arg @ref ADV_SCAN_IND Scannable undirected advertising
+ * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising
+ * @param AdvIntervMin Minimum advertising interval.
+ * Range: 0x0020 to 0x4000
+ * Default: 1.28 s
+ * Time = N * 0.625 msec
+ * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND).
+ * @param AdvIntervMax Maximum advertising interval.
+ * Range: 0x0020 to 0x4000
+ * Default: 2.56 s
+ * Time = N * 0.625 msec
+ * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND).
+ * @param OwnAddrType Type of our address used during advertising
+ * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR).
+ * @param AdvFilterPolicy Filter policy:
+ * @arg @ref NO_WHITE_LIST_USE
+ * @arg @ref WHITE_LIST_FOR_ONLY_SCAN
+ * @arg @ref WHITE_LIST_FOR_ONLY_CONN
+ * @arg @ref WHITE_LIST_FOR_ALL
+ * @param LocalNameLen Length of LocalName array.
+ * @param LocalName Array containing the Local Name AD data. First byte is the AD type:
+ * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME.
+ * @param ServiceUUIDLen Length of ServiceUUIDList array.
+ * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3,
+ * Section 11.1.1 of GAP Specification. First byte is the AD Type.
+ * @arg @ref AD_TYPE_16_BIT_SERV_UUID
+ * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST
+ * @arg @ref AD_TYPE_128_BIT_SERV_UUID
+ * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST
+ * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral.
+ * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000,
+ * Slave Connection Interval Range AD structure will be added in advertising
+ * data.
+ * Connection interval is defined in the following manner:
+ * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms
+ * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80
+ * Value of 0xFFFF indicates no specific minimum.
+ * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral.
+ * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000,
+ * Slave Connection Interval Range AD structure will be added in advertising
+ * data.
+ * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms
+ * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80
+ * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min.
+ * Value of 0xFFFF indicates no specific maximum.
+ *
+ * @retval tBleStatus Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax,
+ uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen,
+ const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList,
+ uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax);
+
+/**
+ * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3).
+ * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address
+ * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only
+ * for 1.28 seconds. If no connection is established within this duration, the device enters non
+ * discoverable mode and advertising will have to be again enabled explicitly.
+ * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT
+ * if the connection was not established and 0x00 if the connection was successfully established.
+ *
+ * Usage example:
+ * @code
+ *
+ * tBleStatus ret;
+ *
+ * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02};
+ * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address);
+ * @endcode
+ *
+ *
+ *
+ * @param OwnAddrType Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR).
+ * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV).
+ * @param InitiatorAddrType Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR).
+ * @param InitiatorAddr Initiator's address (Little Endian).
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr);
+/**
+ * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3).
+ * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address
+ * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only
+ * for 1.28 seconds. If no connection is established within this duration, the device enters non
+ * discoverable mode and advertising will have to be again enabled explicitly.
+ * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT
+ * if the connection was not established and 0x00 if the connection was successfully established.
+ *
+ * Usage example:
+ * @code
+ *
+ * tBleStatus ret;
+ *
+ * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02};
+ * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address);
+ * @endcode
+ *
+ *
+ *
+ * @param OwnAddrType Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR).
+ * @param InitiatorAddrType Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR).
+ * @param InitiatorAddr Initiator's address (Little Endian).
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr);
+
+/**
+ * @brief Set the IO capabilities of the device.
+ * @note This command has to be given only when the device is not in a connected state.
+ * @param io_capability One of the allowed codes for IO Capability:
+ * @arg @ref IO_CAP_DISPLAY_ONLY
+ * @arg @ref IO_CAP_DISPLAY_YES_NO
+ * @arg @ref IO_CAP_KEYBOARD_ONLY
+ * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT
+ * @arg @ref IO_CAP_KEYBOARD_DISPLAY
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_io_capability(uint8_t io_capability);
+
+/**
+ * @brief Set the authentication requirements for the device.
+ * @note If the oob_enable is set to 0, oob_data will be ignored.
+ * This command has to be given only when the device is not in a connected state.
+ * @param mitm_mode MITM mode:
+ * @arg @ref MITM_PROTECTION_NOT_REQUIRED
+ * @arg @ref MITM_PROTECTION_REQUIRED
+ * @param oob_enable If OOB data are present or not:
+ * @arg @ref OOB_AUTH_DATA_ABSENT
+ * @arg @ref OOB_AUTH_DATA_PRESENT
+ * @param oob_data Out-Of-Band data
+ * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process
+ * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process
+ * @param use_fixed_pin If application wants to use a fixed pin or not:
+ * @arg @ref USE_FIXED_PIN_FOR_PAIRING
+ * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING
+ * If a fixed pin is not used, it has to be provided by the application with
+ * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event.
+ * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will
+ * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is
+ * accepted.
+ * @param bonding_mode One of the bonding modes:
+ * @arg @ref BONDING
+ * @arg @ref NO_BONDING
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode,
+ uint8_t oob_enable,
+ uint8_t oob_data[16],
+ uint8_t min_encryption_key_size,
+ uint8_t max_encryption_key_size,
+ uint8_t use_fixed_pin,
+ uint32_t fixed_pin,
+ uint8_t bonding_mode);
+ /**
+ * @brief Set the authorization requirements of the device.
+ * @note This command has to be given only when the device is not in a connected state.
+ * @param conn_handle Handle of the connection in case BlueNRG is configured as a master (otherwise it can be also 0).
+ * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required
+ * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables
+ * the authorization requirement in the device and when a remote device
+ * tries to connect to GATT server, @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event
+ * will be sent to the Host.
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable);
+
+/**
+ * @brief Provide the pass key that will be used during pairing.
+ * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event.
+ * @param conn_handle Connection handle
+ * @param passkey Pass key that will be used during the pairing process. Must be a number between
+ * 0 and 999999.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey);
+
+/**
+ * @brief Authorize a device to access attributes.
+ * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST.
+ *
+ * @param conn_handle Connection handle
+ * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection)
+ * @arg @ref CONNECTION_REJECTED : Reject (reject connection)
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize);
+
+/**
+ * @brief Put the device into non-connectable mode.
+ * @param adv_type One of the allowed advertising types:
+ * @arg @ref ADV_SCAN_IND : Scannable undirected advertising
+ * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising
+ * @param own_address_type If Privacy is disabled, then the peripheral address can be
+ * @arg @ref PUBLIC_ADDR.
+ * @arg @ref STATIC_RANDOM_ADDR.
+ * If Privacy is enabled, then the peripheral address can be
+ * @arg @ref RESOLVABLE_PRIVATE_ADDR
+ * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type);
+/**
+ * @brief Put the device into non-connectable mode.
+ * @param adv_type One of the allowed advertising types:
+ * @arg @ref ADV_SCAN_IND : Scannable undirected advertising
+ * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type);
+
+/**
+ * @brief Put the device into undirected connectable mode.
+ * @note If privacy is enabled in the device, a resolvable private address is generated and used
+ * as the advertiser's address. If not, the address of the type specified in own_addr_type
+ * is used for advertising.
+ * @param own_addr_type Type of our address used during advertising:
+ * if BLUENRG (IDB04A1)
+ * @arg @ref PUBLIC_ADDR.
+ * @arg @ref STATIC_RANDOM_ADDR.
+ * else if BLUENRG_MS (IDB05A1)
+ * If Privacy is disabled:
+ * @arg @ref PUBLIC_ADDR.
+ * @arg @ref STATIC_RANDOM_ADDR.
+ * If Privacy is enabled:
+ * @arg @ref RESOLVABLE_PRIVATE_ADDR
+ * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR
+ * @param adv_filter_policy Filter policy:
+ * @arg @ref NO_WHITE_LIST_USE
+ * @arg @ref WHITE_LIST_FOR_ALL
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy);
+
+/**
+ * @brief Send a slave security request to the master.
+ * @note This command has to be issued to notify the master of the security requirements of the slave.
+ * The master may encrypt the link, initiate the pairing procedure, or reject the request.
+ * @param conn_handle Connection handle
+ * @param bonding One of the bonding modes:
+ * @arg @ref BONDING
+ * @arg @ref NO_BONDING
+ * @param mitm_protection If MITM protection is required or not:
+ * @arg @ref MITM_PROTECTION_NOT_REQUIRED
+ * @arg @ref MITM_PROTECTION_REQUIRED
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection);
+
+/**
+ * @brief Update advertising data.
+ * @note This command can be used to update the advertising data for a particular AD type.
+ * If the AD type specified does not exist, then it is added to the advertising data.
+ * If the overall advertising data length is more than 31 octets after the update, then
+ * the command is rejected and the old data is retained.
+ * @param AdvLen Length of AdvData array
+ * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification
+ * (Volume 3, Part C, 11), including data length. It can contain more than one AD type.
+ * Example
+ * @code
+ * tBleStatus ret;
+ * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'};
+ * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12};
+ * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01};
+ *
+ * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE,
+ * 8, local_name, 3, serviceUUIDList, 0, 0);
+ * ret = aci_gap_update_adv_data(5, manuf_data);
+ * @endcode
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData);
+
+/**
+ * @brief Delete an AD Type
+ * @note This command can be used to delete the specified AD type from the advertisement data if
+ * present.
+ * @param ad_type One of the allowed AD types (see @ref AD_Types)
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_delete_ad_type(uint8_t ad_type);
+
+/**
+ * @brief Get the current security settings
+ * @note This command can be used to get the current security settings of the device.
+ * @param mitm_protection @arg 0: Not required
+ * @arg 1: Required
+ * @param bonding @arg 0: No bonding mode
+ * @arg 1: Bonding mode
+ * @param oob_data @arg 0: Data absent
+ * @arg 1: Data present
+ * @param passkey_required @arg 0: Not required
+ * @arg 1: Fixed pin is present which is being used
+ * @arg 2: Passkey required for pairing. An event will be generated
+ * when required.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding,
+ uint8_t* oob_data, uint8_t* passkey_required);
+
+/**
+ * @brief Add addresses of bonded devices into the controller's whitelist.
+ * @note The command will return an error if there are no devices in the database or if it was unable
+ * to add the device into the whitelist.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_configure_whitelist(void);
+
+/**
+ * @brief Terminate a connection.
+ * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected.
+ * @param conn_handle Connection handle
+ * @param reason Reason for requesting disconnection. The error code can be any of ones as specified
+ * for the disconnected command in the HCI specification (See @ref HCI_Error_codes).
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason);
+
+/**
+ * @brief Clear the security database.
+ * @note All the devices in the security database will be removed.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_clear_security_database(void);
+
+/**
+ * @brief Allows the security manager to complete the pairing procedure and re-bond with the master.
+ * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated.
+ * @param conn_handle
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle);
+/**
+ * @brief Allows the security manager to complete the pairing procedure and re-bond with the master.
+ * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_allow_rebond_IDB04A1(void);
+
+/**
+ * @brief Start the limited discovery procedure.
+ * @note The controller is commanded to start active scanning. When this procedure is started,
+ * only the devices in limited discoverable mode are returned to the upper layers.
+ * The procedure is terminated when either the upper layers issue a command to terminate the
+ * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code
+ * set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated
+ * due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with
+ * the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC.
+ * The device found when the procedure is ongoing is returned to the upper layers through the
+ * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) 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.
+ * For a number N, Time = N x 0.625 msec.
+ * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * or equal to Scan_Interval. The scan window should be a number in the range
+ * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * For a number N, Time = N x 0.625 msec.
+ * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR).
+ * @param filterDuplicates Duplicate filtering enabled or not.
+ * @arg 0x00: Do not filter the duplicates
+ * @arg 0x01: Filter duplicates
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
+ uint8_t own_address_type, uint8_t filterDuplicates);
+
+/**
+ * @brief Start the general discovery procedure.
+ * @note The controller is commanded to start active scanning. The procedure is terminated when
+ * either the upper layers issue a command to terminate the procedure by issuing the command
+ * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC
+ * or a timeout happens. When the procedure is terminated due to any of the above reasons,
+ * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to
+ * @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to
+ * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) 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.
+ * For a number N, Time = N x 0.625 msec.
+ * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * or equal to Scan_Interval. The scan window should be a number in the range
+ * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * For a number N, Time = N x 0.625 msec.
+ * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR).
+ * @param filterDuplicates Duplicate filtering enabled or not.
+ * @arg 0x00: Do not filter the duplicates
+ * @arg 0x01: Filter duplicates
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
+ uint8_t own_address_type, uint8_t filterDuplicates);
+
+/**
+ * @brief Start the name discovery procedure.
+ * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter
+ * policy set to ignore whitelist and process connectable advertising packets only for the
+ * specified device. Once a connection is established, GATT procedure is started to read the
+ * device name characteristic. When the read is completed (successfully or unsuccessfully),
+ * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also
+ * contains the name of the device if the device name was read successfully.
+ * @param scanInterval Time interval from when the Controller started its last LE scan until it begins
+ * the subsequent LE scan. The scan interval should be a number in the range
+ * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * For a number N, Time = N x 0.625 msec.
+ * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * or equal to Scan_Interval. The scan window should be a number in the range
+ * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * For a number N, Time = N x 0.625 msec.
+ * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR).
+ * @param peer_bdaddr Address of the peer device with which a connection has to be established.
+ * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR).
+ * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or
+ * equal to Conn_Interval_Max.\n
+ * Range: 0x0006 to 0x0C80\n
+ * Time = N x 1.25 msec\n
+ * Time Range: 7.5 msec to 4 seconds
+ * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or
+ * equal to Conn_Interval_Min.\n
+ * Range: 0x0006 to 0x0C80\n
+ * Time = N x 1.25 msec\n
+ * Time Range: 7.5 msec to 4 seconds
+ * @param conn_latency Slave latency for the connection in number of connection events.\n
+ * Range: 0x0000 to 0x01F4
+ * @param supervision_timeout Supervision timeout for the LE Link.\n
+ * Range: 0x000A to 0x0C80\n
+ * Time = N x 10 msec\n
+ * Time Range: 100 msec to 32 seconds
+ * @param min_conn_length Minimum length of connection needed for the LE connection.\n
+ * Range: 0x0000 - 0xFFFF\n
+ * Time = N x 0.625 msec.
+ * @param max_conn_length Maximum length of connection needed for the LE connection.\n
+ * Range: 0x0000 - 0xFFFF\n
+ * Time = N x 0.625 msec.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow,
+ uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr,
+ uint8_t own_bdaddr_type, uint16_t conn_min_interval,
+ uint16_t conn_max_interval, uint16_t conn_latency,
+ uint16_t supervision_timeout, uint16_t min_conn_length,
+ uint16_t max_conn_length);
+
+/**
+ * @brief Start the auto connection establishment procedure.
+ * @note The devices specified are added to the white list of the controller and a LE_Create_Connection
+ * call will be made to the controller by GAP with the initiator filter policy set to
+ * use whitelist to determine which advertiser to connect to. When a command is issued to
+ * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the
+ * controller by GAP.
+ * The procedure is terminated when either a connection is successfully established with one of
+ * the specified devices in the white list or the procedure is explicitly terminated by issuing
+ * the command aci_gap_terminate_gap_procedure() with the procedure code set to
+ * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with
+ * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC.
+ * @param scanInterval Time interval from when the Controller started its last LE scan until it begins
+ * the subsequent LE scan. The scan interval should be a number in the range
+ * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * For a number N, Time = N x 0.625 msec.
+ * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * or equal to Scan_Interval. The scan window should be a number in the range
+ * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * For a number N, Time = N x 0.625 msec.
+ * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR).
+ * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or
+ * equal to Conn_Interval_Max.\n
+ * Range: 0x0006 to 0x0C80\n
+ * Time = N x 1.25 msec\n
+ * Time Range: 7.5 msec to 4 seconds
+ * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or
+ * equal to Conn_Interval_Min.\n
+ * Range: 0x0006 to 0x0C80\n
+ * Time = N x 1.25 msec\n
+ * Time Range: 7.5 msec to 4 seconds
+ * @param conn_latency Slave latency for the connection in number of connection events.\n
+ * Range: 0x0000 to 0x01F4
+ * @param supervision_timeout Supervision timeout for the LE Link.\n
+ * Range: 0x000A to 0x0C80\n
+ * Time = N x 10 msec\n
+ * Time Range: 100 msec to 32 seconds
+ * @param min_conn_length Minimum length of connection needed for the LE connection.\n
+ * Range: 0x0000 - 0xFFFF\n
+ * Time = N x 0.625 msec.
+ * @param max_conn_length Maximum length of connection needed for the LE connection.\n
+ * Range: 0x0000 - 0xFFFF\n
+ * Time = N x 0.625 msec.
+ * @cond BLUENRG
+ * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address
+ * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n
+ * @param reconn_addr Reconnection address used if use_reconn_addr is 1.
+ * @endcond
+ * @param num_whitelist_entries Number of devices that have to be added to the whitelist.
+ * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The
+ * format of the addr_array should be: address type followed by address.
+ * Example:
+ * @code
+ * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02,
+ * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02};
+ * @endcode
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow,
+ uint8_t own_bdaddr_type, uint16_t conn_min_interval,
+ uint16_t conn_max_interval, uint16_t conn_latency,
+ uint16_t supervision_timeout, uint16_t min_conn_length,
+ uint16_t max_conn_length,
+ uint8_t num_whitelist_entries,
+ const uint8_t *addr_array);
+tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow,
+ uint8_t own_bdaddr_type, uint16_t conn_min_interval,
+ uint16_t conn_max_interval, uint16_t conn_latency,
+ uint16_t supervision_timeout, uint16_t min_conn_length,
+ uint16_t max_conn_length,
+ uint8_t use_reconn_addr,
+ const tBDAddr reconn_addr,
+ uint8_t num_whitelist_entries,
+ const uint8_t *addr_array);
+
+/**
+ * @brief Start a general connection establishment procedure.
+ * @note The host enables scanning in the controller with the scanner filter policy set
+ * to accept all advertising packets and from the scanning results all the devices
+ * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) 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
+ * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to
+ * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a
+ * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to
+ * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC.
+ * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN)
+ * @param scan_interval Time interval from when the Controller started its last LE scan until it begins
+ * the subsequent LE scan. The scan interval should be a number in the range
+ * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * For a number N, Time = N x 0.625 msec.
+ * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * or equal to Scan_Interval. The scan window should be a number in the range
+ * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * For a number N, Time = N x 0.625 msec.
+ * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR).
+ * @param filter_duplicates Duplicate filtering enabled or not.
+ * @arg 0x00: Do not filter the duplicates
+ * @arg 0x01: Filter duplicates
+ * @cond BLUENRG
+ * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address
+ * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n
+ * @param reconn_addr Reconnection address used if use_reconn_addr is 1.
+ * @endcond
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window,
+ uint8_t own_address_type, uint8_t filter_duplicates);
+tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window,
+ uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr);
+
+/**
+ * @brief Start a selective connection establishment procedure.
+ * @note The GAP adds the specified device addresses into white list and enables scanning in
+ * the controller with the scanner filter policy set to accept packets only from
+ * devices in whitelist. All the devices found are sent to the upper layer by the
+ * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) 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.
+ * The procedure is terminated when a connection is established or the upper layer terminates
+ * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure
+ * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC.
+ * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN)
+ * @param scan_interval Time interval from when the Controller started its last LE scan until it begins
+ * the subsequent LE scan. The scan interval should be a number in the range
+ * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * For a number N, Time = N x 0.625 msec.
+ * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * or equal to Scan_Interval. The scan window should be a number in the range
+ * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * For a number N, Time = N x 0.625 msec.
+ * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR).
+ * @param filter_duplicates Duplicate filtering enabled or not.
+ * @arg 0x00: Do not filter the duplicates
+ * @arg 0x01: Filter duplicates
+ * @param num_whitelist_entries Number of devices that have to be added to the whitelist.
+ * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The
+ * format of the addr_array should be: address type followed by address.
+ * Example:
+ * @code
+ * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02,
+ * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02};
+ * @endcode
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window,
+ uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries,
+ const uint8_t *addr_array);
+
+/**
+ * @brief Start the direct connection establishment procedure.
+ * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter
+ * policy set to ignore whitelist and process connectable advertising packets only for the
+ * specified device. The procedure can be terminated explicitly by the upper layer by issuing
+ * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the
+ * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller
+ * by GAP.
+ * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can
+ * be explicitly terminated by the upper layer by issuing the command
+ * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC.
+ * @param scanInterval Time interval from when the Controller started its last LE scan until it begins
+ * the subsequent LE scan. The scan interval should be a number in the range
+ * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * For a number N, Time = N x 0.625 msec.
+ * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than
+ * or equal to Scan_Interval. The scan window should be a number in the range
+ * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
+ * For a number N, Time = N x 0.625 msec.
+ * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR).
+ * @param peer_bdaddr Address of the peer device with which a connection has to be established.
+ * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR).
+ * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or
+ * equal to Conn_Interval_Max.\n
+ * Range: 0x0006 to 0x0C80\n
+ * Time = N x 1.25 msec\n
+ * Time Range: 7.5 msec to 4 seconds
+ * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or
+ * equal to Conn_Interval_Min.\n
+ * Range: 0x0006 to 0x0C80\n
+ * Time = N x 1.25 msec\n
+ * Time Range: 7.5 msec to 4 seconds
+ * @param conn_latency Slave latency for the connection in number of connection events.\n
+ * Range: 0x0000 to 0x01F4
+ * @param supervision_timeout Supervision timeout for the LE Link.\n
+ * Range: 0x000A to 0x0C80\n
+ * Time = N x 10 msec\n
+ * Time Range: 100 msec to 32 seconds
+ * @param min_conn_length Minimum length of connection needed for the LE connection.\n
+ * Range: 0x0000 - 0xFFFF\n
+ * Time = N x 0.625 msec.
+ * @param max_conn_length Maximum length of connection needed for the LE connection.\n
+ * Range: 0x0000 - 0xFFFF\n
+ * Time = N x 0.625 msec.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow,
+ uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr,
+ uint8_t own_bdaddr_type, uint16_t conn_min_interval,
+ uint16_t conn_max_interval, uint16_t conn_latency,
+ uint16_t supervision_timeout, uint16_t min_conn_length,
+ uint16_t max_conn_length);
+
+/**
+ * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is
+ * returned with the procedure code set to the corresponding procedure.
+ * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes").
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code);
+
+/**
+ * @brief Start the connection parameter update procedure.
+ * @note Allowed by the Central to update the connection parameter of the specified connection.
+ * A Link Layer Connection Update procedure is started on the controller.
+ * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to
+ * the upper layer.
+ * @param conn_handle Handle of the connection for which the update procedure has to be started.
+ * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or
+ * equal to Conn_Interval_Max.\n
+ * Range: 0x0006 to 0x0C80\n
+ * Time = N x 1.25 msec\n
+ * Time Range: 7.5 msec to 4 seconds
+ * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or
+ * equal to Conn_Interval_Min.\n
+ * Range: 0x0006 to 0x0C80\n
+ * Time = N x 1.25 msec\n
+ * Time Range: 7.5 msec to 4 seconds
+ * @param conn_latency Slave latency for the connection in number of connection events.\n
+ * Range: 0x0000 to 0x01F4
+ * @param supervision_timeout Supervision timeout for the LE Link.\n
+ * Range: 0x000A to 0x0C80\n
+ * Time = N x 10 msec\n
+ * Time Range: 100 msec to 32 seconds
+ * @param min_conn_length Minimum length of connection needed for the LE connection.\n
+ * Range: 0x0000 - 0xFFFF\n
+ * Time = N x 0.625 msec.
+ * @param max_conn_length Maximum length of connection needed for the LE connection.\n
+ * Range: 0x0000 - 0xFFFF\n
+ * Time = N x 0.625 msec.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval,
+ uint16_t conn_max_interval, uint16_t conn_latency,
+ uint16_t supervision_timeout, uint16_t min_conn_length,
+ uint16_t max_conn_length);
+
+/**
+ * @brief Send a pairing request.
+ * @note Send the SM pairing request to start a pairing process from a Central. The authentication
+ * requirements and IO capabilities should be set before issuing this command using
+ * aci_gap_set_io_capability() and aci_gap_set_auth_requirement().
+ * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed.
+ * @param conn_handle Handle of the connection for which the pairing request has to be sent.
+ * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded
+ * @arg 0x01: Pairing request will be sent even if the device was previously bonded
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond);
+
+/**
+ * @brief Resolve a private address.
+ * @note This command tries to resolve the address provided with the IRKs present in its database. If
+ * the address is resolved successfully with any one of the IRKs present in the database, it
+ * returns success.
+ * @param address Address to be resolved.
+ * @param[in] actual_address The public or static random address of the peer device, distributed during pairing phase.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address);
+
+/**
+ * @brief Resolve a private address.
+ * @note This command tries to resolve the address provided with the IRKs present in its database. If
+ * the address is resolved successfully with any one of the IRKs present in the database, it
+ * returns success.
+ * @param address Address to be resolved.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address);
+
+/**
+ * @brief This command gets the list of bonded devices.
+ * @note It returns the number of addresses and the corresponding address types and values.
+ * Example:
+ * @code
+ * tBleStatus ret;
+ * uint8_t num_devices = 0;
+ * uint8_t device_list[12*7];
+ * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list));
+ * for(int i = 0; i < num_devices; i+=7){
+ * uint8_t addr_type = device_list[i];
+ * uint8_t addr = device_list[i+1];
+ * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]);
+ * }
+ * @endcode
+ *
+ * @param[in] num_devices The number of bonded devices.
+ * @param[in] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address
+ * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR.
+ * @param device_list_size Maximum size of the device_list buffer used to return the device list.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size);
+
+/**
+ * @brief Puts the device into broadcast mode
+ * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address
+ * as specified in the own_addr_type parameter of the command.
+ * @param adv_interv_min Minimum advertising interval.
+ * Range: 0x00A0 to 0x4000
+ * Time = N * 0.625 msec
+ * Time Range: 100 ms to 10.24 sec
+ * @param adv_interv_max Maximum advertising interval.
+ * Range: 0x00A0 to 0x4000
+ * Time = N * 0.625 msec
+ * Time Range: 100 ms to 10.24 sec
+ * @param adv_type One of the allowed advertising types:
+ * @arg @ref ADV_SCAN_IND Scannable undirected advertising
+ * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising
+ * @param own_address_type If Privacy is disabled, the broadcaster address can be
+ * @arg @ref PUBLIC_ADDR.
+ * @arg @ref STATIC_RANDOM_ADDR.
+ * If Privacy is enabled, then the broadcaster address can be
+ * @arg @ref RESOLVABLE_PRIVATE_ADDR
+ * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR
+ * @param adv_data_length Length of the advertising data in the advertising packet
+ * @param adv_data Advertising data used by the device while advertising
+ * @param num_whitelist_entries Number of devices to be added to whitelist
+ * @param addr_array It will contain the addresses that have to be added into the whitelist. The
+ * format of the addr_array should be: address type followed by address.
+ * Example:
+ * @code
+ * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02,
+ * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02};
+ * @endcode
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type,
+ uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries,
+ const uint8_t *addr_array);
+
+/**
+ * @brief Starts an observation procedure, when the device is in Observer role.
+ * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer
+ * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth
+ * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event.
+ * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan.
+ * The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec
+ * to 10240 msec. For a number N, Time = N * 0.625 msec.
+ * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval.
+ * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec
+ * to 10240 msec. For a number N, Time = N * 0.625 msec.
+ * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN)
+ * @param own_address_type If Privacy is disabled, then the scanner address can be
+ * @arg @ref PUBLIC_ADDR.
+ * @arg @ref STATIC_RANDOM_ADDR.
+ * If Privacy is enabled, then the scanner address can be
+ * @arg @ref RESOLVABLE_PRIVATE_ADDR
+ * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR
+ * @param filter_duplicates Duplicate filtering enabled or not.
+ * @arg 0x00: Do not filter the duplicates
+ * @arg 0x01: Filter duplicates
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type,
+ uint8_t own_address_type, uint8_t filter_duplicates);
+
+/**
+ * @brief The command finds whether a device is bonded.
+ * @note If the device is using a resolvable private address and it has been bonded, then the command will return
+ * BLE_STATUS_SUCCESS.
+ * @param peer_address_type The address type of the peer device
+ * @arg @ref PUBLIC_ADDR.
+ * @arg @ref RANDOM_ADDR.
+ * @param peer_address Address used by the peer device while advertising.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gap_is_device_bonded_IDB05A1(uint8_t peer_address_type, const tBDAddr peer_address);
+
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup GAP_Events GAP events
+ * @{
+ */
+
+/**
+ * This event is generated by the controller when the limited discoverable
+ * mode ends due to timeout (180 seconds). No parameters in the event.
+ */
+#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400)
+
+
+/**
+ * This event is generated when the pairing process has completed successfully
+ * or a pairing procedure timeout has occurred or the pairing has failed.
+ * This is to notify the application that we have paired with a remote device
+ * so that it can take further actions or to notify that a timeout has occurred
+ * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt.
+ */
+#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401)
+typedef __packed struct _evt_gap_pairing_cmplt{
+ uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */
+ /**
+ * 0x00: Pairing Success. Pairing with a remote device was successful\n
+ * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n
+ * 0x02: Pairing Failed. The pairing failed with the remote device.
+ */
+ uint8_t status;
+} PACKED evt_gap_pairing_cmplt;
+
+
+/**
+ * This event is generated by the Security manager to the application when a pass key is required for pairing.
+ * When this event is received, the application has to respond with the aci_gap_pass_key_response() command.
+ * See @ref _evt_gap_pass_key_req.
+ */
+#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402)
+typedef __packed struct _evt_gap_pass_key_req{
+ uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */
+} PACKED evt_gap_pass_key_req;
+
+
+/**
+ * This event is generated by the Security manager to the application when the application
+ * has set that authorization is required for reading/writing of attributes. This event will
+ * be generated as soon as the pairing is complete. When this event is received,
+ * aci_gap_authorization_response() command should be used by the application.
+ * See @ref _evt_gap_author_req.
+ */
+#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403)
+typedef __packed struct _evt_gap_author_req{
+ uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */
+} PACKED evt_gap_author_req;
+
+/**
+ * This event is generated when the slave security request is successfully sent to the master.
+ * No parameters for this event.
+ */
+#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404)
+
+/**
+ * This event is generated when a pairing request is issued in response to a slave security
+ * request from a master which has previously bonded with the slave. When this event is received,
+ * the upper layer has to issue the command aci_gap_allow_rebond() in order to allow the slave
+ * to continue the pairing process with the master. No parameters for this event
+ */
+#define EVT_BLUE_GAP_BOND_LOST (0X0405)
+
+/**
+ * The event is given by the GAP layer to the upper layers when a device is discovered during scanning
+ * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found.
+ */
+#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406)
+typedef __packed struct _evt_gap_device_found{
+ uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */
+ uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */
+ tBDAddr bdaddr; /**< Address of the peer device found during scanning. */
+ uint8_t data_length; /**< Length of advertising or scan response data. */
+ uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */
+} PACKED evt_gap_device_found;
+
+/**
+ * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated
+ * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete.
+ */
+#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407)
+typedef __packed struct _evt_gap_procedure_complete{
+ uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */
+ /**
+ * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed
+ * due to authentication requirements).
+ */
+ uint8_t status;
+ /**
+ * Procedure specific data.\n
+ * @li For Name Discovery Procedure:\n
+ * the name of the peer device if the procedure completed successfully.
+ * @li For General Connection Establishment Procedure:\n
+ * The reconnection address written to the peripheral device if the peripheral is privacy enabled
+ */
+ uint8_t data[VARIABLE_SIZE];
+} PACKED evt_gap_procedure_complete;
+
+/**
+ * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral
+ * is not able to resolve the private address of the peer device after connecting to it.
+ */
+#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408)
+typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{
+ uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */
+} PACKED evt_gap_addr_not_resolved_IDB05A1;
+/**
+ * This event is raised when the reconnection address is generated during the general connection
+ * establishment procedure. The same address is set into the peer device also as a part of the general
+ * connection establishment procedure. In order to make use of the reconnection address the next time
+ * while connecting to the bonded peripheral, the application needs to use this reconnection address
+ * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc()
+ * and aci_gap_start_auto_conn_establish_proc().
+ */
+#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408)
+typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{
+ uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */
+} PACKED evt_gap_reconnection_addr_IDB04A1;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#endif /* __BLUENRG_GAP_ACI_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_aci.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_aci.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,1070 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name : bluenrg_gatt_aci.h
+* Author : AMS - AAS
+* Version : V1.0.0
+* Date : 26-Jun-2014
+* Description : Header file with GATT commands for BlueNRG FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_GATT_ACI_H__
+#define __BLUENRG_GATT_ACI_H__
+
+#include "bluenrg_gatt_server.h"
+
+/**
+ *@addtogroup GATT GATT
+ *@brief GATT layer.
+ *@{
+ */
+
+/**
+ *@defgroup GATT_Functions GATT functions
+ *@brief API for GATT layer.
+ *@{
+ */
+
+/**
+ * @brief Initialize the GATT layer for server and client roles.
+ * @note It adds also the GATT service with Service Changed Characteristic.
+ * Until this command is issued the GATT channel will not process any commands
+ * even if the connection is opened. This command has to be given
+ * before using any of the GAP features.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_init(void);
+
+/**
+ * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs
+ * to reserve the handle ranges for this service using max_attr_records parameter. This
+ * parameter specifies the maximum number of attribute records that can be added to this
+ * service (including the service attribute, include attribute, characteristic attribute,
+ * characteristic value attribute and characteristic descriptor attribute). Handle of the
+ * created service is returned.
+ * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors
+ * are allocated from the attribute pool.
+ * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types".
+ * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field
+ * @param service_type Primary or secondary service. See @ref Service_type "Service Type".
+ * @param max_attr_records Maximum number of attribute records that can be added to this service
+ * (including the service declaration itself)
+ * @param[out] serviceHandle Handle of the Service. When this service is added to the service,
+ * a handle is allocated by the server to this service. Server also
+ * allocates a range of handles for this service from serviceHandle to
+ * <serviceHandle + max_attr_records>.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type,
+ const uint8_t* service_uuid,
+ uint8_t service_type,
+ uint8_t max_attr_records,
+ uint16_t *serviceHandle);
+
+/**
+ * @brief Include a service given by included_start_handle and included_end_handle to another service
+ * given by service_handle. Attribute server creates an INCLUDE definition attribute and return
+ * the handle of this attribute in included_handle.
+ * @param service_handle Handle of the service to which another service has to be included
+ * @param included_start_handle Start Handle of the service which has to be included in service
+ * @param included_end_handle End Handle of the service which has to be included in service
+ * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs".
+ * @param[in] included_uuid 16-bit or 128-bit UUID.
+ * @param[out] included_handle Handle of the include declaration.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle,
+ uint16_t included_end_handle, uint8_t included_uuid_type,
+ const uint8_t* included_uuid, uint16_t *included_handle);
+
+/**
+ * @brief Add a characteristic to a service.
+ * @param serviceHandle Handle of the service to which the characteristic has to be added.
+ * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types".
+ * @arg @ref UUID_TYPE_16
+ * @arg @ref UUID_TYPE_128
+ * @param charUuid 16-bit or 128-bit UUID.
+ * @param charValueLen Maximum length of the characteristic value.
+ * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3,
+ * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties".
+ * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions".
+ * @arg ATTR_PERMISSION_NONE
+ * @arg ATTR_PERMISSION_AUTHEN_READ
+ * @arg ATTR_PERMISSION_AUTHOR_READ
+ * @arg ATTR_PERMISSION_ENCRY_READ
+ * @arg ATTR_PERMISSION_AUTHEN_WRITE
+ * @arg ATTR_PERMISSION_AUTHOR_WRITE
+ * @arg ATTR_PERMISSION_ENCRY_WRITE
+ * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server
+ * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask".
+ * @arg GATT_DONT_NOTIFY_EVENTS
+ * @arg GATT_NOTIFY_ATTRIBUTE_WRITE
+ * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP
+ * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP
+ * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16.
+ * @param isVariable If the attribute has a variable length value field (1) or not (0).
+ * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration.
+ * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client
+ * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE
+ * properties.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_add_char(uint16_t serviceHandle,
+ uint8_t charUuidType,
+ const uint8_t* charUuid,
+ uint8_t charValueLen,
+ uint8_t charProperties,
+ uint8_t secPermissions,
+ uint8_t gattEvtMask,
+ uint8_t encryKeySize,
+ uint8_t isVariable,
+ uint16_t* charHandle);
+
+/**
+ * Add a characteristic descriptor to a service.
+ * @param serviceHandle Handle of the service to which the characteristic belongs
+ * @param charHandle Handle of the characteristic to which description has to be added.
+ * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types".
+ * @arg @ref UUID_TYPE_16
+ * @arg @ref UUID_TYPE_128
+ * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG
+ * (Well_known_UUIDs) or a user-defined one.
+ * @param descValueMaxLen The maximum length of the descriptor value
+ * @param descValueLen Current Length of the characteristic descriptor value
+ * @param[in] descValue Value of the characteristic description
+ * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions".
+ * @arg ATTR_PERMISSION_NONE
+ * @arg ATTR_PERMISSION_AUTHEN_READ
+ * @arg ATTR_PERMISSION_AUTHOR_READ
+ * @arg ATTR_PERMISSION_ENCRY_READ
+ * @arg ATTR_PERMISSION_AUTHEN_WRITE
+ * @arg ATTR_PERMISSION_AUTHOR_WRITE
+ * @arg ATTR_PERMISSION_ENCRY_WRITE
+ * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions".
+ * @arg ATTR_NO_ACCESS
+ * @arg ATTR_ACCESS_READ_ONLY
+ * @arg ATTR_ACCESS_WRITE_REQ_ONLY
+ * @arg ATTR_ACCESS_READ_WRITE
+ * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE
+ * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED
+ * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server
+ * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask".
+ * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16.
+ * @param isVariable If the attribute has a variable length value field (1) or not (0).
+ * @param[out] descHandle Handle of the Characteristic Descriptor.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle,
+ uint16_t charHandle,
+ uint8_t descUuidType,
+ const uint8_t* uuid,
+ uint8_t descValueMaxLen,
+ uint8_t descValueLen,
+ const void* descValue,
+ uint8_t secPermissions,
+ uint8_t accPermissions,
+ uint8_t gattEvtMask,
+ uint8_t encryKeySize,
+ uint8_t isVariable,
+ uint16_t* descHandle);
+
+/**
+ * @brief Update a characteristic value in a service.
+ * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication)
+ * will be sent to the client after sending this command to the BlueNRG. The command is queued into the
+ * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed,
+ * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or
+ * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate
+ * than what is allowed by the link. Throughput on BLE link depends on connection interval and
+ * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request()
+ * for more info on how to suggest new connection parameters from a slave). If the application does not
+ * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function
+ * returns @ref BLE_STATUS_SUCCESS or any other error code.\n
+ * Example:\n
+ * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some
+ * notifications will be lost.
+ * @code
+ * tBleStatus Free_Fall_Notify(void)
+ * {
+ * uint8_t val;
+ * tBleStatus ret;
+ *
+ * val = 0x01;
+ * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val);
+ *
+ * if (ret != BLE_STATUS_SUCCESS){
+ * PRINTF("Error while updating ACC characteristic.\n") ;
+ * return BLE_STATUS_ERROR ;
+ * }
+ * return BLE_STATUS_SUCCESS;
+ * }
+ * @endcode
+ * Here if BlueNRG buffer become full, the application try again to send the notification.
+ * @code
+ * struct timer t;
+ * Timer_Set(&t, CLOCK_SECOND*10);
+ * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){
+ * // Radio is busy (buffer full).
+ * if(Timer_Expired(&t))
+ * break;
+ * }
+ * @endcode
+ *
+ * @param servHandle Handle of the service to which characteristic belongs
+ * @param charHandle Handle of the characteristic
+ * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0,
+ * and the attribute value is of variable length, then the length of the attribute will
+ * be set to the charValueLen. If the charValOffset is set to a value greater than 0,
+ * then the length of the attribute will be set to the maximum length as specified for
+ * the attribute while adding the characteristic.
+ * @param charValueLen Length of the characteristic value in octets
+ * @param[in] charValue Characteristic value
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_update_char_value(uint16_t servHandle,
+ uint16_t charHandle,
+ uint8_t charValOffset,
+ uint8_t charValueLen,
+ const void *charValue);
+/**
+ * @brief Delete the specified characteristic from the service.
+ * @param servHandle Handle of the service to which characteristic belongs
+ * @param charHandle Handle of the characteristic to be deleted
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle);
+
+/**
+ * @brief Delete the specified service from the GATT server database.
+ * @param servHandle Handle of the service to be deleted
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_del_service(uint16_t servHandle);
+
+/**
+ * @brief Delete the Include definition from the service.
+ * @param servHandle Handle of the service to which Include definition belongs
+ * @param includeServHandle Handle of the Included definition to be deleted
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle);
+
+/**
+ * @brief Perform an ATT MTU exchange procedure.
+ * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP
+ * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated
+ * to indicate the end of the procedure.
+ * @param conn_handle Connection handle for which the command is given.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle);
+
+/**
+ * @brief Send a @a Find @a Information @a Request.
+ * @note This command is used to obtain the mapping of attribute handles with their associated
+ * types. The responses of the procedure are given through the
+ * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by
+ * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param start_handle Starting handle of the range of attributes to be discovered on the server
+ * @param end_handle Ending handle of the range of attributes to be discovered on the server
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle);
+
+/**
+ * @brief Send a @a Find @a By @a Type @a Value @a Request
+ * @note The Find By Type Value Request is used to obtain the handles of attributes that
+ * have a given 16-bit UUID attribute type and a given attribute value.
+ * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event.
+ * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param start_handle First requested handle number
+ * @param end_handle Last requested handle number
+ * @param uuid 2 octet UUID to find (little-endian)
+ * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7).
+ * @param attr_val Attribute value to find
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+ uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val);
+
+/**
+ * @brief Send a @a Read @a By @a Type @a Request
+ * @note The Read By Type Request is used to obtain the values of attributes where the attribute type
+ * is known but the handle is not known.
+ * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event.
+ * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param start_handle First requested handle number
+ * @param end_handle Last requested handle number
+ * @param uuid_type @arg @ref UUID_TYPE_16
+ * @arg @ref UUID_TYPE_128
+ * @param uuid 2 or 16 octet UUID
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+ uint8_t uuid_type, uint8_t* uuid);
+
+/**
+ * @brief Send a @a Read @a By @a Group @a Type @a Request
+ * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute
+ * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping
+ * attribute types are: «Primary Service», «Secondary Service» and «Characteristic».
+ * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event.
+ * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param start_handle First requested handle number
+ * @param end_handle Last requested handle number
+ * @param uuid_type @arg @ref UUID_TYPE_16
+ * @arg @ref UUID_TYPE_128
+ * @param uuid 2 or 16 octet UUID
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+ uint8_t uuid_type, uint8_t* uuid);
+
+/**
+ * @brief Send a @a Prepare @a Write @a Request
+ * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute.
+ * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event.
+ * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param attr_handle The handle of the attribute to be written
+ * @param value_offset The offset of the first octet to be written
+ * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5).
+ * @param attr_val The value of the attribute to be written
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset,
+ uint8_t attr_val_len, uint8_t* attr_val);
+
+/**
+ * @brief Send an @a Execute @a Write @a Request
+ * @note The Execute Write Request is used to request the server to write or cancel the write of all the
+ * prepared values currently held in the prepare queue from this client.
+ * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event.
+ * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param execute @arg 0x00 Cancel all prepared writes
+ * @arg 0x01 Immediately write all pending prepared values.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute);
+
+/**
+ * @brief This command will start the GATT client procedure to discover all primary services on the server.
+ * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event.
+ * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle);
+
+/**
+ * @brief Start the procedure to discover the primary services of the specified UUID on the server.
+ * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event.
+ * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param uuid_type @arg @ref UUID_TYPE_16
+ * @arg @ref UUID_TYPE_128
+ * @param uuid 2 or 16 octet UUID
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid);
+
+/**
+ * @brief Start the procedure to find all included services.
+ * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event.
+ * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param start_handle Start handle of the service
+ * @param end_handle End handle of the service
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle,
+ uint16_t end_handle);
+
+/**
+ * @brief Start the procedure to discover all the characteristics of a given service.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param start_attr_handle Start attribute handle of the service
+ * @param end_attr_handle End attribute handle of the service
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle,
+ uint16_t end_attr_handle);
+
+/**
+ * @brief Start the procedure to discover all the characteristics specified by a UUID.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * Before procedure completion the response packets are given through
+ * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param start_handle Start attribute handle of the service
+ * @param end_handle End attribute handle of the service
+ * @param uuid_type @arg @ref UUID_TYPE_16
+ * @arg @ref UUID_TYPE_128
+ * @param uuid 2 or 16 octet UUID
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle,
+ uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid);
+
+/**
+ * @brief Start the procedure to discover all characteristic descriptors on the server.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event.
+ * @param conn_handle Connection handle for which the command is given.
+ * @param char_val_handle Starting handle of the characteristic
+ * @param char_end_handle End handle of the characteristic
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle,
+ uint16_t char_end_handle);
+
+/**
+ * @brief Start the procedure to read the attribute value.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the characteristic to be read
+ * @return Value indicating success or error code.\n
+ * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n
+ * - If the exchange has already taken place\n
+ * - If GATT is expecting response for previous request\n
+ * - Already a request is in the queue to be sent\n
+ * - Channel not open\n
+ * - Already one GATT procedure is started
+ */
+tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle);
+
+/**
+ * @brief Start the procedure to read all the characteristics specified by the UUID.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * Before procedure completion the response packets are given through
+ * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param start_handle Starting handle of the range to be searched
+ * @param end_handle End handle of the range to be searched
+ * @param uuid_type @arg @ref UUID_TYPE_16
+ * @arg @ref UUID_TYPE_128
+ * @param uuid 2 or 16 octet UUID
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle,
+ uint8_t uuid_type, uint8_t* uuid);
+
+/**
+ * @brief Start the procedure to read a long characteristic value.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the characteristic to be read
+ * @param val_offset Offset from which the value needs to be read
+ * @return Value indicating success or error code.\n
+ * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n
+ * - If the exchange has already taken place\n
+ * - If GATT is expecting response for previous request\n
+ * - Already a request is in the queue to be sent\n
+ * - Channel not open\n
+ * - Already one GATT procedure is started
+ */
+tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle,
+ uint16_t val_offset);
+
+/**
+ * @brief Start a procedure to read multiple characteristic values from a server.
+ * @note This sub-procedure is used to read multiple Characteristic Values from a server when the
+ * client knows the Characteristic Value Handles.
+ * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * Before procedure completion the response packets are given through
+ * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param num_handles The number of handles for which the value has to be read
+ * @param set_of_handles The handles for which the attribute value has to be read
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles,
+ uint8_t* set_of_handles);
+
+/**
+ * @brief Start the procedure to write a characteristic value.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the characteristic to be written
+ * @param value_len Length of the value to be written
+ * @param[in] attr_value Value to be written
+ * @return Value indicating success or error code.\n
+ * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n
+ * - If the exchange has already taken place\n
+ * - If GATT is expecting response for previous request\n
+ * - Already a request is in the queue to be sent\n
+ * - Channel not open\n
+ * - Already one GATT procedure is started
+ */
+tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle,
+ uint8_t value_len, uint8_t *attr_value);
+
+/**
+ * @brief Start the procedure to write a long characteristic value.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP
+ * events are raised.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute to be written
+ * @param val_offset Offset at which the attribute has to be written
+ * @param val_len Length of the value to be written
+ * @param attr_val Value to be written
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle,
+ uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val);
+
+/**
+ * @brief Start the procedure to write a characteristic reliably.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP
+ * events are raised.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute to be written
+ * @param val_offset Offset at which the attribute has to be written
+ * @param val_len Length of the value to be written
+ * @param attr_val Value to be written
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle,
+ uint16_t val_offset, uint8_t val_len, uint8_t* attr_val);
+
+/**
+ * @brief Start the procedure to write a long characteristic descriptor.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP
+ * events are raised.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute to be written
+ * @param val_offset Offset at which the attribute has to be written
+ * @param val_len Length of the value to be written
+ * @param attr_val Value to be written
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle,
+ uint16_t val_offset, uint8_t val_len, uint8_t* attr_val);
+
+/**
+ * @brief Start the procedure to read a long characteristic value.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP
+ * event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the characteristic descriptor
+ * @param val_offset Offset from which the value needs to be read
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle,
+ uint16_t val_offset);
+
+/**
+ * @brief Start the procedure to write a characteristic descriptor.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute to be written
+ * @param value_len Length of the value to be written
+ * @param[in] attr_value Value to be written
+ * @return Value indicating success or error code.\n
+ * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n
+ * - If the exchange has already taken place\n
+ * - If GATT is expecting response for previous request\n
+ * - Already a request is in the queue to be sent\n
+ * - Channel not open\n
+ * - Already one GATT procedure is started
+ */
+tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle,
+ uint8_t value_len, uint8_t *attr_value);
+
+/**
+ * @brief Start the procedure to read the descriptor specified.
+ * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated.
+ * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the descriptor to be read
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle);
+
+/**
+ * @brief Start the procedure to write a characteristic value without waiting for any response from the server.
+ * @note No events are generated after this command is executed.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute to be written
+ * @param val_len Length of the value to be written (up to ATT_MTU - 3)
+ * @param[in] attr_val Value to be written
+ * @return Value indicating success or error code.\n
+ * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n
+ * - If the exchange has already taken place\n
+ * - If GATT is expecting response for previous request\n
+ * - Already a request is in the queue to be sent\n
+ * - Channel not open\n
+ * - Already one GATT procedure is started
+ */
+tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle,
+ uint8_t val_len, const uint8_t* attr_val);
+
+/**
+ * @brief Start a signed write without response from the server.
+ * @note The procedure i used to write a characteristic value with an authentication signature without waiting
+ * for any response from the server. It cannot be used when the link is encrypted.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute to be written
+ * @param val_len Length of the value to be written (up to ATT_MTU - 13).
+ * @param attr_val Value to be written
+ * @return Value indicating success or error code
+ */
+tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle,
+ uint8_t val_len, uint8_t* attr_val);
+
+/**
+ * @brief Confirm an indication
+ * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION.
+ * @param conn_handle Connection handle for which the command is given.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle);
+
+/**
+ * @brief Allow or reject a write request from a client.
+ * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ.
+ * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed,
+ * then the status has to be set to 1 and the error code has to be set to the error code that has to be
+ * passed to the client.
+ * @param conn_handle Connection handle for which the command is given
+ * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ.
+ * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n
+ * 0x01: The value cannot be written to the attribute specified by the attr_handle.
+ * @param err_code The error code that has to be passed to the client in case the write has to be rejected.
+ * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ.
+ * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_write_response(uint16_t conn_handle,
+ uint16_t attr_handle,
+ uint8_t write_status,
+ uint8_t err_code,
+ uint8_t att_val_len,
+ uint8_t *att_val);
+
+/**
+ * @brief Allow the GATT server to send a response to a read request from a client.
+ * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ
+ * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response
+ * can be sent to the client. So if the application wishes to update any of the attributes before
+ * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value
+ * and then give this command. The application should perform the required operations within 30 seconds,
+ * otherwise the GATT procedure will go to timeout.
+ * @param conn_handle Connection handle for which the command is given.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_allow_read(uint16_t conn_handle);
+
+/**
+ * @brief Set the security permission for the attribute handle specified.
+ * @note Currently the setting of security permission is allowed only for client configuration descriptor.
+ * @param service_handle Handle of the service which contains the attribute whose security
+ * permission has to be modified.
+ * @param attr_handle Handle of the attribute whose security permission has to be modified.
+ * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions".
+ * @arg ATTR_PERMISSION_NONE
+ * @arg ATTR_PERMISSION_AUTHEN_READ
+ * @arg ATTR_PERMISSION_AUTHOR_READ
+ * @arg ATTR_PERMISSION_ENCRY_READ
+ * @arg ATTR_PERMISSION_AUTHEN_WRITE
+ * @arg ATTR_PERMISSION_AUTHOR_WRITE
+ * @arg ATTR_PERMISSION_ENCRY_WRITE
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle,
+ uint8_t security_permission);
+
+/**
+ * @brief This command sets the value of the descriptor specified by charDescHandle.
+ * @param servHandle Handle of the service which contains the descriptor.
+ * @param charHandle Handle of the characteristic which contains the descriptor.
+ * @param charDescHandle Handle of the descriptor whose value has to be set.
+ * @param charDescValOffset Offset from which the descriptor value has to be updated.
+ * @param charDescValueLen Length of the descriptor value
+ * @param[in] charDescValue descriptor value
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_set_desc_value(uint16_t servHandle,
+ uint16_t charHandle,
+ uint16_t charDescHandle,
+ uint16_t charDescValOffset,
+ uint8_t charDescValueLen,
+ const void *charDescValue);
+
+/**
+ * @brief Reads the value of the attribute handle specified from the local GATT database.
+ * @param attr_handle Handle of the attribute to read
+ * @param data_len Length of the data buffer.
+ * @param[in] data_len_out_p Length of the read attribute.
+ * @param[in] data Pointer to the buffer that will contain the read value.
+ * The buffer will be filled with the attribute value.
+ * The length will be the minimum between the provided data_len and the actual length of the
+ * attribute (in data_len_out_p).
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data);
+
+ /**
+ * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset.
+ * @param attr_handle Handle of the attribute to read
+ * @param offset Offset from which the value needs to be read
+ * @param data_len Length of the data buffer.
+ * @param[in] data_len_out_p Length of the read attribute.
+ * @param[in] data Pointer to the buffer that will contain the read value.
+ * The buffer will be filled with the attribute value.
+ * The length will be the minimum between the provided data_len and the actual length of the
+ * attribute (in data_len_out_p).
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data);
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup GATT_Events GATT events
+ * The structures are the data field of @ref evt_blue_aci.
+ * @{
+ */
+
+/**
+ * This event is raised to the application by the GATT server when a client modifies any attribute on the server,
+ * if event is enabled (see @ref Gatt_Event_Mask "Gatt Event Mask").
+ * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1.
+ */
+#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01)
+typedef __packed struct _evt_gatt_attr_modified_IDB05A1{
+ uint16_t conn_handle; /**< The connection handle which modified the attribute. */
+ uint16_t attr_handle; /**< Handle of the attribute that was modified. */
+ uint8_t data_length; /**< The length of the data */
+ uint16_t offset; /**< Offset from which the write has been performed by the peer device */
+ uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */
+} PACKED evt_gatt_attr_modified_IDB05A1;
+
+typedef __packed struct _evt_gatt_attr_modified_IDB04A1{
+ uint16_t conn_handle; /**< The connection handle which modified the attribute. */
+ uint16_t attr_handle; /**< Handle of the attribute that was modified. */
+ uint8_t data_length; /**< The length of the data */
+ uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */
+} PACKED evt_gatt_attr_modified_IDB04A1;
+
+/**
+ * This event is generated by the client/server to the application on a GATT timeout (30 seconds).
+ * See @ref _evt_gatt_procedure_timeout.
+ */
+#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02)
+typedef __packed struct _evt_gatt_procedure_timeout{
+ uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */
+} PACKED evt_gatt_procedure_timeout;
+
+/**
+ * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration().
+ * See @ref _evt_att_exchange_mtu_resp.
+ */
+#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03)
+typedef __packed struct _evt_att_exchange_mtu_resp{
+ uint16_t conn_handle; /**< The connection handle related to the response */
+ uint8_t event_data_length; /**< Length of following data (always 1). */
+ uint16_t server_rx_mtu; /**< Attribute server receive MTU size */
+} PACKED evt_att_exchange_mtu_resp;
+
+/**
+ * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and
+ * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp.
+ */
+#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04)
+typedef __packed struct _evt_att_find_information_resp{
+ uint16_t conn_handle; /**< The connection handle related to the response */
+ uint8_t event_data_length; /**< Length of following data. */
+ uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */
+ /**
+ * A sequence of handle-uuid pairs.\n
+ * @li if format=1, each pair is:\n
+ * [2 octets for handle, 2 octets for UUIDs] \n
+ * @li if format=2, each pair is:\n
+ * [2 octets for handle, 16 octets for UUIDs]
+ */
+ uint8_t handle_uuid_pair[VARIABLE_SIZE];
+} PACKED evt_att_find_information_resp;
+
+/**
+ * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See
+ * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp.
+ */
+#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05)
+typedef __packed struct _evt_att_find_by_type_val_resp{
+ uint16_t conn_handle; /**< The connection handle related to the response */
+ uint8_t event_data_length; /**< Length of following data. */
+ /**
+ * Handles Information List as defined in Bluetooth Core v4.0 spec.
+ * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle]
+ */
+ uint8_t handles_info_list[VARIABLE_SIZE];
+} PACKED evt_att_find_by_type_val_resp;
+
+/**
+ * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and
+ * aci_gatt_disc_all_charac_of_serv().
+ * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp.
+ */
+#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06)
+typedef __packed struct _evt_att_read_by_type_resp{
+ uint16_t conn_handle; /**< The connection handle related to the response */
+ uint8_t event_data_length; /**< Length of following data. */
+ uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */
+ /**
+ * Attribute Data List as defined in Bluetooth Core v4.0 spec.
+ * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value]
+ */
+ uint8_t handle_value_pair[VARIABLE_SIZE];
+} PACKED evt_att_read_by_type_resp;
+
+/**
+ * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val().
+ * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp.
+ */
+#define EVT_BLUE_ATT_READ_RESP (0x0C07)
+typedef __packed struct _evt_att_read_resp{
+ uint16_t conn_handle; /**< The connection handle related to the response. */
+ uint8_t event_data_length; /**< Length of following data. */
+ uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */
+} PACKED evt_att_read_resp;
+
+/**
+ * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val().
+ * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp.
+ */
+#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08)
+typedef __packed struct _evt_att_read_blob_resp{
+ uint16_t conn_handle; /**< The connection handle related to the response. */
+ uint8_t event_data_length; /**< Length of following data. */
+ uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */
+} PACKED evt_att_read_blob_resp;
+
+/**
+ * This event is generated in response to a @a Read @a Multiple @a Request.
+ * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp.
+ */
+#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09)
+typedef __packed struct _evt_att_read_mult_resp{
+ uint16_t conn_handle; /**< The connection handle related to the response. */
+ uint8_t event_data_length; /**< Length of following data. */
+ uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/
+} PACKED evt_att_read_mult_resp;
+
+/**
+ * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services().
+ * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp.
+ */
+#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A)
+typedef __packed struct _evt_att_read_by_group_resp{
+ uint16_t conn_handle; /**< The connection handle related to the response. */
+ uint8_t event_data_length; /**< Length of following data. */
+ uint8_t attribute_data_length; /**< The size of each Attribute Data. */
+ /**
+ * A list of Attribute Data where the attribute data is composed by:
+ * @li 2 octets for Attribute Handle
+ * @li 2 octets for End Group Handle
+ * @li (attribute_data_length - 4) octets for Attribute Value
+ */
+ uint8_t attribute_data_list[VARIABLE_SIZE];
+} PACKED evt_att_read_by_group_resp;
+
+/**
+ * This event is generated in response to a @a Prepare @a Write @a Request.
+ * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp.
+ */
+#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C)
+typedef __packed struct _evt_att_prepare_write_resp{
+ uint16_t conn_handle; /**< The connection handle related to the response. */
+ uint8_t event_data_length; /**< Length of following data. */
+ uint16_t attribute_handle; /**< The handle of the attribute to be written. */
+ uint16_t offset; /**< The offset of the first octet to be written. */
+ uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */
+} PACKED evt_att_prepare_write_resp;
+
+/**
+ * This event is generated in response to an @a Execute @a Write @a Request.
+ * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp.
+ */
+#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D)
+typedef __packed struct _evt_att_exec_write_resp{
+ uint16_t conn_handle; /**< The connection handle related to the response. */
+ uint8_t event_data_length; /**< Always 0. */
+} PACKED evt_att_exec_write_resp;
+
+/**
+ * This event is generated when an indication is received from the server.
+ * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication.
+ */
+#define EVT_BLUE_GATT_INDICATION (0x0C0E)
+typedef __packed struct _evt_gatt_indication{
+ uint16_t conn_handle; /**< The connection handle related to the event. */
+ uint8_t event_data_length; /**< Length of following data. */
+ uint16_t attr_handle; /**< The handle of the attribute. */
+ uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */
+} PACKED evt_gatt_indication;
+
+/**
+ * This event is generated when a notification is received from the server.
+ * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification.
+ */
+#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F)
+typedef __packed struct _evt_gatt_notification{
+ uint16_t conn_handle; /**< The connection handle related to the event. */
+ uint8_t event_data_length; /**< Length of following data. */
+ uint16_t attr_handle; /**< The handle of the attribute. */
+ uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */
+} PACKED evt_gatt_attr_notification;
+
+/**
+ * This event is generated when a GATT client procedure completes either with error or successfully.
+ * See @ref _evt_gatt_procedure_complete.
+ */
+#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10)
+typedef __packed struct _evt_gatt_procedure_complete{
+ uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */
+ uint8_t data_length; /**< Length of error_code field (always 1). */
+ /**
+ * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS).
+ */
+ uint8_t error_code;
+} PACKED evt_gatt_procedure_complete;
+
+/**
+ * This event is generated when an Error Response is received from the server. The error response can be given
+ * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended
+ * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp.
+ */
+#define EVT_BLUE_GATT_ERROR_RESP (0x0C11)
+typedef __packed struct _evt_gatt_error_resp{
+ uint16_t conn_handle; /**< The connection handle related to the event. */
+ uint8_t event_data_length; /**< Length of following data. */
+ uint8_t req_opcode; /**< The request that generated this error response. */
+ uint16_t attr_handle; /**< The attribute handle that generated this error response. */
+ uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */
+} PACKED evt_gatt_error_resp;
+
+/**
+ * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using
+ * Characteristic UUID" procedure.
+ * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1),
+ * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a
+ * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp.
+ */
+#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12)
+typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{
+ uint16_t conn_handle; /**< The connection handle related to the event. */
+ uint8_t event_data_length; /**< Length of following data. */
+ uint16_t attr_handle; /**< The handle of the attribute. */
+ /**
+ * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1),
+ * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a
+ * "Read using Characteristic UUID" has been performed.
+ */
+ uint8_t attr_value[VARIABLE_SIZE];
+} PACKED evt_gatt_disc_read_char_by_uuid_resp;
+
+/**
+ * This event is given to the application when a write request, write command or signed write command
+ * is received by the server from the client. This event will be given to the application only if the
+ * event bit for this event generation is set when the characteristic was added.
+ * When this event is received, the application has to check whether the value being requested for write
+ * is allowed to be written and respond with the command aci_gatt_write_response().
+ * If the write is rejected by the application, then the value of the attribute will not be modified.
+ * In case of a write request, an error response will be sent to the client, with the error code as specified by the application.
+ * In case of write/signed write commands, no response is sent to the client but the attribute is not modified.
+ * See @ref evt_gatt_write_permit_req.
+ */
+#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13)
+typedef __packed struct _evt_gatt_write_permit_req{
+ uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */
+ uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */
+ uint8_t data_length; /**< Length of data field. */
+ uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */
+} PACKED evt_gatt_write_permit_req;
+
+/**
+ * This event is given to the application when a read request or read blob request is received by the server
+ * from the client. This event will be given to the application only if the event bit for this event generation
+ * is set when the characteristic was added.
+ * On receiving this event, the application can update the value of the handle if it desires and when done
+ * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client.
+ * See @ref evt_gatt_read_permit_req.
+ *
+ */
+#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14)
+typedef __packed struct _evt_gatt_read_permit_req{
+ uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */
+ uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */
+ uint8_t data_length; /**< Length of offset field. (always 1). */
+ uint8_t offset; /**< Contains the offset from which the read has been requested */
+} PACKED evt_gatt_read_permit_req;
+
+/**
+ * This event is given to the application when a read multiple request or read by type request is received
+ * by the server from the client. This event will be given to the application only if the event bit for this
+ * event generation is set when the characteristic was added.
+ * On receiving this event, the application can update the values of the handles if it desires and when done
+ * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client.
+ * See @ref evt_gatt_read_multi_permit_req.
+ *
+ */
+#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15)
+typedef __packed struct _evt_gatt_read_multi_permit_req{
+ uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */
+ uint8_t data_length; /**< Length of data field. */
+ uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */
+} PACKED evt_gatt_read_multi_permit_req;
+
+/**
+ * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2).
+ * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES.
+ * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value().
+ * See @ref evt_gatt_tx_pool_vailable.
+ *
+ */
+#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_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;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* __BLUENRG_GATT_ACI_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_server.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_server.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,223 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name : bluenrg_gatt_server.h
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 19-July-2012
+* Description : Header file for BlueNRG's GATT server layer.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BNRG_GATT_SERVER_H__
+#define __BNRG_GATT_SERVER_H__
+
+#include "ble_compiler.h"
+#include "ble_status.h"
+
+/**
+ *@addtogroup GATT GATT
+ *@{
+ */
+
+/**
+ * @anchor Well-Known_UUIDs
+ * @name Well-Known UUIDs
+ * @{
+ */
+#define PRIMARY_SERVICE_UUID (0x2800)
+#define SECONDARY_SERVICE_UUID (0x2801)
+#define INCLUDE_SERVICE_UUID (0x2802)
+#define CHARACTERISTIC_UUID (0x2803)
+#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900)
+#define CHAR_USER_DESC_UUID (0x2901)
+#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902)
+#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903)
+#define CHAR_FORMAT_DESC_UUID (0x2904)
+#define CHAR_AGGR_FMT_DESC_UUID (0x2905)
+#define GATT_SERVICE_UUID (0x1801)
+#define GAP_SERVICE_UUID (0x1800)
+#define SERVICE_CHANGED_UUID (0x2A05)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Access_permissions
+ * @name Access permissions
+ * Access permissions for an attribute
+ * @{
+ */
+#define ATTR_NO_ACCESS (0x00)
+#define ATTR_ACCESS_READ_ONLY (0x01)
+#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02)
+#define ATTR_ACCESS_READ_WRITE (0x03)
+#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04)
+#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08)
+/**
+ * Allows all write procedures
+ */
+#define ATTR_ACCESS_WRITE_ANY (0x0E)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Char_properties
+ * @name Characteristic properties.
+ * @{
+ */
+#define CHAR_PROP_BROADCAST (0x01)
+#define CHAR_PROP_READ (0x02)
+#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04)
+#define CHAR_PROP_WRITE (0x08)
+#define CHAR_PROP_NOTIFY (0x10)
+#define CHAR_PROP_INDICATE (0x20)
+#define CHAR_PROP_SIGNED_WRITE (0x40)
+#define CHAR_PROP_EXT (0x80)
+/**
+ * @}
+ */
+
+
+/**
+ * @anchor Security_permissions
+ * @name Security permissions for an attribute.
+ * @{
+ */
+#define ATTR_PERMISSION_NONE (0x00) /**< No security. */
+#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */
+#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */
+#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */
+#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */
+#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */
+#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */
+/**
+ * @}
+ */
+
+/**
+ * @anchor UUID_Types
+ * @name Type of UUID (16 bit or 128 bit).
+ * @{
+ */
+#define UUID_TYPE_16 (0x01)
+#define UUID_TYPE_128 (0x02)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Service_type
+ * @name Type of service (primary or secondary)
+ * @{
+ */
+#define PRIMARY_SERVICE (0x01)
+#define SECONDARY_SERVICE (0x02)
+/**
+ * @}
+ */
+
+/**
+ * @anchor Gatt_Event_Mask
+ * @name Gatt Event Mask
+ * Type of event generated by GATT server
+ * @{
+ */
+#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */
+#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute.
+ An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */
+#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd
+ or a signed write cmd are received by the server for this attribute.
+ An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */
+#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is
+ received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */
+/**
+ * @}
+ */
+
+/**
+ * @name Type of characteristic length
+ * See aci_gatt_add_char()
+ * @{
+ */
+#define CHAR_VALUE_LEN_CONSTANT (0x00)
+#define CHAR_VALUE_LEN_VARIABLE (0x01)
+/**
+ * @}
+ */
+
+
+/**
+ * @name Encryption key size
+ * @{
+ */
+/**
+ * Minimum encryption key size
+ */
+#define MIN_ENCRY_KEY_SIZE (7)
+
+/**
+ * Maximum encryption key size
+ */
+#define MAX_ENCRY_KEY_SIZE (0x10)
+/**
+ * @}
+ */
+
+/**
+ * @name Characteristic Presentation Format
+ * @{
+ */
+typedef __packed struct _charactFormat {
+ uint8_t format;
+ int8_t exp;
+ uint16_t unit;
+ uint8_t name_space;
+ uint16_t desc;
+} PACKED charactFormat;
+
+/**
+ * @}
+ */
+
+/**
+ * @name Format
+ * @{
+ */
+#define FORMAT_UINT8 0x04
+#define FORMAT_UINT16 0x06
+#define FORMAT_SINT16 0x0E
+#define FORMAT_SINT24 0x0F
+/**
+ * @}
+ */
+
+/**
+ * @name Unit
+ * @{
+ */
+#define UNIT_UNITLESS 0x2700
+#define UNIT_TEMP_CELSIUS 0x272F
+#define UNIT_PRESSURE_BAR 0x2780
+/**
+ * @}
+ */
+
+
+/**
+ * ATT MTU size
+ */
+#define ATT_MTU (23)
+
+/**
+ * @}
+ */
+
+
+
+#endif /* __BNRG_GATT_SERVER_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_hal_aci.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_hal_aci.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,183 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name : bluenrg_hal_aci.h
+* Author : AMS - AAS
+* Version : V1.0.0
+* Date : 26-Jun-2014
+* Description : Header file with HCI commands for BlueNRG FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_HAL_ACI_H__
+#define __BLUENRG_HAL_ACI_H__
+
+/**
+ *@addtogroup HAL HAL
+ *@brief Hardware Abstraction Layer.
+ *@{
+ */
+
+/**
+ * @defgroup HAL_Functions HAL functions
+ * @brief API for BlueNRG HAL layer.
+ * @{
+ */
+
+/**
+ * @brief This command writes a value to a low level configure data structure.
+ * @note It is useful to setup directly some low level parameters for the system at runtime.
+ * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n
+ * See @ref Config_vals.
+ *
+ * @param len Length of data to be written
+ * @param[out] val Data to be written
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_write_config_data(uint8_t offset,
+ uint8_t len,
+ const uint8_t *val);
+
+/**
+ * @brief This command requests the value in the low level configure data structure.
+ * The number of read bytes changes for different Offset.
+ * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n
+ * See @ref Config_vals.
+ * @param data_len Length of the data buffer
+ * @param[out] data_len_out_p length of the data returned by the read.
+ * @param[out] data Read data
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data);
+
+/**
+ * @brief This command sets the TX power level of the BlueNRG.
+ * @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines
+ * the output power level (dBm).
+ * When the system starts up or reboots, the default TX power level will be used, which is
+ * the maximum value of 8dBm. Once this command is given, the output power will be changed
+ * instantly, regardless if there is Bluetooth communication going on or not. For example,
+ * for debugging purpose, the BlueNRG can be set to advertise all the time and use this
+ * command to observe the signal strength changing. The system will keep the last received
+ * TX power level from the command, i.e. the 2nd command overwrites the previous TX power
+ * level. The new TX power level remains until another Set TX Power command, or the system
+ * reboots.\n
+ * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the
+ * right value, depending on the selected hardware configuration for the RF network:
+ * normal mode or high power mode.
+ * @param pa_level Can be from 0 to 7. Set the PA level value.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level);
+
+/**
+ * @brief This command returns the number of packets sent in Direct Test Mode.
+ * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets
+ * have been transmitted. This command can be used to check how many packets have been sent
+ * during the Direct TX test.\n
+ * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again.
+ * The counter is not cleared until the next Direct TX test starts.
+ * @param[out] number_of_packets Number of packets sent during the last Direct TX test.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets);
+
+/**
+ * @brief Put the device in standby mode.
+ * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the
+ * device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode,
+ * the device can still wake up itself with the internal timer. But in standby mode, this timer is
+ * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command
+ * sent via SPI bus.
+ * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code
+ * ERR_COMMAND_DISALLOWED will be returned.
+ *
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_device_standby(void);
+
+/**
+ * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel.
+ * @note The frequency sine wave at the specific channel may be used for test purpose only.
+ * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc.
+ * This command shouldn't be used when normal Bluetooth activities are ongoing.
+ * The tone should be stopped by aci_hal_tone_stop() command.
+ *
+ * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the
+ * channel central frequency minus 250 kHz.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_tone_start(uint8_t rf_channel);
+
+/**
+ * This command is used to stop the previously started aci_hal_tone_start() command.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_tone_stop(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Config_vals Offsets and lengths for configuration values.
+ * @brief Offsets and lengths for configuration values.
+ * See aci_hal_write_config_data().
+ * @{
+ */
+
+/**
+ * @name Configuration values.
+ * See @ref aci_hal_write_config_data().
+ * @{
+ */
+#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */
+#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */
+#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */
+#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */
+#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host.
+ It can be written only if aci_hal_write_config_data() is the first command
+ after reset. */
+
+#define CONFIG_DATA_RANDOM_ADDRESS_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)
+ * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB)
+ * @li Mode 3: master only, 8 connections, RAM1 and RAM2.
+ */
+#define CONFIG_DATA_ROLE (0x2D)
+/**
+ * @}
+ */
+
+/**
+ * @name Length for configuration values.
+ * See @ref aci_hal_write_config_data().
+ * @{
+ */
+#define CONFIG_DATA_PUBADDR_LEN (6)
+#define CONFIG_DATA_DIV_LEN (2)
+#define CONFIG_DATA_ER_LEN (16)
+#define CONFIG_DATA_IR_LEN (16)
+#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1)
+#define CONFIG_DATA_ROLE_LEN (1)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#endif /* __BLUENRG_HAL_ACI_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_l2cap_aci.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_l2cap_aci.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,166 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name : bluenrg_l2cap_aci.h
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 26-Jun-2014
+* Description : Header file with L2CAP commands for BlueNRG FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_L2CAP_ACI_H__
+#define __BLUENRG_L2CAP_ACI_H__
+
+/**
+ *@addtogroup L2CAP L2CAP
+ *@brief L2CAP layer.
+ *@{
+ */
+
+/**
+ *@defgroup L2CAP_Functions L2CAP functions
+ *@brief API for L2CAP layer.
+ *@{
+ */
+
+/**
+ * @brief Send an L2CAP Connection Parameter Update request from the slave to the master.
+ * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request
+ * (accepts or rejects).
+ * @param conn_handle Connection handle on which the connection parameter update request has to be sent.
+ * @param interval_min Defines minimum value for the connection event interval in the following manner:
+ * connIntervalMin = interval_min x 1.25ms
+ * @param interval_max Defines maximum value for the connection event interval in the following manner:
+ * connIntervalMax = interval_max x 1.25ms
+ * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped).
+ * @param timeout_multiplier Defines connection timeout parameter in the following manner:
+ * timeout_multiplier x 10ms.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min,
+ uint16_t interval_max, uint16_t slave_latency,
+ uint16_t timeout_multiplier);
+/**
+ * @brief Accept or reject a connection update.
+ * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller.
+ * The accept parameter has to be set if the connection parameters given in the event are acceptable.
+ * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event.
+ * @param interval_min The connection interval parameter as received in the l2cap connection update request event
+ * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event.
+ * @param slave_latency The slave latency parameter as received in the l2cap connection update request event.
+ * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event.
+ * @param min_ce_length Minimum length of connection event needed for the LE connection.\n
+ * Range: 0x0000 - 0xFFFF\n
+ * Time = N x 0.625 msec.
+ * @param max_ce_length Maximum length of connection event needed for the LE connection.\n
+ * Range: 0x0000 - 0xFFFF\n
+ * Time = N x 0.625 msec.
+ * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event.
+ * @param accept @arg 0x00: The connection update parameters are not acceptable.
+ * @arg 0x01: The connection update parameters are acceptable.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min,
+ uint16_t interval_max, uint16_t slave_latency,
+ uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length,
+ uint8_t id, uint8_t accept);
+ /**
+ * @brief Accept or reject a connection update.
+ * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller.
+ * The accept parameter has to be set if the connection parameters given in the event are acceptable.
+ * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event.
+ * @param interval_min The connection interval parameter as received in the l2cap connection update request event
+ * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event.
+ * @param slave_latency The slave latency parameter as received in the l2cap connection update request event.
+ * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event.
+ * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event.
+ * @param accept @arg 0x00: The connection update parameters are not acceptable.
+ * @arg 0x01: The connection update parameters are acceptable.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min,
+ uint16_t interval_max, uint16_t slave_latency,
+ uint16_t timeout_multiplier, uint8_t id, uint8_t accept);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup L2CAP_Events L2CAP events
+ * @{
+ */
+
+/**
+ * This event is generated when the master responds to the L2CAP connection update request packet.
+ * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec.
+ */
+#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800)
+typedef __packed struct _evt_l2cap_conn_upd_resp{
+ uint16_t conn_handle; /**< The connection handle related to the event. */
+ uint8_t event_data_length; /**< Length of following data. */
+/**
+ * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet.
+ * @li 0x01 in case of Command Reject.
+ */
+ uint8_t code;
+ uint8_t identifier; /**< Identifier of the response. It is equal to the request. */
+ uint16_t l2cap_length; /**< Length of following data. It should always be 2 */
+/**
+ * Result code (parameters accepted or rejected) in case of Connection Parameter Update
+ * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01).
+ */
+ uint16_t result;
+} PACKED evt_l2cap_conn_upd_resp;
+
+/**
+ * This event is generated when the master does not respond to the connection update request
+ * within 30 seconds.
+ */
+#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801)
+typedef __packed struct _evt_l2cap_procedure_timeout{
+ uint16_t conn_handle; /**< The connection handle related to the event. */
+ uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */
+} PACKED evt_l2cap_procedure_timeout;
+
+/**
+ * The event is given by the L2CAP layer when a connection update request is received from the slave.
+ * The application has to respond by calling aci_l2cap_connection_parameter_update_response().
+ */
+#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802)
+typedef __packed struct _evt_l2cap_conn_upd_req{
+/**
+ * Handle of the connection for which the connection update request has been received.
+ * The same handle has to be returned while responding to the event with the command
+ * aci_l2cap_connection_parameter_update_response().
+ */
+ uint16_t conn_handle;
+ uint8_t event_data_length; /**< Length of following data. */
+/**
+ * This is the identifier which associates the request to the
+ * response. The same identifier has to be returned by the upper
+ * layer in the command aci_l2cap_connection_parameter_update_response().
+ */
+ uint8_t identifier;
+ uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */
+ uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */
+ uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */
+ uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */
+ uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */
+} PACKED evt_l2cap_conn_upd_req;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#endif /* __BLUENRG_L2CAP_ACI_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_updater_aci.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_updater_aci.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,78 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name : bluenrg_updater_aci.h
+* Author : AMS - HEA&RF BU
+* Version : V1.0.0
+* Date : 26-Jun-2014
+* Description : Header file with updater commands for BlueNRG FW6.3.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef __BLUENRG_UPDATER_ACI_H__
+#define __BLUENRG_UPDATER_ACI_H__
+
+#include <ble_compiler.h>
+
+/**
+ * @defgroup Updater Updater
+ * @brief Updater.
+ * @{
+ */
+
+/**
+ * @defgroup Updater_Functions Updater functions
+ * @brief API for BlueNRG Updater.
+ * @{
+ */
+
+tBleStatus aci_updater_start(void);
+
+tBleStatus aci_updater_reboot(void);
+
+tBleStatus aci_get_updater_version(uint8_t *version);
+
+tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size);
+
+tBleStatus aci_erase_blue_flag(void);
+
+tBleStatus aci_reset_blue_flag(void);
+
+tBleStatus aci_updater_erase_sector(uint32_t address);
+
+tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data);
+
+tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data);
+
+tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc);
+
+tBleStatus aci_updater_hw_version(uint8_t *version);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Updater_Events Updater events
+ * @{
+ */
+/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */
+#define EVT_BLUE_INITIALIZED (0x0001)
+typedef __packed struct _evt_blue_initialized{
+ uint8_t reason_code;
+} PACKED evt_blue_initialized;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+
+#endif /* __BLUENRG_UPDATER_ACI_H__ */
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_utils.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_utils.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,204 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name : bluenrg_utils.h
+* Author : AMS - VMA, RF Application Team
+* Version : V1.0.1
+* Date : 03-October-2014
+* Description : Header file for BlueNRG utility functions
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+/**
+ * @file bluenrg_utils.h
+ * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description
+ *
+ * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*-->
+**/
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __BLUENRG_UTILS_H
+#define __BLUENRG_UTILS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "ble_hal_types.h"
+#include "ble_compiler.h"
+
+/* Exported types ------------------------------------------------------------*/
+typedef struct{
+ uint8_t stack_mode;
+ uint8_t day;
+ uint8_t month;
+ uint8_t year;
+ uint16_t slave_sca_ppm;
+ uint8_t master_sca;
+ uint16_t hs_startup_time; /* In system time units*/
+} IFR_config2_TypeDef;
+
+/**
+ * Structure inside IFR for configuration options.
+ */
+typedef __packed struct{
+ uint8_t cold_ana_act_config_table[64];
+ uint8_t hot_ana_config_table[64];
+ uint8_t stack_mode;
+ uint8_t gpio_config;
+ uint8_t rsrvd1[2];
+ uint32_t rsrvd2[3];
+ uint32_t max_conn_event_time;
+ uint32_t ls_crystal_period;
+ uint32_t ls_crystal_freq;
+ uint16_t slave_sca_ppm;
+ uint8_t master_sca;
+ uint8_t rsrvd3;
+ uint16_t hs_startup_time; /* In system time units*/
+ uint8_t rsrvd4[2];
+ uint32_t uid;
+ uint8_t rsrvd5;
+ uint8_t year;
+ uint8_t month;
+ uint8_t day;
+ uint32_t unused[5];
+} PACKED IFR_config_TypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+extern const IFR_config_TypeDef IFR_config;
+
+/* Exported macros -----------------------------------------------------------*/
+#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414))
+#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414))
+
+/* Convert 2 digit BCD number to an integer */
+#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10)
+
+/* Convert 2 digit number to a BCD number */
+#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10)
+
+/**
+ * Return values
+ */
+#define BLE_UTIL_SUCCESS 0
+#define BLE_UTIL_UNSUPPORTED_VERSION 1
+#define BLE_UTIL_WRONG_IMAGE_SIZE 2
+#define BLE_UTIL_ACI_ERROR 3
+#define BLE_UTIL_CRC_ERROR 4
+#define BLE_UTIL_PARSE_ERROR 5
+#define BLE_UTIL_WRONG_VERIFY 6
+
+/* Exported functions ------------------------------------------------------- */
+/**
+ * @brief Flash a new firmware using internal bootloader.
+ * @param fw_image Pointer to the firmware image (raw binary data,
+ * little-endian).
+ * @param fw_size Size of the firmware image. The firmware image size shall
+ * be multiple of 4 bytes.
+ * @retval int It returns 0 if successful, or a number not equal to 0 in
+ * case of error (ACI_ERROR, UNSUPPORTED_VERSION,
+ * WRONG_IMAGE_SIZE, CRC_ERROR)
+ */
+int program_device(const uint8_t *fw_image, uint32_t fw_size);
+
+/**
+ * @brief Read raw data from IFR (3 64-bytes blocks).
+ * @param data Pointer to the buffer that will contain the read data.
+ * Its size must be 192 bytes. This data can be parsed by
+ * parse_IFR_data_config().
+ * @retval int It returns 0 if successful, or a number not equal to 0 in
+ * case of error (ACI_ERROR, UNSUPPORTED_VERSION)
+ */
+int read_IFR(uint8_t data[192]);
+
+/**
+ * @brief Verify raw data from IFR (3 64-bytes blocks).
+ * @param ifr_data Pointer to the buffer that will contain the data to verify.
+ * Its size must be 192 bytes.
+ * @retval int It returns 0 if successful, or a number not equal to 0 in
+ case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY)
+ */
+uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data);
+
+/**
+ * @brief Program raw data to IFR (3 64-bytes blocks).
+ * @param ifr_image Pointer to the buffer that will contain the data to program.
+ * Its size must be 192 bytes.
+ * @retval int It returns 0 if successful
+ */
+int program_IFR(const IFR_config_TypeDef *ifr_image);
+
+/**
+ * @brief Parse IFR raw data.
+ * @param data Pointer to the raw data: last 64 bytes read from IFR sector.
+ * @param IFR_config Data structure that will be filled with parsed data.
+ * @retval None
+ */
+void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config);
+
+/**
+ * @brief Check for the correctness of parsed data.
+ * @param IFR_config Data structure filled with parsed data.
+ * @retval int It returns 0 if successful, or PARSE_ERROR in case data is
+ * not correct.
+ */
+int IFR_validate(IFR_config2_TypeDef *IFR_config);
+
+/**
+ * @brief Modify IFR data. (Last 64-bytes block).
+ * @param IFR_config Structure that contains the new parameters inside the
+ * IFR configuration data.
+ * @note It is highly recommended to parse the IFR configuration from
+ * a working IFR block (this should be done with parse_IFR_data_config()).
+ * Then it is possible to write the new parameters inside the IFR_config
+ * structure.
+ * @param data Pointer to the buffer that contains the original data. It
+ * will be modified according to the new data in the IFR_config
+ * structure. Then this data must be written in the last
+ * 64-byte block in the IFR.
+ * Its size must be 64 bytes.
+ * @retval None
+ */
+void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]);
+
+/**
+ * @brief Get BlueNRG hardware and firmware version
+ * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31).
+ * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN
+ * where JJ = Major Version number, M = Minor Version number and N = Patch Version number.
+ * @retval Status of the call
+ */
+uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion);
+
+/**
+ * @brief Get BlueNRG updater version
+ * @param version This parameter returns the updater version. If the updadter version is 0x03
+ * the chip has the updater old, needs to update the bootloader.
+ * @retval Status of the call
+ */
+uint8_t getBlueNRGUpdaterVersion(uint8_t *version);
+
+/**
+ * @brief Get BlueNRG HW version in bootloader mode
+ * @param version This parameter returns the updater HW version.
+ * @retval Status of the call
+ */
+uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version);
+
+/**
+ * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on
+ * the HW bootloader related to the 32 MHz external crystal oscillator.
+ * @retval TRUE if the HW bootloader is already patched, FALSE otherwise
+ */
+uint8_t isHWBootloader_Patched(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__BLUENRG_UTILS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/platform/btle.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/platform/btle.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,61 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef _BTLE_H_
+#define _BTLE_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "ble_hci.h"
+#include "bluenrg_aci.h"
+#include "ble_hci_const.h"
+#include "bluenrg_hal_aci.h"
+#include "stm32_bluenrg_ble.h"
+#include "bluenrg_gap.h"
+#include "bluenrg_gatt_server.h"
+
+extern uint16_t g_gap_service_handle;
+extern uint16_t g_appearance_char_handle;
+extern uint16_t g_device_name_char_handle;
+extern uint16_t g_preferred_connection_parameters_char_handle;
+
+void btleInit(void);
+void SPI_Poll(void);
+void User_Process(void);
+void setConnectable(void);
+void setVersionString(uint8_t hwVersion, uint16_t fwVersion);
+const char* getVersionString(void);
+tBleStatus btleStartRadioScan(uint8_t scan_type,
+ uint16_t scan_interval,
+ uint16_t scan_window,
+ uint8_t own_address_type);
+
+
+extern int btle_handler_pending;
+extern void btle_handler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/platform/stm32_bluenrg_ble.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/platform/stm32_bluenrg_ble.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,104 @@
+/**
+ ******************************************************************************
+ * @file stm32_bluenrg_ble.h
+ * @author CL
+ * @version V1.0.1
+ * @date 15-June-2014
+ * @brief
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32_BLUENRG_BLE_H
+#define __STM32_BLUENRG_BLE_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#include <stdint.h>
+#include "ble_gp_timer.h"
+#include "ble_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup X-NUCLEO-IDB04A1
+ * @{
+ */
+
+/** @addtogroup STM32_BLUENRG_BLE
+ * @{
+ */
+
+/** @defgroup STM32_BLUENRG_BLE_Exported_Functions
+ * @{
+ */
+
+// FIXME: add prototypes for BlueNRG here
+void BlueNRG_RST(void);
+uint8_t BlueNRG_DataPresent(void);
+void BlueNRG_HW_Bootloader(void);
+int32_t BlueNRG_SPI_Read_All(uint8_t *buffer,
+ uint8_t buff_size);
+int32_t BlueNRG_SPI_Write(uint8_t* data1,
+ uint8_t* data2,
+ uint8_t Nb_bytes1,
+ uint8_t Nb_bytes2);
+void Clear_SPI_EXTI_Flag(void);
+
+void print_csv_time(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32_BLUENRG_BLE_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/utils/ble_payload.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/utils/ble_payload.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,195 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifdef YOTTA_CFG_MBED_OS
+ #include "mbed-drivers/mbed.h"
+#else
+ #include "mbed.h"
+#endif
+#include "ble_debug.h"
+
+#ifndef __PAYLOAD_H__
+#define __PAYLOAD_H__
+
+class UnitPayload
+{
+public:
+ uint8_t length;
+ uint8_t id;
+ uint8_t *data;
+ uint8_t *idptr;
+
+
+
+ void set_length(uint8_t l) {
+ length=l;
+ }
+
+ void set_id(uint8_t i) {
+ id=i;
+ }
+
+ void set_data(uint8_t* data1) {
+ for(int j=0;j<length;j++)
+ {
+ data[j]=data1[j];
+ }
+ }
+
+ uint8_t get_length() {
+ return length;
+ }
+
+ uint8_t get_id() {
+ return id;
+ }
+
+ uint8_t* get_data() {
+ return data;
+ }
+
+};
+
+class Payload {
+ UnitPayload *payload;
+ int stringLength;
+ int payloadUnitCount;
+
+public:
+ Payload(const uint8_t *tokenString, uint8_t string_ength);
+ Payload();
+ ~Payload();
+ uint8_t getPayloadUnitCount();
+
+ uint8_t getIDAtIndex(int index);
+ uint8_t getLengthAtIndex(int index);
+ uint8_t* getDataAtIndex(int index);
+ int8_t getInt8AtIndex(int index);
+ uint16_t getUint16AtIndex(int index);
+ uint8_t* getSerializedAdDataAtIndex(int index);
+};
+
+
+class PayloadUnit {
+private:
+ uint8_t* lenPtr;
+ uint8_t* adTypePtr;
+ uint8_t* dataPtr;
+
+public:
+ PayloadUnit() {
+ lenPtr = NULL;
+ adTypePtr = NULL;
+ dataPtr = NULL;
+ }
+
+ PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) {
+ lenPtr = len;
+ adTypePtr = adType;
+ dataPtr = data;
+ }
+
+ void setLenPtr(uint8_t *len) {
+ lenPtr = len;
+ }
+
+ void setAdTypePtr(uint8_t *adType) {
+ adTypePtr = adType;
+ }
+
+ void setDataPtr(uint8_t *data) {
+ dataPtr = data;
+ }
+
+ uint8_t* getLenPtr() {
+ return lenPtr;
+ }
+
+ uint8_t* getAdTypePtr() {
+ return adTypePtr;
+ }
+
+ uint8_t* getDataPtr() {
+ return dataPtr;
+ }
+
+ void printDataAsHex() {
+ int i = 0;
+ PRINTF("AdData=");
+ for(i=0; i<*lenPtr-1; i++) {
+ PRINTF("0x%x ", dataPtr[i]);
+ }
+ PRINTF("\n");
+ }
+
+ void printDataAsString() {
+ int i = 0;
+ PRINTF("AdData=");
+ for(i=0; i<*lenPtr-1; i++) {
+ PRINTF("%c", dataPtr[i]);
+ }
+ PRINTF("\n");
+ }
+
+};
+
+class PayloadPtr {
+private:
+ PayloadUnit *unit;
+ int payloadUnitCount;
+public:
+ PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) {
+ // initialize private data members
+ int stringLength = string_ength;
+ payloadUnitCount = 0;
+
+ int index = 0;
+ while(index!=stringLength) {
+ int len=tokenString[index];
+ index=index+1+len;
+ payloadUnitCount++;
+ }
+
+ // allocate memory to unit
+ unit = new PayloadUnit[payloadUnitCount];
+ int i = 0;
+ int nextUnitOffset = 0;
+
+ while(i<payloadUnitCount) {
+ unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset);
+ unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1);
+ unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2);
+
+ nextUnitOffset += *unit[i].getLenPtr()+1;
+ i++;
+
+ }
+ }
+
+ PayloadUnit getUnitAtIndex(int index) {
+ return unit[index];
+ }
+
+ int getPayloadUnitCount() { return payloadUnitCount; }
+
+ ~PayloadPtr() {
+ if(unit) delete[] unit;
+
+ unit = NULL;
+ }
+};
+
+#endif // __PAYLOAD_H__
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/utils/ble_utils.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/utils/ble_utils.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,46 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+// utility functions
+
+#ifndef __UTIL_H__
+#define __UTIL_H__
+
+#include "ble_status.h"
+#include "ble_hal_types.h"
+
+#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \
+ ((buf)[1] = (uint8_t) (val>>8) ) )
+
+#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \
+ ((buf)[1] = (uint8_t) (val>>8) ) , \
+ ((buf)[2] = (uint8_t) (val>>16) ) , \
+ ((buf)[3] = (uint8_t) (val>>24) ) )
+
+#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \
+ do {\
+ uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \
+ uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \
+ uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \
+ uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \
+ }while(0)
+
+
+tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL);
+
+#endif // __UTIL_H__
+
diff -r 000000000000 -r 1eec8720727a shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/x_nucleo_idb0xa1_targets.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/x-nucleo-idb0xa1/x_nucleo_idb0xa1_targets.h Mon Jan 16 14:16:03 2017 +0000 @@ -0,0 +1,75 @@ +/** + ****************************************************************************** + * @file x_nucleo_idb0xa1_targets.h + * @author AST / EST + * @version V0.0.1 + * @date 24-July-2015 + * @brief This header file is intended to manage the differences between + * the different supported base-boards which might mount the + * X_NUCLEO_IDB0XA1 BlueNRG BLE Expansion Board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent from recursive inclusion --------------------------------*/ +#ifndef _X_NUCLEO_IDB0XA1_TARGETS_H_ +#define _X_NUCLEO_IDB0XA1_TARGETS_H_ + +/*** SPI ***/ +/* Use Arduino I2C Connectors */ +#define IDB0XA1_PIN_SPI_MOSI (D11) +#define IDB0XA1_PIN_SPI_MISO (D12) +#define IDB0XA1_PIN_SPI_nCS (A1) +#define IDB0XA1_PIN_SPI_RESET (D7) +#define IDB0XA1_PIN_SPI_IRQ (A0) + +/* NOTE: Define macro 'IDB0XA1_D13_PATCH' if you want to compile for a specifically + modified version of the X_NUCLEO_IDB0XA1 expansion board in + which pin 'D13' (rather than the standard pin 'D3') is used + in order to provide the SPI serial clock. + Expansion boards modified in this way allow to be used on almost + any Arduino-compliant base board. +*/ +#if defined(IDB0XA1_D13_PATCH) +#define IDB0XA1_PIN_SPI_SCK (D13) +#else // !defined(IDB0XA1_D13_PATCH) +#define IDB0XA1_PIN_SPI_SCK (D3) +#endif // !defined(IDB0XA1_D13_PATCH) + +/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv) + Define macro 'SSADV' to enable it +*/ +#define SSADV +#if defined(SSADV) +#define IDB0XA1_STACK_MODE (0x04) +#else +#define IDB0XA1_STACK_MODE (0x02) +#endif + +#endif // _X_NUCLEO_IDB0XA1_TARGETS_H_
diff -r 000000000000 -r 1eec8720727a source/DOORService.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/DOORService.h Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,42 @@
+/* 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 __BLE_DOOR_SERVICE_H__
+#define __BLE_DOOR_SERVICE_H__
+
+class DOORService {
+public:
+ const static uint16_t DOOR_SERVICE_UUID = 0xA000;
+ const static uint16_t DOOR_STATE_CHARACTERISTIC_UUID = 0xA001 ;
+
+ DOORService(BLEDevice &_ble, uint8_t initialValueForDOORCharacteristic):
+ ble(_ble), doorState(DOOR_STATE_CHARACTERISTIC_UUID, &initialValueForDOORCharacteristic)
+ {
+ GattCharacteristic *charTable[] = {&doorState};
+ GattService doorCTL_Service(DOOR_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+ ble.addService(doorCTL_Service);
+ }
+
+ GattAttribute::Handle_t getValueHandle() const {
+ return doorState.getValueHandle();
+ }
+
+private:
+ BLEDevice &ble;
+ ReadWriteGattCharacteristic<uint8_t> doorState;
+};
+
+#endif /* #ifndef __BLE_LED_SERVICE_H__ */
diff -r 000000000000 -r 1eec8720727a source/main.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/main.cpp Mon Jan 16 14:16:03 2017 +0000
@@ -0,0 +1,198 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2014 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <events/mbed_events.h>
+#include <mbed.h>
+#include "ble/BLE.h"
+#include "ble/Gap.h"
+#include "ble/services/BatteryService.h"
+#include "DOORService.h"
+
+//DigitalOut led1(LED1, 1);
+
+const static char DEVICE_NAME[] = "DOORCTL";
+static const uint16_t uuid16_list[] = {DOORService::DOOR_SERVICE_UUID};
+
+
+uint8_t BLE_RX_CMD = 0xFF;
+uint8_t doorStatusPayload[2] = {0xFF,};
+
+DigitalOut relay1(D7); // Relay 1
+DigitalOut relay2(D6); // Relay 2
+DigitalOut relay3(D5); // Relay 3
+DigitalOut relay4(D4); // Relay 4
+
+BLEDevice ble;
+
+
+static DOORService *doorServicePtr;
+static EventQueue eventQueue(
+ /* event count */ 16 * /* event size */ 32
+);
+
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
+{
+ BLE::Instance().gap().startAdvertising();
+}
+
+
+
+void onDataWrittenCallback(const GattWriteCallbackParams *params) {
+
+
+ if ((params->handle == doorServicePtr->getValueHandle()) && (params->len == 1)) {
+ {
+ BLE_RX_CMD = *(params->data);
+ }
+ }
+}
+
+void cmd_thread(void const *args) {
+ while (true) {
+ switch (BLE_RX_CMD)
+ {
+ case 0x00:
+ relay1 = 1;
+ relay2 = 0;
+ relay3 = 0;
+ relay4 = 0;
+ // Thread::wait(500);
+ doorStatusPayload[0]=0xF0;
+ break;
+
+ case 0x01:
+ relay1 = 0;
+ relay2 = 1;
+ relay3 = 0;
+ relay4 = 0;
+ //Thread::wait(500);
+ doorStatusPayload[0]=0xF1;
+ break;
+
+ case 0x02:
+ relay1 = 0;
+ relay2 = 0;
+ relay3 = 1;
+ relay4 = 0;
+ //Thread::wait(500);
+ doorStatusPayload[0]=0xF2;
+ break;
+
+ case 0x03:
+ relay1 = 0;
+ relay2 = 0;
+ relay3 = 0;
+ relay4 = 1;
+ //Thread::wait(500);
+ doorStatusPayload[0]=0xF3;
+ break;
+
+ case 0x04:
+ relay1 = 0;
+ relay2 = 0;
+ relay3 = 0;
+ relay4 = 0;
+ //Thread::wait(500);
+ doorStatusPayload[0]=0xF4;
+ break;
+
+ case 0x05: //Test Mode!!
+ relay1 = 1;
+ relay2 = 1;
+ relay3 = 1;
+ relay4 = 1;
+ //Thread::wait(500);
+ doorStatusPayload[0]=0xF5;
+ break;
+
+
+ default:
+ break;
+ }
+ if (ble.getGapState().connected) {
+ ble.updateCharacteristicValue((doorServicePtr->getValueHandle()),doorStatusPayload, 1);
+ }
+ }
+}
+
+
+
+/**
+ * This function is called when the ble initialization process has failled
+ */
+void onBleInitError(BLE &ble, ble_error_t error)
+{
+ /* Initialization error handling should go here */
+}
+
+/**
+ * Callback triggered when the ble initialization process has finished
+ */
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
+{
+ BLE& ble = params->ble;
+ ble_error_t error = params->error;
+
+ if (error != BLE_ERROR_NONE) {
+ /* In case of error, forward the error handling to onBleInitError */
+ onBleInitError(ble, error);
+ return;
+ }
+
+ /* Ensure that it is the default instance of BLE */
+ if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
+ return;
+ }
+
+ ble.gap().onDisconnection(disconnectionCallback);
+ ble.gattServer().onDataWritten(onDataWrittenCallback);
+
+ /* Setup primary services */
+ uint8_t initialValueForDOORCharacteristic = 0xFF;
+ doorServicePtr = new DOORService(ble, initialValueForDOORCharacteristic);
+
+ /* Setup advertising */
+ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *) uuid16_list, sizeof(uuid16_list));
+ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *) DEVICE_NAME, sizeof(DEVICE_NAME));
+ ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+ ble.gap().setAdvertisingInterval(1000); /* 1000ms */
+ ble.gap().startAdvertising();
+}
+
+void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
+ BLE &ble = BLE::Instance();
+ eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
+}
+
+int main()
+{
+ relay1 = 0;
+ relay2 = 0;
+ relay3 = 0;
+ relay4 = 0;
+
+ BLE &ble = BLE::Instance();
+ ble.onEventsToProcess(scheduleBleEventsProcessing);
+ ble.init(bleInitComplete);
+
+ Thread thread0(cmd_thread,(void *)"DOORCTL");
+
+ eventQueue.dispatch_forever();
+
+
+ return 0;
+}