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.
Fork of X_NUCLEO_IDB0XA1 by
Revision 130:770ce14d3d15, committed 2015-10-06
- Comitter:
- Wolfgang Betz
- Date:
- Tue Oct 06 14:25:08 2015 +0200
- Parent:
- 129:d5686dd11391
- Child:
- 131:e09947216ccb
- Commit message:
- Include mbed-classic version
Derived from
- repo (on Codex): gitolite@codex.cro.st.com:x-nucleodev/X-NUCLEO-IKC01A1-MBED.git
- branch: ble_wb
- SHA1 ID: 5ccc73e35868169e42132c0d1c056f908a6d70c0
Changed in this revision
--- a/module.json Tue Oct 06 13:59:23 2015 +0200
+++ b/module.json Tue Oct 06 14:25:08 2015 +0200
@@ -18,5 +18,14 @@
"type": "Apache-2.0"
}
],
- "dependencies": {}
+ "extraIncludes": [
+ "x-nucleo-idb0xa1",
+ "x-nucleo-idb0xa1/BlueNRG_HCI/include",
+ "x-nucleo-idb0xa1/x-nucleo-idb0xa1/platform/inc",
+ "x-nucleo-idb0xa1/x-nucleo-idb0xa1/platform/X-NUCLEO-IDB04A1",
+ "x-nucleo-idb0xa1/x-nucleo-idb0xa1/utils/inc"
+ ],
+ "dependencies": {
+ "ble": "*"
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRGDevice.cpp Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,400 @@
+/* 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
+ * @{
+ */
+
+#include "mbed.h"
+#include "BlueNRGDevice.h"
+#include "BlueNRGGap.h"
+#include "BlueNRGGattServer.h"
+
+#include "btle.h"
+#include "Utils.h"
+#include "osal.h"
+
+#include "debug.h"
+#include "stm32_bluenrg_ble.h"
+
+extern "C" {
+ #include "hci.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) : spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq)
+{
+ isInitialized = false;
+
+ // 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);
+}
+
+/**************************************************************************/
+/**
+ @brief Destructor
+*/
+/**************************************************************************/
+BlueNRGDevice::~BlueNRGDevice(void)
+{
+}
+
+
+/**
+ @brief Initialises anything required to start using BLE
+ @param[in] void
+ @returns ble_error_t
+*/
+ble_error_t BlueNRGDevice::init(void)
+{
+ // Set the interrupt handler for the device
+ irq_.mode(PullNone); // betzw: set irq mode
+ irq_.rise(&HCI_Isr);
+
+ /* ToDo: Clear memory contents, reset the SD, etc. */
+ btle_init(BlueNRGGap::getInstance().getIsSetAddress());
+
+ isInitialized = true;
+
+ return BLE_ERROR_NONE;
+}
+
+
+/**
+ @brief Resets the BLE HW, removing any existing services and
+ characteristics
+ @param[in] void
+ @returns ble_error_t
+*/
+ble_error_t 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);
+
+ isInitialized = false;
+
+ return BLE_ERROR_NONE;
+}
+
+
+/*!
+ @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 {
+ BlueNRGGap::getInstance().Process();
+
+ HCI_Process();
+
+ 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
+ @param[in] void
+ @returns char *
+*/
+const char *BlueNRGDevice::getVersion(void)
+{
+ char *version = new char[6];
+ memcpy((void *)version, "1.0.0", 5);
+ return version;
+}
+
+/**************************************************************************/
+/*!
+ @brief get init state
+ @param[in] void
+ @returns bool
+*/
+/**************************************************************************/
+bool BlueNRGDevice::getIsInitialized(void)
+{
+ return isInitialized;
+}
+
+/**************************************************************************/
+/*!
+ @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 the BLE device
+ @param[out] error if any
+*/
+/**************************************************************************/
+ble_error_t BlueNRGDevice::shutdown(void) {
+ return reset();
+}
+
+/**
+ * @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();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRGGap.cpp Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,999 @@
+/* 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>
+ */
+
+// ANDREA: Changed some types (e.g., tHalUint8 --> uint8_t)
+
+/** @defgroup BlueNRGGap
+ * @brief BlueNRG BLE_API GAP Adaptation
+ * @{
+ */
+
+#include "BlueNRGDevice.h"
+#include "mbed.h"
+#include "Payload.h"
+#include "Utils.h"
+
+//Local Variables
+//const char *local_name = NULL;
+//uint8_t local_name_length = 0;
+const uint8_t *scan_response_payload = NULL;
+uint8_t scan_rsp_length = 0;
+
+uint32_t advtInterval = BLUENRG_GAP_ADV_INTERVAL_MAX;
+
+/*
+ * 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)
+{
+ DEBUG("BlueNRGGap::setAdvertisingData\n\r");
+ /* Make sure we don't exceed the advertising payload length */
+ if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
+ return BLE_ERROR_BUFFER_OVERFLOW;
+ }
+
+ /* Make sure we have a payload! */
+ if (advData.getPayloadLen() <= 0) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ } else {
+ PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen());
+ for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) {
+ loadPtr.getUnitAtIndex(index);
+
+ DEBUG("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr()));
+ DEBUG("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()));
+
+ switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) {
+ case GapAdvertisingData::FLAGS: /* ref *Flags */
+ {
+ DEBUG("Advertising type: FLAGS\n\r");
+ //Check if Flags are OK. BlueNRG only supports LE Mode.
+ uint8_t *flags = loadPtr.getUnitAtIndex(index).getDataPtr();
+ if((*flags & GapAdvertisingData::BREDR_NOT_SUPPORTED) != GapAdvertisingData::BREDR_NOT_SUPPORTED) {
+ DEBUG("BlueNRG does not support BR/EDR Mode");
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ break;
+ }
+ case GapAdvertisingData::INCOMPLETE_LIST_16BIT_SERVICE_IDS: /**< Incomplete list of 16-bit Service IDs */
+ case GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS: /**< Complete list of 16-bit Service IDs */
+ {
+ DEBUG("Advertising type: INCOMPLETE_LIST_16BIT_SERVICE_IDS/COMPLETE_LIST_16BIT_SERVICE_IDS\n\r");
+
+ uint8_t buffSize = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;
+ // The total lenght should include the Data Type Value
+ if(buffSize>UUID_BUFFER_SIZE-1) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ servUuidlength = buffSize+1; // +1 to include the Data Type Value
+ servUuidData[0] = (uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()); //Data Type Value
+
+ DEBUG("servUuidlength=%d servUuidData[0]=%d buffSize=%d\n\r", servUuidlength, servUuidData[0], buffSize);
+ // Save the Service UUID list just after the Data Type Value field
+ memcpy(servUuidData+1, loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize);
+
+ for(unsigned i=0; i<servUuidlength; i++) {
+ DEBUG("servUuidData[%d] = 0x%x\n\r", i, servUuidData[i]);
+ }
+
+ for(unsigned i=0; i<buffSize; i++) {
+ DEBUG("loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r", i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
+ }
+
+ break;
+ }
+ case GapAdvertisingData::INCOMPLETE_LIST_32BIT_SERVICE_IDS: /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
+ {
+ DEBUG("Advertising type: INCOMPLETE_LIST_32BIT_SERVICE_IDS\n\r");
+ return BLE_ERROR_NOT_IMPLEMENTED;
+ }
+ case GapAdvertisingData::COMPLETE_LIST_32BIT_SERVICE_IDS: /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
+ {
+ DEBUG("Advertising type: COMPLETE_LIST_32BIT_SERVICE_IDS\n\r");
+ return BLE_ERROR_NOT_IMPLEMENTED;
+ }
+ case GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS: /**< Incomplete list of 128-bit Service IDs */
+ {
+ DEBUG("Advertising type: INCOMPLETE_LIST_128BIT_SERVICE_IDS\n\r");
+ return BLE_ERROR_NOT_IMPLEMENTED;
+ }
+ case GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS: /**< Complete list of 128-bit Service IDs */
+ {
+ DEBUG("Advertising type: COMPLETE_LIST_128BIT_SERVICE_IDS\n\r");
+ return BLE_ERROR_NOT_IMPLEMENTED;
+ }
+ case GapAdvertisingData::SHORTENED_LOCAL_NAME: /**< Shortened Local Name */
+ {
+ break;
+ }
+ case GapAdvertisingData::COMPLETE_LOCAL_NAME: /**< Complete Local Name */
+ {
+ DEBUG("Advertising type: COMPLETE_LOCAL_NAME\n\r");
+ loadPtr.getUnitAtIndex(index).printDataAsString();
+ local_name_length = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;
+ local_name = (uint8_t*)loadPtr.getUnitAtIndex(index).getAdTypePtr();
+ DEBUG("Advertising type: COMPLETE_LOCAL_NAME local_name=%s\n\r", local_name);
+ //COMPLETE_LOCAL_NAME is only advertising device name. Gatt Device Name is not the same.(Must be set right after GAP/GATT init?)
+
+ DEBUG("device_name length=%d\n\r", local_name_length);
+ break;
+ }
+ case GapAdvertisingData::TX_POWER_LEVEL: /**< TX Power Level (in dBm) */
+ {
+ DEBUG("Advertising type: TX_POWER_LEVEL\n\r");
+ int8_t enHighPower = 0;
+ int8_t paLevel = 0;
+#if NEED_CONSOLE_OUTPUT
+ int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr();
+ int8_t dbmActuallySet = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel);
+#endif
+ DEBUG("dbm=%d, dbmActuallySet=%d\n\r", dbm, dbmActuallySet);
+ DEBUG("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);
+ aci_hal_set_tx_power_level(enHighPower, paLevel);
+ break;
+ }
+ case GapAdvertisingData::DEVICE_ID: /**< Device ID */
+ {
+ break;
+ }
+ case GapAdvertisingData::SLAVE_CONNECTION_INTERVAL_RANGE: /**< Slave :Connection Interval Range */
+ {
+ break;
+ }
+ case GapAdvertisingData::SERVICE_DATA: /**< Service Data */
+ {
+ DEBUG("Advertising type: SERVICE_DATA\n\r");
+ uint8_t buffSize = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;
+ DEBUG("Advertising type: SERVICE_DATA (buffSize=%d)\n\r", buffSize);
+ // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Service Data Type Value byte
+ if(buffSize>ADV_DATA_MAX_SIZE-2) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+ for(int i=0; i<buffSize+1; i++) {
+ DEBUG("Advertising type: SERVICE_DATA loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r", i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
+ }
+ AdvLen = buffSize+2; // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Service Data Type Value byte
+ AdvData[0] = buffSize+1; // the fisrt byte is the data buffer size (type+data)
+ AdvData[1] = AD_TYPE_SERVICE_DATA;
+ memcpy(AdvData+2, loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize);
+ break;
+ }
+ case GapAdvertisingData::APPEARANCE:
+ {
+ /*
+ Tested with GapAdvertisingData::GENERIC_PHONE.
+ for other appearances BLE Scanner android app is not behaving properly
+ */
+ DEBUG("Advertising type: APPEARANCE\n\r");
+ const char *deviceAppearance = NULL;
+ deviceAppearance = (const char*)loadPtr.getUnitAtIndex(index).getDataPtr(); // to be set later when startAdvertising() is called
+
+#if NEED_CONSOLE_OUTPUT
+ uint8_t Appearance[2] = {0, 0};
+ uint16_t devP = (uint16_t)*deviceAppearance;
+ STORE_LE_16(Appearance, (uint16_t)devP);
+#endif
+
+ DEBUG("input: deviceAppearance= 0x%x 0x%x..., strlen(deviceAppearance)=%d\n\r", Appearance[1], Appearance[0], (uint8_t)*loadPtr.getUnitAtIndex(index).getLenPtr()-1); /**< \ref Appearance */
+
+ aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (uint8_t *)deviceAppearance);//not using array Appearance[2]
+ break;
+ }
+ case GapAdvertisingData::ADVERTISING_INTERVAL: /**< Advertising Interval */
+ {
+ DEBUG("Advertising type: ADVERTISING_INTERVAL\n\r");
+ advtInterval = (uint16_t)(*loadPtr.getUnitAtIndex(index).getDataPtr());
+ DEBUG("advtInterval=%d\n\r", advtInterval);
+ break;
+ }
+ case GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA: /**< Manufacturer Specific Data */
+ {
+ break;
+ }
+
+ }
+ }
+ //Set the SCAN_RSP Payload
+ scan_response_payload = scanResponse.getPayload();
+ scan_rsp_length = scanResponse.getPayloadLen();
+ }
+ return BLE_ERROR_NONE;
+}
+
+/*
+ * Utility to set ADV timeout flag
+ */
+void BlueNRGGap::setAdvToFlag(void) {
+ AdvToFlag = true;
+}
+
+/*
+ * ADV timeout callback
+ */
+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 */
+
+ }
+}
+
+
+/**************************************************************************/
+/*!
+ @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)
+{
+ /* Make sure we support the advertising type */
+ if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
+ /* ToDo: This requires a propery 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;
+ }
+
+ //tBleStatus ret;
+ //const LongUUIDBytes_t HRM_SERVICE_UUID_128 = {0x18, 0x0D};
+ /* set scan response data */
+ hci_le_set_scan_resp_data(scan_rsp_length, scan_response_payload); /*int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]);*/
+
+ /*aci_gap_set_discoverable(Advertising_Event_Type, Adv_min_intvl, Adv_Max_Intvl, Addr_Type, Adv_Filter_Policy,
+ Local_Name_Length, local_name, service_uuid_length, service_uuid_list, Slave_conn_intvl_min, Slave_conn_intvl_max);*/
+ /*LINK_LAYER.H DESCRIBES THE ADVERTISING TYPES*/
+
+ char* name = NULL;
+ uint8_t nameLen = 0;
+ if(local_name!=NULL) {
+ name = (char*)local_name;
+ DEBUG("name=%s\n\r", name);
+ nameLen = local_name_length;
+ } else {
+ char str[] = "ST_BLE_DEV";
+ name = new char[strlen(str)+1];
+ name[0] = AD_TYPE_COMPLETE_LOCAL_NAME;
+ strcpy(name+1, str);
+ nameLen = strlen(name);
+ DEBUG("nameLen=%d\n\r", nameLen);
+ DEBUG("name=%s\n\r", name);
+ }
+
+ advtInterval = params.getIntervalInADVUnits(); // set advtInterval in case it is not already set by user application
+ ret = aci_gap_set_discoverable(params.getAdvertisingType(), // Advertising_Event_Type
+ advtInterval, // Adv_Interval_Min
+ advtInterval, // Adv_Interval_Max
+ PUBLIC_ADDR, // Address_Type
+ NO_WHITE_LIST_USE, // Adv_Filter_Policy
+ nameLen, //local_name_length, // Local_Name_Length
+ (const char*)name, //local_name, // Local_Name
+ servUuidlength, //Service_Uuid_Length
+ servUuidData, //Service_Uuid_List
+ 0, // Slave_Conn_Interval_Min
+ 0); // Slave_Conn_Interval_Max
+
+
+ DEBUG("!!!setting discoverable (servUuidlength=0x%x)\n", servUuidlength);
+ if(BLE_STATUS_SUCCESS!=ret) {
+ DEBUG("error occurred while setting discoverable (ret=0x%x)\n", ret);
+ return BLE_ERROR_PARAM_OUT_OF_RANGE; // no other suitable error code is available
+ }
+
+ // Before updating the ADV data, delete COMPLETE_LOCAL_NAME and TX_POWER_LEVEL fields (if present)
+ if(AdvLen>0) {
+ if(name!=NULL) {
+ DEBUG("!!!calling aci_gap_delete_ad_type AD_TYPE_COMPLETE_LOCAL_NAME!!!\n");
+ ret = aci_gap_delete_ad_type(AD_TYPE_COMPLETE_LOCAL_NAME);
+ if (ret != BLE_STATUS_SUCCESS){
+ DEBUG("aci_gap_delete_ad_type failed return=%d\n", ret);
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+ }
+
+ if(txPowerAdType) {
+ DEBUG("!!!calling aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL)!!!\n", AdvLen);
+ ret = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL);
+ if (ret != BLE_STATUS_SUCCESS){
+ DEBUG("aci_gap_delete_ad_type failed return=%d\n", ret);
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+ }
+
+ ret = aci_gap_update_adv_data(AdvLen, AdvData);
+ if(BLE_STATUS_SUCCESS!=ret) {
+ DEBUG("error occurred while adding adv data (ret=0x%x)\n", ret);
+ return BLE_ERROR_PARAM_OUT_OF_RANGE; // no other suitable error code is available
+ }
+
+ }
+
+ state.advertising = 1;
+
+ AdvToFlag = false;
+ if(params.getTimeout() != 0) {
+ DEBUG("!!! attaching to!!!\n");
+ advTimeout.attach(advTimeoutCB, params.getTimeout());
+ }
+
+ 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)
+{
+ tBleStatus ret;
+
+ if(state.advertising == 1) {
+ //Set non-discoverable to stop advertising
+ ret = aci_gap_set_non_discoverable();
+
+ if (ret != BLE_STATUS_SUCCESS){
+ DEBUG("Error in stopping advertisement (ret=0x%x)!!\n\r", ret) ;
+ return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value
+ //FIXME: Define Error values equivalent to BlueNRG Error Codes.
+ }
+ DEBUG("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(Gap::DisconnectionReason_t reason)
+{
+ tBleStatus ret;
+ //For Reason codes check BlueTooth HCI Spec
+
+ if(m_connectionHandle != BLE_CONN_HANDLE_INVALID) {
+ ret = aci_gap_terminate(m_connectionHandle, 0x16);//0x16 Connection Terminated by Local Host.
+
+ if (ret != BLE_STATUS_SUCCESS){
+ DEBUG("Error in GAP termination!!\n\r") ;
+ return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value
+ //FIXME: Define Error values equivalent to BlueNRG Error Codes.
+ }
+
+ //DEBUG("Disconnected from localhost!!\n\r") ;
+ m_connectionHandle = BLE_CONN_HANDLE_INVALID;
+ }
+
+ 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;
+ //For Reason codes check BlueTooth HCI Spec
+
+ if(connectionHandle != BLE_CONN_HANDLE_INVALID) {
+ ret = aci_gap_terminate(connectionHandle, 0x16);//0x16 Connection Terminated by Local Host.
+
+ if (ret != BLE_STATUS_SUCCESS){
+ DEBUG("Error in GAP termination!!\n\r") ;
+ return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value
+ //FIXME: Define Error values equivalent to BlueNRG Error Codes.
+ }
+
+ //DEBUG("Disconnected from localhost!!\n\r") ;
+ m_connectionHandle = BLE_CONN_HANDLE_INVALID;
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Sets the 16-bit connection handle
+
+ @param[in] con_handle
+ Connection Handle which is set in the Gap Instance
+
+ @returns void
+*/
+/**************************************************************************/
+void BlueNRGGap::setConnectionHandle(uint16_t con_handle)
+{
+ m_connectionHandle = con_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(addr_type_t type, const Address_t address)
+{
+ //tBleStatus ret;
+
+ if (type > ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ //copy address to bdAddr[6]
+ for(int i=0; i<BDADDR_SIZE; i++) {
+ bdaddr[i] = address[i];
+ //DEBUG("i[%d]:0x%x\n\r",i,bdaddr[i]);
+ }
+
+ if(!isSetAddress) isSetAddress = true;
+
+ //Re-Init the BTLE Device with SetAddress as true
+ //if(BlueNRGDevice::getIsInitialized())//Re-init only initialization is already done
+ // ANDREA
+ //btle_init(isSetAddress, D11, D12, D3);
+
+ //if (ret==BLE_STATUS_SUCCESS)
+ 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(AddressType_t *typeP, Address_t address)
+{
+ *typeP = Gap::ADDR_TYPE_PUBLIC;
+
+ if(isSetAddress)
+ {
+ for(int i=0; i<BDADDR_SIZE; i++) {
+ address[i] = bdaddr[i];
+ //DEBUG("i[%d]:0x%x\n\r",i,bdaddr[i]);
+ }
+ }
+
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ int ret;
+ uint8_t nameLen = 0;
+
+ DeviceName = (uint8_t *)deviceName;
+ //DEBUG("SetDeviceName=%s\n\r", DeviceName);
+
+ nameLen = strlen((const char*)DeviceName);
+ //DEBUG("DeviceName Size=%d\n\r", nameLen);
+
+ ret = aci_gatt_update_char_value(g_gap_service_handle,
+ g_device_name_char_handle,
+ 0,
+ nameLen,
+ (uint8_t *)DeviceName);
+
+ if(ret){
+ DEBUG("device set name failed\n\r");
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;//TODO:Wrong error code
+ }
+
+ 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)
+{
+ //int ret;
+
+ if(DeviceName==NULL)
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+
+ strcpy((char*)deviceName, (const char*)DeviceName);
+ //DEBUG("GetDeviceName=%s\n\r", deviceName);
+
+ *lengthP = strlen((const char*)DeviceName);
+ //DEBUG("DeviceName Size=%d\n\r", *lengthP);
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @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)
+{
+ /*
+ Tested with GapAdvertisingData::GENERIC_PHONE.
+ for other appearances BLE Scanner android app is not behaving properly
+ */
+ //char deviceAppearance[2];
+ STORE_LE_16(deviceAppearance, appearance);
+ DEBUG("input: incoming = %d deviceAppearance= 0x%x 0x%x\n\r", appearance, deviceAppearance[1], deviceAppearance[0]);
+
+ aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (uint8_t *)deviceAppearance);
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @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)
+{
+ uint16_t devP;
+ if(!appearanceP) return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ devP = ((uint16_t)(0x0000|deviceAppearance[0])) | (((uint16_t)(0x0000|deviceAppearance[1]))<<8);
+ strcpy((char*)appearanceP, (const char*)&devP);
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Gets the value of maximum advertising interval in ms
+
+ @returns uint16_t
+
+ @retval value of maximum advertising interval in ms
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+uint16_t BlueNRGGap::getMaxAdvertisingInterval(void) const {
+ return advtInterval;
+}
+
+
+/**************************************************************************/
+/*!
+ @brief Gets the value of minimum advertising interval in ms
+
+ @returns uint16_t
+
+ @retval value of minimum advertising interval in ms
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+uint16_t BlueNRGGap::getMinAdvertisingInterval(void) const {
+ return 0; // minimum Advertising interval is 0
+}
+
+/**************************************************************************/
+/*!
+ @brief Gets the value of minimum non connectable advertising interval in ms
+
+ @returns uint16_t
+
+ @retval value of minimum non connectable advertising interval in ms
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+uint16_t BlueNRGGap::getMinNonConnectableAdvertisingInterval(void) const {
+ return BLE_GAP_ADV_NONCON_INTERVAL_MIN;
+}
+
+// ANDREA
+ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) {
+ // Empty by now
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGap::stopScan() {
+ // Empty by now
+ 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;
+#if NEED_CONSOLE_OUTPUT
+ int8_t dbmActuallySet = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel);
+#endif
+
+ DEBUG("txPower=%d, dbmActuallySet=%d\n\r", txPower, dbmActuallySet);
+ DEBUG("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_UNSPECIFIED;
+ }
+
+ txPowerAdType = true;
+ 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, -14, -11, -8, -4, -1, 1, 5, -15, -11, -8, -5, -2, 1, 4, 8
+ };
+
+ *valueArrayPP = permittedTxValues;
+ *countP = sizeof(permittedTxValues) / sizeof(int8_t);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRGGattServer.cpp Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,443 @@
+/* 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>
+ */
+
+
+// ANDREA: Changed some types (e.g., tHalUint8 --> uint8_t)
+
+/** @defgroup BlueNRGGATTSERVER
+ * @brief BlueNRG BLE_API GattServer Adaptation
+ * @{
+ */
+
+#include "BlueNRGGattServer.h"
+#include "mbed.h"
+#include "BlueNRGGap.h"
+#include "Utils.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 = 0;
+ uint8_t maxAttrRecords = 0;
+
+ type = (service.getUUID()).shortOrLong();
+ DEBUG("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],base_uuid[13],base_uuid[12],base_uuid[11],base_uuid[10],base_uuid[9],
+ base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],primary_short_uuid[1],primary_short_uuid[0],base_uuid[1],base_uuid[0]);
+ }
+
+ charsCount = service.getCharacteristicCount();
+ //1(service record)+2records*char+1record*char_desc
+ maxAttrRecords = 1+3*charsCount;
+
+ if(type==UUID::UUID_TYPE_SHORT) {
+ ret = aci_gatt_add_serv(UUID_TYPE_16,
+ primary_short_uuid,
+ PRIMARY_SERVICE,
+ maxAttrRecords/*7*/,
+ &servHandle);
+ DEBUG("aci_gatt_add_serv UUID_TYPE_LONG 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);
+ DEBUG("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret);
+ }
+
+ service.setHandle(servHandle);
+ //serviceHandleVector.push_back(servHandle);
+ DEBUG("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);
+
+ if(type==UUID::UUID_TYPE_LONG) {
+ base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID();
+
+ COPY_UUID_128(char_base_uuid, base_char_uuid[15],base_char_uuid[14],base_char_uuid[13],base_char_uuid[12],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],int_8_uuid[1],int_8_uuid[0],base_char_uuid[1],base_char_uuid[0]);
+ }
+
+ DEBUG("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))) {
+ DEBUG("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r");
+ Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE;
+ }
+ if((p_char->getProperties() &
+ (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ|
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) {
+ DEBUG("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);
+
+ DEBUG("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);
+
+ DEBUG("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
+ }
+
+ /* Update the characteristic handle */
+ //uint16_t charHandle = characteristicCount;
+
+ bleCharHanldeMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle));
+
+ p_characteristics[characteristicCount++] = p_char;
+ p_char->getValueAttribute().setHandle(bleCharacteristic); //Set the characteristic count as the corresponding char handle
+ DEBUG("added bleCharacteristic handle =%u\n\r", bleCharacteristic);
+
+ if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getInitialLength() > 0)) {
+ write(p_char->getValueAttribute().getHandle(), p_char->getValueAttribute().getValuePtr(), p_char->getValueAttribute().getInitialLength(), false /* localOnly */);
+ }
+
+ // add descriptors now
+ uint16_t descHandle = 0;
+ DEBUG("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);
+ uint16_t shortUUID = descriptor->getUUID().getShortUUID();
+ const uint8_t uuidArray[] = {(uint8_t)((shortUUID>>8)&0xFF), (uint8_t)((shortUUID&0xFF))};
+ ret = aci_gatt_add_char_desc(service.getHandle(), p_char->getValueAttribute().getHandle(),
+ CHAR_DESC_TYPE_16_BIT, uuidArray, descriptor->getMaxLength(), descriptor->getInitialLength(),
+ descriptor->getValuePtr(), CHAR_DESC_SECURITY_PERMISSION, CHAR_DESC_ACCESS_PERMISSION, GATT_NOTIFY_ATTRIBUTE_WRITE,
+ MIN_ENCRY_KEY_SIZE, CHAR_ATTRIBUTE_LEN_IS_FIXED, &descHandle);
+ DEBUG("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret);
+ if(ret==(tBleStatus)0) {
+ DEBUG("Descriptor added successfully, descriptor handle=%d\n\r", descHandle);
+ descriptor->setHandle(descHandle);
+ }
+ }
+
+ }
+
+ 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 the service
+ and characteristic index fields
+
+ @param[in] charHandle
+ 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::readValue(uint16_t charHandle, uint8_t buffer[], uint16_t *const lengthP)
+{
+ DEBUG("ReadValue() Not Supported\n\r");
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Updates the value of a characteristic, based on the service
+ and characteristic index fields
+
+ @param[in] charHandle
+ 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] len
+ The number of bytes in buffer
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+// <<<ANDREA>>>
+ble_error_t BlueNRGGattServer::readValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) {
+ // Empty by now
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly) {
+ // Empty by now
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t charHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
+{
+ tBleStatus ret;
+ //uint8_t buff[2];
+
+ DEBUG("updating bleCharacteristic charHandle =%u, corresponding serviceHanle= %u len=%d\n\r", charHandle, bleCharHanldeMap.find(charHandle)->second, len);
+ /*
+ for(int i=0; i<len; i++) {
+ DEBUG("buffer[%d]=%d\n\r", i, buffer[i]);
+ }
+ */
+ ret = aci_gatt_update_char_value(bleCharHanldeMap.find(charHandle)->second, charHandle, 0, len, buffer);
+
+ if (ret != BLE_STATUS_SUCCESS){
+ DEBUG("Error while updating characteristic (ret=0x%x).\n\r", ret) ;
+ return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value
+ //FIXME: Define Error values equivalent to BlueNRG Error Codes.
+ }
+
+ //Generate Data Sent Event Here? (GattServerEvents::GATT_EVENT_DATA_SENT) //FIXME: Is this correct?
+ //Check if characteristic property is NOTIFY|INDICATE, if yes generate event
+ GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(charHandle);
+ if(p_char->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY
+ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) {
+ DEBUG("Generate event after updating\n\r");
+ BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_SENT, charHandle);
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Reads a value according to the handle provided
+
+ @param[in] charHandle
+ The handle of the GattCharacteristic 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 handle)
+{
+ //signed short refvalue;
+ uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle();
+
+ GattReadCallbackParams readParams;
+ readParams.handle = handle;
+
+ //DEBUG("readParams.charHandle = %d\n\r", readParams.charHandle);
+ HCIDataReadEvent(&readParams);
+
+ //EXIT:
+ if(gapConnectionHandle != 0){
+ //DEBUG("Calling aci_gatt_allow_read\n\r");
+ aci_gatt_allow_read(gapConnectionHandle);
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Returns the GattCharacteristic according to the handle provided
+
+ @param[in] charHandle
+ The handle of the GattCharacteristic
+
+ @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;
+
+ DEBUG("BlueNRGGattServer::getCharacteristicFromHandle()>>Attribute Handle received %d\n\r",attrHandle);
+ for(i=0; i<characteristicCount; i++)
+ {
+ handle = p_characteristics[i]->getValueAttribute().getHandle();
+ DEBUG("handle(%d)=%d\n\r", i, handle);
+ if(i==characteristicCount-1)//Last Characteristic check
+ {
+ if(attrHandle>=handle)
+ {
+ p_char = p_characteristics[i];
+ DEBUG("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle);
+ break;
+ }
+ }
+ else {
+ handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle();
+ //Testing if attribute handle is between two Characteristic Handles
+ if(attrHandle>=handle && attrHandle<handle_1)
+ {
+ p_char = p_characteristics[i];
+ DEBUG("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) {
+ DEBUG("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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRG_HCI/hci/controller/bluenrg_IFR.c Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,361 @@
+#ifndef __MBED__
+
+#include "hal.h"
+#include "hal_types.h"
+#include "ble_status.h"
+#include "bluenrg_updater_aci.h"
+#include "bluenrg_utils.h"
+
+/************** Do not change this define section ************/
+
+#define BLUENRG_32_MHZ 1
+#define BLUENRG_32_MHZ_RO 2
+#define BLUENRG_16_MHZ 3
+#define BLUENRG_16_MHZ_RO 4
+#define BLUENRG_CUSTOM_CONFIG 5
+
+#define MASTER_SCA_500ppm 0 // 251 ppm to 500 ppm
+#define MASTER_SCA_250ppm 1 // 151 ppm to 250 ppm
+#define MASTER_SCA_150ppm 2 // 101 ppm to 150 ppm
+#define MASTER_SCA_100ppm 3 // 76 ppm to 100 ppm
+#define MASTER_SCA_75ppm 4 // 51 ppm to 75 ppm
+#define MASTER_SCA_50ppm 5 // 31 ppm to 50 ppm
+#define MASTER_SCA_30ppm 6 // 21 ppm to 30 ppm
+#define MASTER_SCA_20ppm 7 // 0 ppm to 20 ppm
+
+#define SMPS_4MHz 0
+#define SMPS_8MHz 1
+
+#ifndef SMPS_FREQUENCY
+#define SMPS_FREQUENCY SMPS_4MHz
+#endif
+
+#if !BLUENRG_MS && (SMPS_FREQUENCY == SMPS_8MHz)
+#error Unsupported SMPS_FREQUENCY
+#endif
+
+/************************************************************/
+
+
+/************** Definitions that can be changed. ************/
+
+#define STACK_MODE 2
+#define SLAVE_SCA_PPM 100
+#define MASTER_SCA MASTER_SCA_100ppm
+#define HS_STARTUP_TIME_US 512
+#define DAY 11
+#define MONTH 02
+#define YEAR 15
+/************************************************************/
+
+/*
+ * IMPORTANT!
+ * This IFR configurations are only for BlueNRG Firmware v6.4 and 7.1.
+ */
+
+#if BLUENRG_CONFIG == BLUENRG_32_MHZ
+
+const IFR_config_TypeDef IFR_config = {
+#if BLUENRG_MS
+#if SMPS_FREQUENCY == SMPS_4MHz
+ 0x02,0x3A,0x44,0x02,
+ 0x34,0x5B,0x02,0x39,
+ 0xA2,0x02,0x3C,0x20,
+ 0x00,0xFF,0xFF,0xFF,
+#elif SMPS_FREQUENCY == SMPS_8MHz
+ 0x02,0x3A,0x44,0x02,
+ 0x34,0x5B,0x02,0x39,
+ 0xAE,0x00,0xFF,0xFF,
+ 0x00,0xFF,0xFF,0xFF,
+#else
+#error Incorrect SMPS_FREQUENCY
+#endif /* SMPS_FREQUENCY */
+#else
+ 0x02,0x3A,0x5C,0x02,
+ 0x39,0xA2,0x02,0x34,
+ 0x5B,0x00,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+#endif /* BLUENRG_MS */
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+
+ 0x02,0x1C,0x43,0x02,
+ 0x20,0xEC,0x02,0x1F,
+ 0xAF,0x00,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+
+ STACK_MODE,
+ 0xFF,0xFF,0xFF,
+ 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+ 0xFFFFFFFF,
+ htobl(0x00190000),
+ htobl(0x0028F5C2),
+ htobs(SLAVE_SCA_PPM),
+ MASTER_SCA,
+ 0xFF,
+ htobs(FROM_US_TO_SYS_TIME(HS_STARTUP_TIME_US)),
+ 0xFF,0xFF,
+ 0xFFFFFFFF,
+ 0xFF,
+ INT_TO_BCD(YEAR),INT_TO_BCD(MONTH),INT_TO_BCD(DAY),
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF
+};
+
+#elif BLUENRG_CONFIG == BLUENRG_32_MHZ_RO
+
+const IFR_config_TypeDef IFR_config = {
+#if BLUENRG_MS
+#if SMPS_FREQUENCY == SMPS_4MHz
+ 0x02,0x3A,0x44,0x02,
+ 0x34,0x1B,0x02,0x39,
+ 0xA2,0x02,0x3C,0x20,
+ 0x00,0xFF,0xFF,0xFF,
+#elif SMPS_FREQUENCY == SMPS_8MHz
+ 0x02,0x3A,0x44,0x02,
+ 0x34,0x1B,0x02,0x39,
+ 0xAE,0x00,0xFF,0xFF,
+ 0x00,0xFF,0xFF,0xFF,
+#else
+#error Incorrect SMPS_FREQUENCY
+#endif /* SMPS_FREQUENCY */
+#else
+ 0x02,0x3A,0x5C,0x02,
+ 0x39,0xA2,0x02,0x34,
+ 0x1B,0x00,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+#endif /* BLUENRG_MS */
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+
+ 0x02,0x1C,0x43,0x02,
+ 0x20,0xEC,0x02,0x1F,
+ 0xAF,0x00,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+
+ STACK_MODE,
+ 0xFF,0xFF,0xFF,
+ 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ htobs(0x01F4),
+ 0x00,
+ 0xFF,
+ htobs(FROM_US_TO_SYS_TIME(HS_STARTUP_TIME_US)),
+ 0xFF,0xFF,
+ 0xFFFFFFFF,
+ 0xFF,
+ INT_TO_BCD(YEAR),INT_TO_BCD(MONTH),INT_TO_BCD(DAY),
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF
+};
+
+#elif BLUENRG_CONFIG == BLUENRG_16_MHZ
+
+const IFR_config_TypeDef IFR_config = {
+#if BLUENRG_MS
+#if SMPS_FREQUENCY == SMPS_4MHz
+ 0x02,0x3A,0x40,0x02,
+ 0x34,0x5B,0x02,0x39,
+ 0xA2,0x02,0x3C,0x20,
+ 0x00,0xFF,0xFF,0xFF,
+#elif SMPS_FREQUENCY == SMPS_8MHz
+ 0x02,0x3A,0x40,0x02,
+ 0x34,0x5B,0x02,0x39,
+ 0xAE,0x00,0xFF,0xFF,
+ 0x00,0xFF,0xFF,0xFF,
+#else
+#error Incorrect SMPS_FREQUENCY
+#endif /* SMPS_FREQUENCY */
+#else
+ 0x02,0x3A,0x58,0x02,
+ 0x39,0xA2,0x02,0x34,
+ 0x5B,0x00,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+#endif /* BLUENRG_MS */
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+
+ 0x02,0x1C,0x43,0x02,
+ 0x20,0xEC,0x02,0x1F,
+ 0xAF,0x00,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+
+ STACK_MODE,
+ 0xFF,0xFF,0xFF,
+ 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+ 0xFFFFFFFF,
+ htobl(0x00190000),
+ htobl(0x0028F5C2),
+ htobs(SLAVE_SCA_PPM),
+ MASTER_SCA,
+ 0xFF,
+ htobs(FROM_US_TO_SYS_TIME(HS_STARTUP_TIME_US)),
+ 0xFF,0xFF,
+ 0xFFFFFFFF,
+ 0xFF,
+ INT_TO_BCD(YEAR),INT_TO_BCD(MONTH),INT_TO_BCD(DAY),
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF
+
+};
+
+#elif BLUENRG_CONFIG == BLUENRG_16_MHZ_RO
+
+const IFR_config_TypeDef IFR_config = {
+#if BLUENRG_MS
+#if SMPS_FREQUENCY == SMPS_4MHz
+ 0x02,0x3A,0x40,0x02,
+ 0x34,0x1B,0x02,0x39,
+ 0xA2,0x02,0x3C,0x20,
+ 0x00,0xFF,0xFF,0xFF,
+#elif SMPS_FREQUENCY == SMPS_8MHz
+ 0x02,0x3A,0x40,0x02,
+ 0x34,0x1B,0x02,0x39,
+ 0xAE,0x00,0xFF,0xFF,
+ 0x00,0xFF,0xFF,0xFF,
+#else
+#error Incorrect SMPS_FREQUENCY
+#endif /* SMPS_FREQUENCY */
+#else
+ 0x02,0x3A,0x58,0x02,
+ 0x39,0xA2,0x02,0x34,
+ 0x1B,0x00,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+#endif /* BLUENRG_MS */
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+
+ 0x02,0x1C,0x43,0x02,
+ 0x20,0xEC,0x02,0x1F,
+ 0xAF,0x00,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,
+
+ STACK_MODE,
+ 0xFF,0xFF,0xFF,
+ 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ htobs(0x01F4),
+ 0x00,
+ 0xFF,
+ htobs(FROM_US_TO_SYS_TIME(HS_STARTUP_TIME_US)),
+ 0xFF,0xFF,
+ 0xFFFFFFFF,
+ 0xFF,
+ INT_TO_BCD(YEAR),INT_TO_BCD(MONTH),INT_TO_BCD(DAY),
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF
+};
+
+#elif BLUENRG_CONFIG == BLUENRG_CUSTOM_CONFIG
+/* Copy and paste here your custom IFR_config structure. It can be generated
+ * with BlueNRG GUI.
+ */
+#else
+#warning BLUENRG_CONFIG not valid
+#endif
+
+#endif // !__MBED__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRG_HCI/hci/controller/bluenrg_gap_aci.c Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,1306 @@
+/******************** (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 "hal_types.h"
+#include "osal.h"
+#include "ble_status.h"
+#include "hal.h"
+#include "osal.h"
+#include "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, sizeof(actual_address));
+
+ return 0;
+}
+tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address)
+{
+ struct hci_request rq;
+ gap_resolve_private_address_cp cp;
+ uint8_t status;
+
+ Osal_MemCpy(cp.address, address, 6);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type,
+ uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries,
+ const uint8_t *addr_array)
+{
+ struct hci_request rq;
+ gap_set_broadcast_mode_cp cp;
+ uint8_t status;
+ uint8_t indx = 0;
+ uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7;
+
+ if (variable_size > sizeof(cp.var_len_data) )
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.adv_interv_min = htobs(adv_interv_min);
+ cp.adv_interv_max = htobs(adv_interv_max);
+ cp.adv_type = adv_type;
+ cp.own_addr_type = own_addr_type;
+
+ cp.var_len_data[indx] = adv_data_length;
+ indx++;
+ Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length);
+ indx += adv_data_length;
+ cp.var_len_data[indx] = num_whitelist_entries;
+ indx ++;
+ Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_SET_BROADCAST_MODE;
+ rq.cparam = &cp;
+ rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type,
+ uint8_t own_address_type, uint8_t filter_duplicates)
+{
+ struct hci_request rq;
+ gap_start_observation_proc_cp cp;
+ uint8_t status;
+
+ cp.scan_interval = scan_interval;
+ cp.scan_window = scan_window;
+ cp.scan_type = scan_type;
+ cp.own_address_type = own_address_type;
+ cp.filter_duplicates = filter_duplicates;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_START_OBSERVATION_PROC;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address)
+{
+ struct hci_request rq;
+ gap_is_device_bonded_cp cp;
+ uint8_t status;
+
+ cp.peer_address_type = peer_address_type;
+ Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_IS_DEVICE_BONDED;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size)
+{
+ struct hci_request rq;
+ gap_get_bonded_devices_rp rp;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GAP_GET_BONDED_DEVICES;
+ rq.rparam = &rp;
+ rq.rlen = sizeof(rp);
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if (rp.status) {
+ return rp.status;
+ }
+
+ *num_devices = rp.num_addr;
+ Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7));
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRG_HCI/hci/controller/bluenrg_gatt_aci.c Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,1472 @@
+/******************** (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 "hal_types.h"
+#include "osal.h"
+#include "ble_status.h"
+#include "hal.h"
+#include "osal.h"
+#include "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 uint8_t *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 uint8_t *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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRG_HCI/hci/controller/bluenrg_hal_aci.c Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,154 @@
+/******************** (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 "hal_types.h"
+#include "osal.h"
+#include "ble_status.h"
+#include "hal.h"
+#include "osal.h"
+#include "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_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;
+}
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRG_HCI/hci/controller/bluenrg_l2cap_aci.c Tue Oct 06 14:25:08 2015 +0200
@@ -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 "hal_types.h"
+#include "osal.h"
+#include "ble_status.h"
+#include "hal.h"
+#include "osal.h"
+#include "hci_const.h"
+#include "bluenrg_aci_const.h"
+#include "bluenrg_hal_aci.h"
+#include "bluenrg_gap.h"
+
+#define MIN(a,b) ((a) < (b) )? (a) : (b)
+#define MAX(a,b) ((a) > (b) )? (a) : (b)
+
+tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min,
+ uint16_t interval_max, uint16_t slave_latency,
+ uint16_t timeout_multiplier)
+{
+ struct hci_request rq;
+ uint8_t status;
+ l2cap_conn_param_update_req_cp cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.interval_min = htobs(interval_min);
+ cp.interval_max = htobs(interval_max);
+ cp.slave_latency = htobs(slave_latency);
+ cp.timeout_multiplier = htobs(timeout_multiplier);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ;
+ rq.cparam = &cp;
+ rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min,
+ uint16_t interval_max, uint16_t slave_latency,
+ uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length,
+ uint8_t id, uint8_t accept)
+{
+ struct hci_request rq;
+ uint8_t status;
+ l2cap_conn_param_update_resp_cp_IDB05A1 cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.interval_min = htobs(interval_min);
+ cp.interval_max = htobs(interval_max);
+ cp.slave_latency = htobs(slave_latency);
+ cp.timeout_multiplier = htobs(timeout_multiplier);
+ cp.min_ce_length = htobs(min_ce_length);
+ cp.max_ce_length = htobs(max_ce_length);
+ cp.id = id;
+ cp.accept = accept;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min,
+ uint16_t interval_max, uint16_t slave_latency,
+ uint16_t timeout_multiplier, uint8_t id, uint8_t accept)
+{
+ struct hci_request rq;
+ uint8_t status;
+ l2cap_conn_param_update_resp_cp_IDB04A1 cp;
+
+ cp.conn_handle = htobs(conn_handle);
+ cp.interval_min = htobs(interval_min);
+ cp.interval_max = htobs(interval_max);
+ cp.slave_latency = htobs(slave_latency);
+ cp.timeout_multiplier = htobs(timeout_multiplier);
+ cp.id = id;
+ cp.accept = accept;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRG_HCI/hci/controller/bluenrg_updater_aci.c Tue Oct 06 14:25:08 2015 +0200
@@ -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 "hal_types.h"
+#include "osal.h"
+#include "ble_status.h"
+#include "hal.h"
+#include "osal.h"
+#include "hci_const.h"
+#include "bluenrg_aci_const.h"
+#include "bluenrg_updater_aci.h"
+
+#define MIN(a,b) ((a) < (b) )? (a) : (b)
+#define MAX(a,b) ((a) > (b) )? (a) : (b)
+
+tBleStatus aci_updater_start(void)
+{
+ struct hci_request rq;
+ uint8_t status = 0;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_START;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ hci_send_req(&rq, FALSE); // No command complete is sent.
+
+ return status;
+}
+
+tBleStatus aci_updater_reboot(void)
+{
+ struct hci_request rq;
+ uint8_t status = 0;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_REBOOT;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ hci_send_req(&rq, FALSE); // No command complete is sent.
+
+ return status;
+}
+
+tBleStatus aci_get_updater_version(uint8_t *version)
+{
+ struct hci_request rq;
+ get_updater_version_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GET_UPDATER_VERSION;
+ rq.rparam = &resp;
+ rq.rlen = GET_UPDATER_VERSION_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ *version = resp.version;
+
+ return resp.status;
+}
+
+tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size)
+{
+ struct hci_request rq;
+ get_updater_bufsize_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_GET_UPDATER_BUFSIZE;
+ rq.rparam = &resp;
+ rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ *buffer_size = resp.buffer_size;
+
+ return resp.status;
+}
+
+tBleStatus aci_erase_blue_flag(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_reset_blue_flag(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_updater_erase_sector(uint32_t address)
+{
+ struct hci_request rq;
+ updater_erase_sector_cp cp;
+ uint8_t status;
+
+ cp.address = htobl(address);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_ERASE_SECTOR;
+ rq.cparam = &cp;
+ rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_updater_program_data_block(uint32_t address,
+ uint16_t len,
+ const uint8_t *data)
+{
+ struct hci_request rq;
+ uint8_t status;
+ updater_prog_data_block_cp cp;
+
+ if( len > sizeof(cp.data))
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.address = htobl(address);
+ cp.data_len = htobs(len);
+ Osal_MemCpy(cp.data, data, len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK;
+ rq.cparam = &cp;
+ rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
+tBleStatus aci_updater_read_data_block(uint32_t address,
+ uint16_t data_len,
+ uint8_t *data)
+{
+ struct hci_request rq;
+ updater_read_data_block_cp cp;
+ uint8_t buffer[HCI_MAX_PAYLOAD_SIZE];
+
+ if((data_len+1) > HCI_MAX_PAYLOAD_SIZE)
+ return BLE_STATUS_INVALID_PARAMS;
+
+ cp.address = htobl(address);
+ cp.data_len = htobs(data_len);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_READ_DATA_BLOCK;
+ rq.cparam = &cp;
+ rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE;
+ rq.rparam = buffer;
+ rq.rlen = data_len + 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ // First byte is status
+ Osal_MemCpy(data, buffer+1, data_len);
+
+ return buffer[0];
+}
+
+tBleStatus aci_updater_calc_crc(uint32_t address,
+ uint8_t num_sectors,
+ uint32_t *crc)
+{
+ struct hci_request rq;
+ updater_calc_crc_cp cp;
+ updater_calc_crc_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ cp.address = htobl(address);
+ cp.num_sectors = num_sectors;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_CALC_CRC;
+ rq.cparam = &cp;
+ rq.clen = UPDATER_CALC_CRC_CP_SIZE;
+ rq.rparam = &resp;
+ rq.rlen = UPDATER_CALC_CRC_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ *crc = btohl(resp.crc);
+
+ return resp.status;
+}
+
+tBleStatus aci_updater_hw_version(uint8_t *version)
+{
+ struct hci_request rq;
+ updater_hw_version_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_UPDATER_HW_VERSION;
+ rq.rparam = &resp;
+ rq.rlen = UPDATER_HW_VERSION_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ *version = resp.version;
+
+ return resp.status;
+}
+
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRG_HCI/hci/controller/bluenrg_utils.c Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,403 @@
+
+#include "hal.h"
+#include "hal_types.h"
+#include "ble_status.h"
+#include "bluenrg_aci.h"
+#include "bluenrg_utils.h"
+#include "hci.h"
+#include "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 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;
+
+ 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 (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 = SECTOR_SIZE; 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(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3)
+ 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
+ }
+
+ HCI_Process(); // To receive the BlueNRG EVT
+
+ 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 isHWBootloader_Patched(void)
+{
+ uint8_t status, version;
+ uint32_t crc, address = 0x10010000;
+
+ if(aci_get_updater_version(&version))
+ return BLE_UTIL_ACI_ERROR;
+
+ RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status);
+ if (status != BLE_STATUS_SUCCESS)
+ return 0;
+
+ if (crc == BOOTLOADER_CRC_NOT_PATCHED)
+ return 0;
+
+ return 1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRG_HCI/hci/hci.c Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,1147 @@
+/**
+ ******************************************************************************
+ * @file 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 "hal_types.h"
+#include "osal.h"
+#include "ble_status.h"
+#include "hal.h"
+#include "hci_const.h"
+#include "gp_timer.h"
+
+#include "stm32_bluenrg_ble.h"
+
+#if BLE_CONFIG_DBG_ENABLE
+#define PRINTF(...) printf(__VA_ARGS__)
+#else
+#define PRINTF(...)
+#endif
+
+#define HCI_LOG_ON 0
+
+#define HCI_READ_PACKET_NUM_MAX (5)
+
+#define MIN(a,b) ((a) < (b) )? (a) : (b)
+#define MAX(a,b) ((a) > (b) )? (a) : (b)
+
+tListNode hciReadPktPool;
+tListNode hciReadPktRxQueue;
+/* 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;
+
+ /* Initialize list heads of ready and free hci data packet queues */
+ list_init_head (&hciReadPktPool);
+ list_init_head (&hciReadPktRxQueue);
+
+ /* Initialize the queue of free hci data packets */
+ for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++)
+ {
+ list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]);
+ }
+}
+
+#define HCI_PCK_TYPE_OFFSET 0
+#define EVENT_PARAMETER_TOT_LEN_OFFSET 2
+
+/**
+ * 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;
+
+ 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);
+ 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);
+
+ data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE);
+ if(data_len > 0){
+ hciReadPacket->data_len = data_len;
+ if(HCI_verify(hciReadPacket) == 0)
+ list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket);
+ else
+ list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket);
+ }
+ else {
+ // Insert the packet back into the pool.
+ list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket);
+ }
+
+ }
+ else{
+ // HCI Read Packet Pool is empty, wait for a free packet.
+ 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().
+ */
+ list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket);
+ /* Be sure there is at list one packet in the pool to process the expected event. */
+ if(list_is_empty(&hciReadPktPool)){
+ pListNode tmp_node;
+ list_remove_head(&hciReadPktRxQueue, &tmp_node);
+ list_insert_tail(&hciReadPktPool, tmp_node);
+ }
+
+ Enable_SPI_IRQ();
+
+ }
+
+failed:
+ move_list(&hciReadPktRxQueue, &hciTempQueue);
+ Enable_SPI_IRQ();
+ return -1;
+
+done:
+ // Insert the packet back into the pool.
+ list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket);
+ 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;
+ 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_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;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRG_HCI/hci/hci_dma_lp.c Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,1194 @@
+/**
+ ******************************************************************************
+ * @file hci_dma_lp.c
+ * @author AMS/HESA Application Team
+ * @brief Function for managing HCI interface.
+ ******************************************************************************
+ *
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
+ */
+
+// ANDREA -- FIXME: to exclude from building when DMA is disabled
+#ifdef __DMA_LP__
+
+#include "hal_types.h"
+#include "osal.h"
+#include "ble_status.h"
+#include "hal.h"
+#include "hci_const.h"
+#include "gp_timer.h"
+
+#include "bluenrg_interface.h"
+#include "stm32xx_timerserver.h"
+
+extern SPI_HandleTypeDef SpiHandle;
+
+#if BLE_CONFIG_DBG_ENABLE
+#define PRINTF(...) printf(__VA_ARGS__)
+#else
+#define PRINTF(...)
+#endif
+
+#define HCI_LOG_ON 0
+
+#define HCI_READ_PACKET_NUM_MAX (5)
+
+#define MIN(a,b) ((a) < (b) )? (a) : (b)
+#define MAX(a,b) ((a) > (b) )? (a) : (b)
+
+static void enqueue_packet(tHciDataPacket * hciReadPacket);
+static void hci_timeout_callback(void);
+
+tListNode hciReadPktPool;
+tListNode hciReadPktRxQueue;
+/* pool of hci read packets */
+static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX];
+
+static volatile uint8_t readPacketListFull=FALSE;
+
+static uint8_t *hci_buffer = NULL;
+static volatile uint16_t hci_pckt_len;
+static volatile uint8_t hci_timer_id;
+static volatile uint8_t hci_timeout;
+
+uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE];
+
+void hci_timeout_callback(void)
+{
+ hci_timeout = 1;
+
+ return;
+}
+
+void HCI_Init(void)
+{
+ uint8_t index;
+
+ /* Initialize list heads of ready and free hci data packet queues */
+ list_init_head (&hciReadPktPool);
+ list_init_head (&hciReadPktRxQueue);
+
+ /* Initialize the queue of free hci data packets */
+ for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++)
+ {
+ list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]);
+ }
+}
+
+#define HCI_PCK_TYPE_OFFSET 0
+#define EVENT_PARAMETER_TOT_LEN_OFFSET 2
+
+void Hal_Init_Event_Request(void)
+{
+ tHciDataPacket * hciReadPacket = NULL;
+
+ list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket);
+
+ Hal_Event_Request ((uint8_t*)hciReadPacket, HCI_READ_PACKET_SIZE);
+}
+
+static volatile hci_packet_complete_callback packet_complete_callback = NULL;
+
+static void hci_set_packet_complete_callback(hci_packet_complete_callback cb)
+{
+ packet_complete_callback = cb;
+}
+
+void HCI_Input(tHciDataPacket * hciReadPacket)
+{
+ uint8_t byte;
+ hci_acl_hdr *acl_hdr;
+
+ static hci_state state = WAITING_TYPE;
+
+ uint16_t collected_payload_len = 0;
+ uint16_t payload_len;
+
+ hci_buffer = hciReadPacket->dataBuff;
+
+ if(state == WAITING_TYPE)
+ hci_pckt_len = 0;
+
+ while(hci_pckt_len < HCI_READ_PACKET_SIZE){
+
+ byte = hci_buffer[hci_pckt_len++];
+
+ if(state == WAITING_TYPE){
+ /* Only ACL Data and Events packets are accepted. */
+ if(byte == HCI_EVENT_PKT){
+ state = WAITING_EVENT_CODE;
+ }
+// else if(byte == HCI_ACLDATA_PKT){
+// state = WAITING_HANDLE;
+// }
+ else{
+ /* Incorrect type. Reset state machine. */
+ state = WAITING_TYPE;
+ break;
+ }
+ }
+ else if(state == WAITING_EVENT_CODE)
+ state = WAITING_PARAM_LEN;
+ else if(state == WAITING_HANDLE)
+ state = WAITING_HANDLE_FLAG;
+ else if(state == WAITING_HANDLE_FLAG)
+ state = WAITING_DATA_LEN1;
+ else if(state == WAITING_DATA_LEN1)
+ state = WAITING_DATA_LEN2;
+
+ else if(state == WAITING_DATA_LEN2){
+ acl_hdr = (void *)&hci_buffer[HCI_HDR_SIZE];
+ payload_len = acl_hdr->dlen;
+ collected_payload_len = 0;
+ state = WAITING_PAYLOAD;
+ }
+ else if(state == WAITING_PARAM_LEN){
+ payload_len = byte;
+ collected_payload_len = 0;
+ state = WAITING_PAYLOAD;
+ }
+ else if(state == WAITING_PAYLOAD){
+ collected_payload_len += 1;
+ if(collected_payload_len >= payload_len){
+ /* Reset state machine. */
+ state = WAITING_TYPE;
+ enqueue_packet(hciReadPacket);
+
+ if(packet_complete_callback){
+ uint16_t len = hci_pckt_len;
+ packet_complete_callback(hci_buffer, len);
+ }
+ break;
+ }
+ }
+ }
+}
+
+void enqueue_packet(tHciDataPacket * hciReadPacket)
+{
+ hci_uart_pckt *hci_pckt = (void*)hciReadPacket->dataBuff;
+ hci_event_pckt *event_pckt = (void*)hci_pckt->data;
+
+ // Do not enqueue Command Complete or Command Status events
+
+ if((hci_pckt->type != HCI_EVENT_PKT) ||
+ event_pckt->evt == EVT_CMD_COMPLETE ||
+ event_pckt->evt == EVT_CMD_STATUS){
+ // Insert the packet back into the pool.
+ list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
+ }
+ else {
+ // Insert the packet into the queue of events to be processed.
+ list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket);
+ HCI_Process_Notification_Request();
+ }
+}
+
+void HCI_Process(void)
+{
+ //uint8_t data_len;
+ //uint8_t buffer[HCI_PACKET_SIZE];
+ tHciDataPacket * hciReadPacket = NULL;
+
+ uint8_t list_empty = list_is_empty(&hciReadPktRxQueue);
+ /* process any pending events read */
+ while(list_empty == FALSE)
+ {
+ list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
+ HCI_Event_CB(hciReadPacket->dataBuff);
+ list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
+ list_empty = list_is_empty(&hciReadPktRxQueue);
+ }
+}
+
+BOOL HCI_Queue_Empty(void)
+{
+ return list_is_empty(&hciReadPktRxQueue);
+}
+
+void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len)
+{
+ tHciDataPacket * hciReadPacket = NULL;
+
+ if (list_is_empty (&hciReadPktPool) == FALSE){
+
+ list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket);
+
+ Hal_Event_Request ((uint8_t*)hciReadPacket, HCI_READ_PACKET_SIZE);
+ }
+
+ if(event_payload_len > 0){
+
+ HCI_Input((tHciDataPacket*)buffer);
+ // Packet will be inserted to te correct queue by
+ }
+ else {
+ // Insert the packet back into the pool.
+ list_insert_head(&hciReadPktPool, (tListNode*)buffer);
+ }
+}
+
+void hci_write(const void* data1, const void* data2, uint16_t n_bytes1, uint16_t n_bytes2){
+#if HCI_LOG_ON
+ PRINTF("HCI <- ");
+ for(int i=0; i < n_bytes1; i++)
+ PRINTF("%02X ", *((uint8_t*)data1 + i));
+ for(int i=0; i < n_bytes2; i++)
+ PRINTF("%02X ", *((uint8_t*)data2 + i));
+ PRINTF("\n");
+#endif
+
+ Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2);
+}
+
+void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param)
+{
+ hci_command_hdr hc;
+
+ hc.opcode = htobs(cmd_opcode_pack(ogf, ocf));
+ hc.plen= plen;
+
+ //uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE];
+ header[0] = HCI_COMMAND_PKT;
+ Osal_MemCpy(header+1, &hc, sizeof(hc));
+
+ hci_write(header, param, sizeof(header), plen);
+}
+
+static uint8_t new_packet;
+
+void new_hci_event(void *pckt, uint16_t len)
+{
+
+ new_packet = TRUE;
+}
+
+/**
+ * FIXME: Param async is unused, it has been introduced to align the interface
+ * to DK 1.6.0 HCI stack
+ */
+/* 'to' is timeout in system clock ticks. */
+int hci_send_req(struct hci_request *r, BOOL async)
+{
+ uint8_t *ptr;
+ uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf));
+ hci_event_pckt *event_pckt;
+ hci_uart_pckt *hci_hdr;
+ int try;
+ uint32_t to = DEFAULT_TIMEOUT;
+
+ new_packet = FALSE;
+ HCI_Cmd_Status(BUSY);
+ hci_set_packet_complete_callback(new_hci_event);
+ hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam);
+
+ try = 10;
+ while (try--) {
+ evt_cmd_complete *cc;
+ evt_cmd_status *cs;
+ evt_le_meta_event *me;
+ int len;
+
+ /* Minimum timeout is 1. */
+ if(to == 0)
+ to = 1;
+
+ hci_timeout = 0;
+ Blue_NRG_HCI_Timer_Start(to, hci_timeout_callback, (uint8_t*)&hci_timer_id);
+
+ while(1){
+ if(hci_timeout){
+ Blue_NRG_HCI_Timer_Stop(hci_timer_id);
+ goto failed;
+ }
+ if(new_packet){
+ Blue_NRG_HCI_Timer_Stop(hci_timer_id);
+ break;
+ }
+ HCI_Wait_For_Response();
+ }
+
+ hci_hdr = (void *)hci_buffer;
+ if(hci_hdr->type != HCI_EVENT_PKT){
+ new_packet = FALSE;
+ continue;
+ }
+
+ event_pckt = (void *) (hci_hdr->data);
+
+ ptr = hci_buffer + (1 + HCI_EVENT_HDR_SIZE);
+ len = hci_pckt_len - (1 + HCI_EVENT_HDR_SIZE);
+
+ switch (event_pckt->evt) {
+
+ case EVT_CMD_STATUS:
+ cs = (void *) ptr;
+
+ if (cs->opcode != opcode)
+ break;
+
+ if (r->event != EVT_CMD_STATUS) {
+ if (cs->status) {
+ goto failed;
+ }
+ break;
+ }
+
+ r->rlen = MIN(len, r->rlen);
+ Osal_MemCpy(r->rparam, ptr, r->rlen);
+ goto done;
+
+ case EVT_CMD_COMPLETE:
+ cc = (void *) ptr;
+
+ if (cc->opcode != opcode)
+ break;
+
+ ptr += EVT_CMD_COMPLETE_SIZE;
+ len -= EVT_CMD_COMPLETE_SIZE;
+
+ r->rlen = MIN(len, r->rlen);
+ Osal_MemCpy(r->rparam, ptr, r->rlen);
+ goto done;
+
+ case EVT_LE_META_EVENT:
+ me = (void *) ptr;
+
+ if (me->subevent != r->event)
+ break;
+
+ len -= 1;
+ r->rlen = MIN(len, r->rlen);
+ Osal_MemCpy(r->rparam, me->data, r->rlen);
+ goto done;
+
+ case EVT_HARDWARE_ERROR:
+ goto failed;
+
+ default:
+ break; // In the meantime there could be other events from the controller.
+ }
+
+ new_packet = FALSE;
+
+ }
+
+failed:
+ hci_set_packet_complete_callback(NULL);
+ return -1;
+
+done:
+ hci_set_packet_complete_callback(NULL);
+ HCI_Cmd_Status(AVAILABLE);
+ return 0;
+}
+
+int hci_reset()
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_HOST_CTL;
+ rq.ocf = OCF_RESET;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_disconnect(uint16_t handle, uint8_t reason)
+{
+ struct hci_request rq;
+ disconnect_cp cp;
+ uint8_t status;
+
+ cp.handle = handle;
+ cp.reason = reason;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LINK_CTL;
+ rq.ocf = OCF_DISCONNECT;
+ rq.cparam = &cp;
+ rq.clen = DISCONNECT_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version,
+ uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion)
+{
+ struct hci_request rq;
+ read_local_version_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_INFO_PARAM;
+ rq.ocf = OCF_READ_LOCAL_VERSION;
+ rq.cparam = NULL;
+ rq.clen = 0;
+ rq.rparam = &resp;
+ rq.rlen = READ_LOCAL_VERSION_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (resp.status) {
+ return -1;
+ }
+
+
+ *hci_version = resp.hci_version;
+ *hci_revision = btohs(resp.hci_revision);
+ *lmp_pal_version = resp.lmp_pal_version;
+ *manufacturer_name = btohs(resp.manufacturer_name);
+ *lmp_pal_subversion = btohs(resp.lmp_pal_subversion);
+
+ return 0;
+}
+
+int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt)
+{
+ struct hci_request rq;
+ le_read_buffer_size_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_BUFFER_SIZE;
+ rq.cparam = NULL;
+ rq.clen = 0;
+ rq.rparam = &resp;
+ rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (resp.status) {
+ return -1;
+ }
+
+ *pkt_len = resp.pkt_len;
+ *max_pkt = resp.max_pkt;
+
+ return 0;
+}
+
+int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype,
+ uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map,
+ uint8_t filter)
+{
+ struct hci_request rq;
+ le_set_adv_parameters_cp adv_cp;
+ uint8_t status;
+
+ Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
+ adv_cp.min_interval = min_interval;
+ adv_cp.max_interval = max_interval;
+ adv_cp.advtype = advtype;
+ adv_cp.own_bdaddr_type = own_bdaddr_type;
+ adv_cp.direct_bdaddr_type = direct_bdaddr_type;
+ Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr));
+ adv_cp.chan_map = chan_map;
+ adv_cp.filter = filter;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_SET_ADV_PARAMETERS;
+ rq.cparam = &adv_cp;
+ rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_set_advertising_data(uint8_t length, const uint8_t data[])
+{
+ struct hci_request rq;
+ le_set_adv_data_cp adv_cp;
+ uint8_t status;
+
+ Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
+ adv_cp.length = length;
+ Osal_MemCpy(adv_cp.data, data, MIN(31,length));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_SET_ADV_DATA;
+ rq.cparam = &adv_cp;
+ rq.clen = LE_SET_ADV_DATA_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_set_advertise_enable(uint8_t enable)
+{
+ struct hci_request rq;
+ le_set_advertise_enable_cp adv_cp;
+ uint8_t status;
+
+ Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
+ adv_cp.enable = enable?1:0;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE;
+ rq.cparam = &adv_cp;
+ rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_rand(uint8_t random_number[8])
+{
+ struct hci_request rq;
+ le_rand_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_RAND;
+ rq.cparam = NULL;
+ rq.clen = 0;
+ rq.rparam = &resp;
+ rq.rlen = LE_RAND_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (resp.status) {
+ return -1;
+ }
+
+ Osal_MemCpy(random_number, resp.random, 8);
+
+ return 0;
+}
+
+int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[])
+{
+ struct hci_request rq;
+ le_set_scan_response_data_cp scan_resp_cp;
+ uint8_t status;
+
+ Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp));
+ scan_resp_cp.length = length;
+ Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA;
+ rq.cparam = &scan_resp_cp;
+ rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level)
+{
+ struct hci_request rq;
+ le_read_adv_channel_tx_power_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER;
+ rq.cparam = NULL;
+ rq.clen = 0;
+ rq.rparam = &resp;
+ rq.rlen = LE_RAND_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (resp.status) {
+ return -1;
+ }
+
+ *tx_power_level = resp.level;
+
+ return 0;
+}
+
+int hci_le_set_random_address(tBDAddr bdaddr)
+{
+ struct hci_request rq;
+ le_set_random_address_cp set_rand_addr_cp;
+ uint8_t status;
+
+ Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp));
+ Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_SET_RANDOM_ADDRESS;
+ rq.cparam = &set_rand_addr_cp;
+ rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_read_bd_addr(tBDAddr bdaddr)
+{
+ struct hci_request rq;
+ read_bd_addr_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_INFO_PARAM;
+ rq.ocf = OCF_READ_BD_ADDR;
+ rq.cparam = NULL;
+ rq.clen = 0;
+ rq.rparam = &resp;
+ rq.rlen = READ_BD_ADDR_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (resp.status) {
+ return -1;
+ }
+ Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr));
+
+ return 0;
+}
+
+int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type,
+ const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval,
+ uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length)
+{
+ struct hci_request rq;
+ le_create_connection_cp create_cp;
+ uint8_t status;
+
+ Osal_MemSet(&create_cp, 0, sizeof(create_cp));
+ create_cp.interval = interval;
+ create_cp.window = window;
+ create_cp.initiator_filter = initiator_filter;
+ create_cp.peer_bdaddr_type = peer_bdaddr_type;
+ Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr));
+ create_cp.own_bdaddr_type = own_bdaddr_type;
+ create_cp.min_interval=min_interval;
+ create_cp.max_interval=max_interval;
+ create_cp.latency = latency;
+ create_cp.supervision_timeout=supervision_timeout;
+ create_cp.min_ce_length=min_ce_length;
+ create_cp.max_ce_length=max_ce_length;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_CREATE_CONN;
+ rq.cparam = &create_cp;
+ rq.clen = LE_CREATE_CONN_CP_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return -1;
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16])
+{
+ struct hci_request rq;
+ le_encrypt_cp params;
+ le_encrypt_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemCpy(params.key, key, 16);
+ Osal_MemCpy(params.plaintext, plaintextData, 16);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_ENCRYPT;
+ rq.cparam = ¶ms;
+ rq.clen = LE_ENCRYPT_CP_SIZE;
+ rq.rparam = &resp;
+ rq.rlen = LE_ENCRYPT_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return -1;
+ }
+
+ if (resp.status) {
+ return -1;
+ }
+
+ Osal_MemCpy(encryptedData, resp.encdata, 16);
+
+ return 0;
+}
+
+int hci_le_ltk_request_reply(uint8_t key[16])
+{
+ struct hci_request rq;
+ le_ltk_reply_cp params;
+ le_ltk_reply_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ params.handle = 1;
+ Osal_MemCpy(params.key, key, 16);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_LTK_REPLY;
+ rq.cparam = ¶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 -1;
+
+ if (resp.status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_ltk_request_neg_reply()
+{
+ struct hci_request rq;
+ le_ltk_neg_reply_cp params;
+ le_ltk_neg_reply_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ params.handle = 1;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_LTK_NEG_REPLY;
+ rq.cparam = ¶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 -1;
+
+ if (resp.status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_read_white_list_size(uint8_t *size)
+{
+ struct hci_request rq;
+ le_read_white_list_size_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE;
+ rq.rparam = &resp;
+ rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return -1;
+ }
+
+ if (resp.status) {
+ return -1;
+ }
+
+ *size = resp.size;
+
+ return 0;
+}
+
+int hci_le_clear_white_list()
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_CLEAR_WHITE_LIST;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return -1;
+ }
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr)
+{
+ struct hci_request rq;
+ le_add_device_to_white_list_cp params;
+ uint8_t status;
+
+ params.bdaddr_type = bdaddr_type;
+ Osal_MemCpy(params.bdaddr, bdaddr, 6);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST;
+ rq.cparam = ¶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 -1;
+ }
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr)
+{
+ struct hci_request rq;
+ le_remove_device_from_white_list_cp params;
+ uint8_t status;
+
+ params.bdaddr_type = bdaddr_type;
+ Osal_MemCpy(params.bdaddr, bdaddr, 6);
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST;
+ rq.cparam = ¶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 -1;
+ }
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level)
+{
+ struct hci_request rq;
+ read_transmit_power_level_cp params;
+ read_transmit_power_level_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ params.handle = *conn_handle;
+ params.type = type;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_HOST_CTL;
+ rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL;
+ rq.cparam = ¶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 -1;
+ }
+
+ if (resp.status) {
+ return -1;
+ }
+
+ *conn_handle = resp.handle;
+ *tx_level = resp.level;
+
+ return 0;
+}
+
+int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi)
+{
+ struct hci_request rq;
+ read_rssi_cp params;
+ read_rssi_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ params.handle = *conn_handle;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_STATUS_PARAM;
+ rq.ocf = OCF_READ_RSSI;
+ rq.cparam = ¶ms;
+ rq.clen = READ_RSSI_CP_SIZE;
+ rq.rparam = &resp;
+ rq.rlen = READ_RSSI_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return -1;
+ }
+
+ if (resp.status) {
+ return -1;
+ }
+
+ *conn_handle = resp.handle;
+ *rssi = resp.rssi;
+
+ return 0;
+}
+
+int hci_le_read_local_supported_features(uint8_t *features)
+{
+ struct hci_request rq;
+ le_read_local_supported_features_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_LOCAL_SUPPORTED_FEATURES;
+ rq.rparam = &resp;
+ rq.rlen = LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return -1;
+ }
+
+ if (resp.status) {
+ return -1;
+ }
+
+ Osal_MemCpy(features, resp.features, sizeof(resp.features));
+
+ return 0;
+}
+
+int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5])
+{
+ struct hci_request rq;
+ le_read_channel_map_cp params;
+ le_read_channel_map_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ params.handle = conn_handle;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_CHANNEL_MAP;
+ rq.cparam = ¶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 -1;
+ }
+
+ if (resp.status) {
+ return -1;
+ }
+
+ Osal_MemCpy(ch_map, resp.map, 5);
+
+ return 0;
+}
+
+int hci_le_read_supported_states(uint8_t states[8])
+{
+ struct hci_request rq;
+ le_read_supported_states_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_SUPPORTED_STATES;
+ rq.rparam = &resp;
+ rq.rlen = LE_READ_SUPPORTED_STATES_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return -1;
+ }
+
+ if (resp.status) {
+ return -1;
+ }
+
+ Osal_MemCpy(states, resp.states, 8);
+
+ return 0;
+}
+
+int hci_le_receiver_test(uint8_t frequency)
+{
+ struct hci_request rq;
+ le_receiver_test_cp params;
+ uint8_t status;
+
+ params.frequency = frequency;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_RECEIVER_TEST;
+ rq.cparam = ¶ms;
+ rq.clen = LE_RECEIVER_TEST_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return -1;
+ }
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload)
+{
+ struct hci_request rq;
+ le_transmitter_test_cp params;
+ uint8_t status;
+
+ params.frequency = frequency;
+ params.length = length;
+ params.payload = payload;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_TRANSMITTER_TEST;
+ rq.cparam = ¶ms;
+ rq.clen = LE_TRANSMITTER_TEST_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return -1;
+ }
+
+ if (status) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_test_end(uint16_t *num_pkts)
+{
+ struct hci_request rq;
+ le_test_end_rp resp;
+
+ Osal_MemSet(&resp, 0, sizeof(resp));
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_TEST_END;
+ rq.rparam = &resp;
+ rq.rlen = LE_TEST_END_RP_SIZE;
+
+ if (hci_send_req(&rq, FALSE) < 0){
+ return -1;
+ }
+
+ if (resp.status) {
+ return -1;
+ }
+
+ *num_pkts = resp.num_pkts;
+
+ return 0;
+}
+
+#endif /* __DMA_LP__ */
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRG_HCI/utils/gp_timer.c Tue Oct 06 14:25:08 2015 +0200
@@ -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 "clock.h"
+#include "gp_timer.h"
+
+/*---------------------------------------------------------------------------*/
+/**
+ * Set a timer.
+ *
+ * This function sets a timer for a time sometime in the
+ * future. The function timer_expired() will evaluate to true after
+ * the timer has expired.
+ *
+ * @param[in] t A pointer to the timer
+ * @param[in] interval The interval before the timer expires.
+ *
+ */
+void
+Timer_Set(struct timer *t, tClockTime interval)
+{
+ t->interval = interval;
+ t->start = Clock_Time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Reset the timer with the same interval.
+ *
+ * This function resets the timer with the same interval that was
+ * given to the timer_set() function. The start point of the interval
+ * is the exact time that the timer last expired. Therefore, this
+ * function will cause the timer to be stable over time, unlike the
+ * timer_restart() function.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa timer_restart()
+ */
+void
+Timer_Reset(struct timer *t)
+{
+ t->start += t->interval;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Restart the timer from the current point in time
+ *
+ * This function restarts a timer with the same interval that was
+ * given to the timer_set() function. The timer will start at the
+ * current time.
+ *
+ * \note A periodic timer will drift if this function is used to reset
+ * it. For preioric timers, use the timer_reset() function instead.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa timer_reset()
+ */
+void
+Timer_Restart(struct timer *t)
+{
+ t->start = Clock_Time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Check if a timer has expired.
+ *
+ * This function tests if a timer has expired and returns true or
+ * false depending on its status.
+ *
+ * \param t A pointer to the timer
+ *
+ * \return Non-zero if the timer has expired, zero otherwise.
+ *
+ */
+int
+Timer_Expired(struct timer *t)
+{
+ /* Note: Can not return diff >= t->interval so we add 1 to diff and return
+ t->interval < diff - required to avoid an internal error in mspgcc. */
+ tClockTime diff = (Clock_Time() - t->start) + 1;
+ return t->interval < diff;
+
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * The time until the timer expires
+ *
+ * This function returns the time until the timer expires.
+ *
+ * \param t A pointer to the timer
+ *
+ * \return The time until the timer expires
+ *
+ */
+tClockTime
+Timer_Remaining(struct timer *t)
+{
+ return t->start + t->interval - Clock_Time();
+}
+/*---------------------------------------------------------------------------*/
+#ifdef __DMA_LP__
+
+tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime,
+ TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb,
+ uint8_t *timerID)
+{
+ TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot,
+ (pf_TIMER_TimerCallBack_t) timercb);
+ TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE);
+
+ return (BLE_STATUS_SUCCESS);
+}
+
+/*---------------------------------------------------------------------------*/
+tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID)
+{
+ TIMER_Delete(timerID);
+
+ return (BLE_STATUS_SUCCESS);
+}
+
+#endif /* __DMA_LP__ */
+/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRG_HCI/utils/list.c Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,119 @@
+/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+* File Name : 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 <hal_types.h>
+#include "list.h"
+
+/******************************************************************************
+ * Function Definitions
+******************************************************************************/
+void list_init_head (tListNode * listHead)
+{
+ listHead->next = listHead;
+ listHead->prev = listHead;
+}
+
+uint8_t list_is_empty (tListNode * listHead)
+{
+ return ((listHead->next == listHead)? TRUE:FALSE);
+}
+
+void list_insert_head (tListNode * listHead, tListNode * node)
+{
+ node->next = listHead->next;
+ node->prev = listHead;
+ listHead->next = node;
+ (node->next)->prev = node;
+}
+
+
+void list_insert_tail (tListNode * listHead, tListNode * node)
+{
+ node->next = listHead;
+ node->prev = listHead->prev;
+ listHead->prev = node;
+ (node->prev)->next = node;
+}
+
+
+void list_remove_node (tListNode * node)
+{
+ (node->prev)->next = node->next;
+ (node->next)->prev = node->prev;
+}
+
+
+void list_remove_head (tListNode * listHead, tListNode ** node )
+{
+ *node = listHead->next;
+ list_remove_node (listHead->next);
+ (*node)->next = NULL;
+ (*node)->prev = NULL;
+}
+
+
+void list_remove_tail (tListNode * listHead, tListNode ** node )
+{
+ *node = listHead->prev;
+ list_remove_node (listHead->prev);
+ (*node)->next = NULL;
+ (*node)->prev = NULL;
+}
+
+
+void list_insert_node_after (tListNode * node, tListNode * ref_node)
+{
+ node->next = ref_node->next;
+ node->prev = ref_node;
+ ref_node->next = node;
+ (node->next)->prev = node;
+}
+
+
+void list_insert_node_before (tListNode * node, tListNode * ref_node)
+{
+ node->next = ref_node;
+ node->prev = ref_node->prev;
+ ref_node->prev = node;
+ (node->prev)->next = node;
+}
+
+
+int list_get_size (tListNode * listHead)
+{
+ int size = 0;
+ tListNode * temp = listHead->next;
+ while (temp != listHead)
+ {
+ size++;
+ temp = temp->next;
+ }
+ return (size);
+}
+
+void list_get_next_node (tListNode * ref_node, tListNode ** node)
+{
+ *node = ref_node->next;
+}
+
+
+void list_get_prev_node (tListNode * ref_node, tListNode ** node)
+{
+ *node = ref_node->prev;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRG_HCI/utils/osal.c Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,72 @@
+/**
+******************************************************************************
+* @file 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 <osal.h>
+
+ /**
+ * @brief Osal_MemCpy
+ * @param dest: Pointer to the destination buffer
+ * @param src : Pointer to the source buffer
+ * @param size: Number of bytes to copy from the source to the destination
+ * buffer
+ * @retval Pointer to the destination buffer
+ */
+void* Osal_MemCpy(void *dest, const void *src, unsigned int size)
+{
+ return(memcpy(dest,src,size));
+}
+
+/**
+ * @brief Osal_MemSet
+ * @param ptr : Pointer to block of memory to fill
+ * @param value: Value to assign to each byte of the memory block
+ * @param size : Number of bytes to be set to "value"
+ * @retval Pointer to the filled block of memory
+ */
+void* Osal_MemSet(void *ptr, int value, unsigned int size)
+{
+ return(memset(ptr,value,size));
+}
+
+/******************************************************************************
+ * local Functions
+ *****************************************************************************/
+
+ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/platform/X-NUCLEO-IDB04A1/stm32_bluenrg_ble.cpp Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,205 @@
+/**
+ ******************************************************************************
+ * @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"
+
+// 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 "gp_timer.h"
+#include "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)
+{
+ // FIXME: this is not implemented yet
+ while (1);
+}
+
+/**
+ * @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();
+}
+
+/**
+ * @brief Disable SPI IRQ.
+ * @param None
+ * @retval None
+ */
+void Disable_SPI_IRQ(void)
+{
+ bluenrgDeviceInstance.disable_irq();
+}
+
+/**
+ * @brief Clear Pending SPI IRQ.
+ * @param None
+ * @retval None
+ */
+void Clear_SPI_IRQ(void)
+{
+}
+
+/**
+ * @brief Clear EXTI (External Interrupt) line for SPI IRQ.
+ * @param None
+ * @retval None
+ */
+void Clear_SPI_EXTI_Flag(void)
+{
+}
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+// End of C function wrappers
+////////////////////////////////////////
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/platform/X-NUCLEO-IDB04A1/stm32_bluenrg_ble_dma_lp.c Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,989 @@
+/**
+ ******************************************************************************
+ * @file stm32_bluenrg_ble_dma_lp.c
+ * @author CL
+ * @version V1.0.0
+ * @date 04-July-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.
+ *
+ ******************************************************************************
+ */
+
+// ANDREA -- FIXME: to exclude from building when DMA is disabled
+#ifdef __DMA_LP__
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32_bluenrg_ble_dma_lp.h"
+#include "hci_const.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup X-NUCLEO-IDB04A1
+ * @{
+ */
+
+/** @defgroup STM32_BLUENRG_BLE_DMA_LP
+ * @{
+ */
+
+/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Defines
+ * @{
+ */
+
+#define TEST_TX_BUFFER_LIMITATION 0
+#define MAX_TX_BUFFER_SIZE 0x7F
+#define BLUENRG_READY_STATE 0x02
+
+#define HEADER_SIZE 5
+#define MAX_BUFFER_SIZE 255
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Types
+* @{
+*/
+
+typedef enum
+{
+ SPI_HEADER_TRANSMIT,
+ SPI_PAYLOAD_TRANSMIT
+} SPI_TRANSMIT_REQUEST_t;
+
+typedef enum
+{
+ SPI_HEADER_TRANSMITTED,
+ SPI_PAYLOAD_TRANSMITTED
+} SPI_TRANSMIT_EVENT_t;
+
+typedef enum
+{
+ SPI_REQUEST_VALID_HEADER_FOR_RX,
+ SPI_REQUEST_VALID_HEADER_FOR_TX,
+ SPI_REQUEST_PAYLOAD
+} SPI_RECEIVE_REQUEST_t;
+
+typedef enum
+{
+ SPI_CHECK_RECEIVED_HEADER_FOR_RX,
+ SPI_CHECK_RECEIVED_HEADER_FOR_TX,
+ SPI_RECEIVE_END
+} SPI_RECEIVE_EVENT_t;
+
+typedef enum
+{
+ SPI_AVAILABLE,
+ SPI_BUSY
+} SPI_PERIPHERAL_STATUS_t;
+
+typedef struct
+{
+ SPI_TRANSMIT_EVENT_t Spi_Transmit_Event;
+ uint8_t* header_data;
+ uint8_t* payload_data;
+ uint8_t header_size;
+ uint8_t payload_size;
+ uint8_t payload_size_to_transmit;
+ uint8_t packet_cont;
+ uint8_t RequestPending;
+} SPI_Transmit_Context_t;
+
+typedef struct
+{
+ SPI_RECEIVE_EVENT_t Spi_Receive_Event;
+ uint16_t payload_len;
+ uint8_t* buffer;
+ uint8_t buffer_size;
+} SPI_Receive_Context_t;
+
+typedef struct
+{
+ SPI_HandleTypeDef *hspi;
+ SPI_PERIPHERAL_STATUS_t Spi_Peripheral_State;
+ SPI_Receive_Context_t SPI_Receive_Context;
+ SPI_Transmit_Context_t SPI_Transmit_Context;
+} SPI_Context_t;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Variables
+ * @{
+ */
+
+SPI_HandleTypeDef SpiHandle;
+SPI_Context_t SPI_Context;
+
+const uint8_t Write_Header_CMD[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00};
+const uint8_t Read_Header_CMD[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00};
+const uint8_t dummy_bytes = 0xFF;
+
+uint8_t Received_Header[HEADER_SIZE];
+
+#ifdef ENABLE_SPI_FIX
+static uint8_t StartupTimerId;
+#endif
+static uint8_t TxRxTimerId;
+volatile uint8_t ubnRFresetTimerLock;
+pf_TIMER_TimerCallBack_t pTimerTxRxCallback;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Extern_Variables
+ * @{
+ */
+extern uint8_t* HCI_read_packet;
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Function_Prototypes
+ * @{
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+static void SPI_Transmit_Manager(SPI_TRANSMIT_REQUEST_t TransmitRequest);
+static void SPI_Receive_Manager(SPI_RECEIVE_REQUEST_t ReceiveRequest);
+static void set_irq_as_output(void);
+static void set_irq_as_input(void);
+static void Disable_SPI_Receiving_Path(void);
+static void Enable_SPI_Receiving_Path(void);
+static void Enable_SPI_CS(void);
+static void Disable_SPI_CS(void);
+static void DisableEnable_SPI_CS(void);
+static void TransmitClosure(void);
+static void ReceiveClosure(void);
+static void ReceiveHeader(SPI_RECEIVE_EVENT_t ReceiveEvent, uint8_t * DataHeader);
+static void WakeupBlueNRG(void);
+static void TimerStartupCallback(void);
+static void TimerTransmitCallback(void);
+static void pf_nRFResetTimerCallBack(void);
+static void TimerTxRxCallback(void);
+static void ProcessEndOfReceive(void);
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Exported_Functions
+ * @{
+ */
+
+/**
+ * @brief This function notify when then BlueNRG nRESET may be released
+ * @param None
+ * @retval None
+ */
+static void pf_nRFResetTimerCallBack(void)
+{
+ ubnRFresetTimerLock = 0;
+
+ return;
+}
+
+/**
+ * @brief Timer callback to handle RxTx Timers
+ * @param None
+ * @retval None
+ */
+static void TimerTxRxCallback(void)
+{
+ pTimerTxRxCallback();
+
+ return;
+}
+
+/**
+ * @brief Close the receiver path
+ * @param None
+ * @retval None
+ */
+static void ReceiveClosure(void)
+{
+ /*
+ * Disable both DMA
+ */
+ __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
+ __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
+
+ /*
+ * Check if a command is pending
+ */
+ __disable_irq();
+ if(SPI_Context.SPI_Transmit_Context.RequestPending == TRUE)
+ {
+ SPI_Context.SPI_Transmit_Context.RequestPending = FALSE;
+ SPI_Context.Spi_Peripheral_State = SPI_BUSY;
+ Disable_SPI_Receiving_Path();
+ __enable_irq();
+ WakeupBlueNRG();
+ }
+ else
+ {
+ SPI_Context.Spi_Peripheral_State = SPI_AVAILABLE;
+ __enable_irq();
+ }
+
+ return;
+}
+
+/**
+ * @brief Delay Notification to the App to prevent dummy event read
+ * @param None
+ * @retval None
+ */
+static void ProcessEndOfReceive(void)
+{
+ ReceiveClosure();
+
+ HCI_Isr(HCI_read_packet, SPI_Context.SPI_Receive_Context.payload_len);
+
+ return;
+}
+
+/**
+ * @brief Timer callback to apply timeout SPI FIX
+ * @param None
+ * @retval None
+ */
+static void TimerTransmitCallback(void)
+{
+ SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX); /**< BlueNRG not ready for writing */
+ LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_Sleep);
+
+ return;
+}
+
+/**
+ * @brief Closes the SPI when BLE is disabled by the application
+ * Releases allocated resources
+ * @param None
+ * @retval None
+ */
+void BNRG_SPI_Close(void)
+{
+#ifdef ENABLE_SPI_FIX
+ TIMER_Delete(StartupTimerId);
+#endif
+ TIMER_Delete(TxRxTimerId);
+
+ return;
+}
+
+/**
+ * @brief Initializes the SPI communication with the BlueNRG Shield.
+ * @param None
+ * @retval None
+ */
+void BNRG_SPI_Init(void)
+{
+ BNRG_MSP_SPI_Init(&SpiHandle);
+
+ SPI_Context.hspi = &SpiHandle;
+
+ SPI_Context.Spi_Peripheral_State = SPI_AVAILABLE;
+ SPI_Context.SPI_Transmit_Context.RequestPending = FALSE;
+
+ __HAL_BLUENRG_SPI_ENABLE_DMAREQ(&SpiHandle, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);
+
+ __HAL_SPI_ENABLE(&SpiHandle);
+
+#ifdef ENABLE_SPI_FIX
+ TIMER_Create(eTimerModuleID_Interrupt, &StartupTimerId, eTimerMode_SingleShot, TimerStartupCallback);
+#endif
+ TIMER_Create(eTimerModuleID_Interrupt, &TxRxTimerId, eTimerMode_SingleShot, TimerTxRxCallback);
+ return;
+}
+
+/**
+ * @brief Initializes the SPI communication with the BlueNRG Shield
+ * @param None
+ * @retval None
+ */
+void BNRG_MSP_SPI_Init(SPI_HandleTypeDef * hspi)
+{
+ hspi->Instance = BNRG_SPI_INSTANCE;
+ hspi->Init.Mode = BNRG_SPI_MODE;
+ hspi->Init.Direction = BNRG_SPI_DIRECTION;
+ hspi->Init.DataSize = BNRG_SPI_DATASIZE;
+ hspi->Init.CLKPolarity = BNRG_SPI_CLKPOLARITY;
+ hspi->Init.CLKPhase = BNRG_SPI_CLKPHASE;
+ hspi->Init.NSS = BNRG_SPI_NSS;
+ hspi->Init.FirstBit = BNRG_SPI_FIRSTBIT;
+ hspi->Init.TIMode = BNRG_SPI_TIMODE;
+ hspi->Init.CRCPolynomial = BNRG_SPI_CRCPOLYNOMIAL;
+ hspi->Init.BaudRatePrescaler = BNRG_SPI_BAUDRATEPRESCALER;
+ hspi->Init.CRCCalculation = BNRG_SPI_CRCCALCULATION;
+
+ HAL_SPI_Init(hspi);
+
+ return;
+}
+
+/**
+ * @brief Resets the BlueNRG.
+ * @param None
+ * @retval None
+ */
+void BlueNRG_RST(void)
+{
+ uint8_t ubnRFResetTimerID;
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ GPIO_InitStruct.Pin = BNRG_SPI_RESET_PIN;
+ GPIO_InitStruct.Speed = BNRG_SPI_RESET_SPEED;
+ TIMER_Create(eTimerModuleID_Interrupt, &ubnRFResetTimerID, eTimerMode_SingleShot, pf_nRFResetTimerCallBack);
+
+ BNRG_SPI_RESET_CLK_ENABLE();
+
+ HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET);
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);
+
+ TIMER_Start(ubnRFResetTimerID, BLUENRG_HOLD_TIME_IN_RESET);
+ ubnRFresetTimerLock = 1;
+ while(ubnRFresetTimerLock == 1);
+
+ HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_SET);
+
+#if 1
+ /*
+ * Limitation in HAL V1.1.0
+ * The HAL_GPIO_Init() is first configuring the Mode of the IO before the Pull UP configuration
+ * To avoid glitch on the IO, the configuration shall go through an extra step OUTPUT/PULLUP
+ * to set upfront the PULL UP configuration.
+ */
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);
+#endif
+
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);
+
+ TIMER_Start(ubnRFResetTimerID, BLUENRG_HOLD_TIME_AFTER_RESET);
+ ubnRFresetTimerLock = 1;
+ while(ubnRFresetTimerLock == 1);
+ TIMER_Delete(ubnRFResetTimerID);
+
+ return;
+}
+
+/**
+ * @brief Writes data from local buffer to SPI.
+ * @param hspi: SPI handle
+ * @param header_data: First data buffer to be written
+ * @param payload_data: Second data buffer to be written
+ * @param header_size: Size of first data buffer to be written
+ * @param payload_size: Size of second data buffer to be written
+ * @retval Number of read bytes
+ */
+void BlueNRG_SPI_Write(uint8_t* header_data, uint8_t* payload_data, uint8_t header_size, uint8_t payload_size)
+{
+ SPI_Context.SPI_Transmit_Context.header_data = header_data;
+ SPI_Context.SPI_Transmit_Context.payload_data = payload_data;
+ SPI_Context.SPI_Transmit_Context.header_size = header_size;
+ SPI_Context.SPI_Transmit_Context.payload_size = payload_size;
+
+ SPI_Context.SPI_Transmit_Context.packet_cont = FALSE;
+
+ __disable_irq();
+ if(SPI_Context.Spi_Peripheral_State == SPI_AVAILABLE)
+ {
+ SPI_Context.Spi_Peripheral_State = SPI_BUSY;
+ Disable_SPI_Receiving_Path();
+ __enable_irq();
+ WakeupBlueNRG();
+ }
+ else
+ {
+ SPI_Context.SPI_Transmit_Context.RequestPending = TRUE;
+ __enable_irq();
+ }
+
+ return;
+}
+
+/**
+ * @brief Set in Output mode the IRQ.
+ * @param None
+ * @retval None
+ */
+static void set_irq_as_output(void)
+{
+ HAL_GPIO_WritePin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN, GPIO_PIN_SET);
+ HAL_LPPUART_GPIO_Set_Mode(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN_POSITION, GPIO_MODE_OUTPUT_PP);
+ __HAL_GPIO_EXTI_CLEAR_IT(BNRG_SPI_IRQ_PIN);
+}
+
+/**
+ * @brief Set the IRQ in input mode.
+ * @param None
+ * @retval None
+ */
+static void set_irq_as_input(void)
+{
+ HAL_GPIO_WritePin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN, GPIO_PIN_RESET); // WARNING: it may conflict with BlueNRG driving High
+ HAL_LPPUART_GPIO_Set_Mode(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN_POSITION, GPIO_MODE_INPUT);
+}
+
+/**
+ * @brief Enable SPI IRQ.
+ * @param None
+ * @retval None
+ */
+static void Enable_SPI_Receiving_Path(void)
+{
+ __HAL_GPIO_EXTI_CLEAR_IT(BNRG_SPI_EXTI_PIN);
+ HAL_NVIC_ClearPendingIRQ(BNRG_SPI_EXTI_IRQn);
+ HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn);
+
+ if (HAL_GPIO_ReadPin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN) == GPIO_PIN_SET)
+ {
+ __HAL_GPIO_EXTI_GENERATE_SWIT(BNRG_SPI_IRQ_PIN);
+ }
+}
+
+/**
+ * @brief Disable SPI IRQ.
+ * @param None
+ * @retval None
+ */
+static void Disable_SPI_Receiving_Path(void)
+{
+ HAL_NVIC_DisableIRQ(BNRG_SPI_EXTI_IRQn);
+}
+
+/**
+ * @brief Enable SPI CS.
+ * @param None
+ * @retval None
+ */
+static void Enable_SPI_CS(void)
+{
+ /* CS reset */
+ HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET);
+}
+
+/**
+ * @brief Disable SPI CS.
+ * @param None
+ * @retval None
+ */
+static void Disable_SPI_CS(void)
+{
+ while (__HAL_SPI_GET_FLAG(SPI_Context.hspi,SPI_FLAG_BSY) == SET);
+
+ /* CS set */
+ HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
+}
+
+/**
+ * @brief Disable and Enable SPI CS.
+ * @param None
+ * @retval None
+ */
+static void DisableEnable_SPI_CS(void)
+{
+ while (__HAL_SPI_GET_FLAG(SPI_Context.hspi,SPI_FLAG_BSY) == SET);
+
+ /* CS set */
+ HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
+
+ /* CS reset */
+ HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET);
+}
+
+/**
+ * @brief Tx and Rx Transfer completed callbacks
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+void BlueNRG_DMA_RxCallback(void)
+{
+ uint16_t byte_count;
+ uint8_t ready_state;
+
+ __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmarx, BNRG_SPI_RX_DMA_TC_FLAG);
+
+ /**
+ * The TCIF shall be cleared to be able to start a new DMA transmission later on when required.
+ * When receiving data, the TCIE is not set as there is no need to handle the interrupt
+ * handler of the DMA_Tx.
+ * The TCIF clearing is mandatory on STM32F4 but not on STM32L0.
+ * In order to keep code identical across platform, the TCIF clearing may be kept as well on
+ * the STM32L0 and all other MCUs.
+ */
+ __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG);
+ switch (SPI_Context.SPI_Receive_Context.Spi_Receive_Event)
+ {
+ case SPI_CHECK_RECEIVED_HEADER_FOR_RX:
+ byte_count = (Received_Header[4]<<8)|Received_Header[3];
+ ready_state = Received_Header[0];
+
+ if ((byte_count == 0) || (ready_state != BLUENRG_READY_STATE))
+ {
+ if (HAL_GPIO_ReadPin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN) == GPIO_PIN_RESET)
+ {
+ /**
+ * This USE CASE shall never happen as this may break the IRQ/CS specification
+ * The IRQ line shall never be low when CS is low to avoid BlueNRG race condition when
+ * entering low power mode
+ * the SPI_END_RECEIVE_FIX has been implemented to make sure this USE CASE never occurs
+ * However, even when the behavior is not compliant to the specification, the BlueNRG
+ * may not fail so it is increasing robustness by adding this checking just in case the
+ * timeout define in the workaround is too short which will end up to marginally brake
+ * the specification.
+ * This checking will poping BluenRG for a dummy even
+ */
+
+ /* Release CS line */
+ Disable_SPI_CS();
+
+ LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_LP_Stop);
+
+ ReceiveClosure();
+ }
+ else
+ {
+ DisableEnable_SPI_CS();
+ SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_RX); /**< BlueNRG not ready for reading */
+ }
+ }
+ else
+ {
+ SPI_Receive_Manager(SPI_REQUEST_PAYLOAD); /**< BlueNRG is ready for reading */
+ }
+ break;
+
+ case SPI_RECEIVE_END:
+ /* Release CS line */
+ Disable_SPI_CS();
+
+ LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_LP_Stop);
+
+#if (SPI_END_RECEIVE_FIX == 1)
+ pTimerTxRxCallback = ProcessEndOfReceive;
+ TIMER_Start(TxRxTimerId, SPI_END_RECEIVE_FIX_TIMEOUT);
+#else
+ ProcessEndOfReceive();
+#endif
+ break;
+
+ case SPI_CHECK_RECEIVED_HEADER_FOR_TX:
+ byte_count = (Received_Header[2]<<8)|Received_Header[1];
+ ready_state = Received_Header[0];
+
+ if ((byte_count == 0) || (ready_state != BLUENRG_READY_STATE))
+ {
+ DisableEnable_SPI_CS();
+ SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX); /**< BlueNRG not ready for writing */
+ }
+ else
+ {
+#if (TEST_TX_BUFFER_LIMITATION == 1)
+ if(byte_count > MAX_TX_BUFFER_SIZE)
+ {
+ byte_count = MAX_TX_BUFFER_SIZE;
+ }
+#endif
+
+ if(SPI_Context.SPI_Transmit_Context.packet_cont != TRUE)
+ {
+ if( byte_count < (SPI_Context.SPI_Transmit_Context.header_size + SPI_Context.SPI_Transmit_Context.payload_size))
+ {
+ SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = byte_count - SPI_Context.SPI_Transmit_Context.header_size;
+ SPI_Context.SPI_Transmit_Context.payload_size -= SPI_Context.SPI_Transmit_Context.payload_size_to_transmit;
+ SPI_Context.SPI_Transmit_Context.packet_cont = TRUE;
+ }
+ else
+ {
+ SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = SPI_Context.SPI_Transmit_Context.payload_size;
+ }
+
+ SPI_Transmit_Manager(SPI_HEADER_TRANSMIT);
+ }
+ else
+ {
+ if( byte_count < SPI_Context.SPI_Transmit_Context.payload_size)
+ {
+ SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = byte_count;
+ SPI_Context.SPI_Transmit_Context.payload_size -= SPI_Context.SPI_Transmit_Context.payload_size_to_transmit;
+ }
+ else
+ {
+ SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = SPI_Context.SPI_Transmit_Context.payload_size;
+ SPI_Context.SPI_Transmit_Context.payload_size = 0;
+ }
+
+ SPI_Transmit_Manager(SPI_PAYLOAD_TRANSMIT);
+ }
+ }
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+#ifdef ENABLE_SPI_FIX
+/**
+ * @brief Wakeup BlueNRG
+ * @param None
+ * @retval None
+ */
+static void WakeupBlueNRG(void)
+{
+ Disable_SPI_Receiving_Path();
+ pTimerTxRxCallback = TimerTransmitCallback;
+ set_irq_as_output();
+ TIMER_Start(StartupTimerId, SPI_FIX_TIMEOUT);
+ TIMER_Start(TxRxTimerId, SPI_FIX_TIMEOUT+SPI_TX_TIMEOUT);
+ LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_LP_Stop);
+
+ return;
+}
+
+/**
+ * @brief Timer callback to apply timeout SPI FIX
+ * @param None
+ * @retval None
+ */
+static void TimerStartupCallback(void)
+{
+ Enable_SPI_CS();
+
+ return;
+}
+
+#else
+/**
+ * @brief Wakeup BlueNRG
+ * @param None
+ * @retval None
+ */
+static void WakeupBlueNRG(void)
+{
+ Disable_SPI_Receiving_Path();
+ pTimerTxRxCallback = TimerTransmitCallback;
+ Enable_SPI_CS();
+ TIMER_Start(TxRxTimerId, SPI_TX_TIMEOUT);
+ LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_LP_Stop);
+
+ return;
+}
+#endif /* ENABLE_SPI_FIX */
+
+/**
+ * @brief Tx and Rx Transfer completed callbacks
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+void BlueNRG_DMA_TxCallback(void)
+{
+ __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG);
+
+ switch (SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event)
+ {
+ case SPI_HEADER_TRANSMITTED:
+ if(SPI_Context.SPI_Transmit_Context.payload_size_to_transmit != 0)
+ {
+ SPI_Transmit_Manager(SPI_PAYLOAD_TRANSMIT);
+ }
+ else
+ {
+ TransmitClosure();
+ }
+ break;
+
+ case SPI_PAYLOAD_TRANSMITTED:
+ if( (SPI_Context.SPI_Transmit_Context.packet_cont == TRUE) && (SPI_Context.SPI_Transmit_Context.payload_size != 0))
+ {
+ SPI_Context.SPI_Transmit_Context.payload_data += SPI_Context.SPI_Transmit_Context.payload_size_to_transmit;
+ DisableEnable_SPI_CS();
+ SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX);
+ }
+ else
+ {
+ TransmitClosure();
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return;
+}
+
+/**
+ * @brief Close the transmit mechanism after packet has been sent
+ * Wait for the event to come back
+ * @param None
+ * @retval None
+ */
+static void TransmitClosure(void)
+{
+ LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_LP_Stop);
+ SPI_Context.Spi_Peripheral_State = SPI_AVAILABLE;
+ Disable_SPI_CS();
+ /*
+ * Disable both DMA
+ */
+ __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
+ __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
+ Enable_SPI_Receiving_Path();
+
+ return;
+}
+
+/**
+ * @brief Manage the SPI transmit
+ * @param TransmitRequest: the transmit request
+ * @retval None
+ */
+static void SPI_Transmit_Manager(SPI_TRANSMIT_REQUEST_t TransmitRequest)
+{
+ /*
+ * Disable both DMA
+ */
+ __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
+ __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
+
+ __HAL_DMA_DISABLE_IT(SPI_Context.hspi->hdmarx, DMA_IT_TC); /**< Disable Receive packet notification */
+
+ __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG); /**< Clear flag in DMA */
+ HAL_NVIC_ClearPendingIRQ(BNRG_SPI_DMA_TX_IRQn); /**< Clear DMA pending bit in NVIC */
+ __HAL_DMA_ENABLE_IT(SPI_Context.hspi->hdmatx, DMA_IT_TC); /**< Enable Transmit packet notification */
+
+ __HAL_BLUENRG_DMA_SET_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send Tx packet */
+
+ switch (TransmitRequest)
+ {
+ case SPI_HEADER_TRANSMIT:
+ SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event = SPI_HEADER_TRANSMITTED;
+
+#ifdef ENABLE_SPI_FIX
+ set_irq_as_input();
+#endif
+
+ __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, SPI_Context.SPI_Transmit_Context.header_size); /**< Set counter in DMA TX */
+ __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)SPI_Context.SPI_Transmit_Context.header_data); /**< Set memory address in DMA TX */
+ break;
+
+ case SPI_PAYLOAD_TRANSMIT:
+ SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event = SPI_PAYLOAD_TRANSMITTED;
+
+ __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, SPI_Context.SPI_Transmit_Context.payload_size_to_transmit); /**< Set counter in DMA TX */
+ __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)SPI_Context.SPI_Transmit_Context.payload_data); /**< Set memory address in DMA TX */
+ break;
+
+ default:
+ break;
+ }
+
+ __HAL_DMA_ENABLE(SPI_Context.hspi->hdmatx); /**< Enable DMA TX */
+
+}
+
+/**
+ * @brief Manage the SPI receive
+ * @param ReceiveRequest: the receive request
+ * @retval None
+ */
+static void SPI_Receive_Manager(SPI_RECEIVE_REQUEST_t ReceiveRequest)
+{
+ uint16_t byte_count;
+ uint8_t localloop;
+
+ /*
+ * Disable both DMA
+ */
+ __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
+ __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
+
+ /**
+ * Flush the Rx register or FIFO
+ */
+ for (localloop = 0 ; localloop < SPI_FIFO_RX_DEPTH ; localloop++)
+ {
+ *(volatile uint8_t*)__HAL_BLUENRG_SPI_GET_RX_DATA_REGISTER_ADDRESS(SPI_Context.hspi);
+ }
+
+ __HAL_DMA_ENABLE_IT(SPI_Context.hspi->hdmarx, DMA_IT_TC); /**< Enable Receive packet notification */
+ __HAL_DMA_DISABLE_IT(SPI_Context.hspi->hdmatx, DMA_IT_TC); /**< Disable Transmit packet notification */
+
+ switch (ReceiveRequest)
+ {
+ case SPI_REQUEST_VALID_HEADER_FOR_RX:
+ ReceiveHeader(SPI_CHECK_RECEIVED_HEADER_FOR_RX, (uint8_t *)Read_Header_CMD);
+ break;
+
+ case SPI_REQUEST_VALID_HEADER_FOR_TX:
+ ReceiveHeader(SPI_CHECK_RECEIVED_HEADER_FOR_TX, (uint8_t *)Write_Header_CMD);
+ break;
+
+ case SPI_REQUEST_PAYLOAD:
+ SPI_Context.SPI_Receive_Context.Spi_Receive_Event = SPI_RECEIVE_END;
+
+ /*
+ * Check data to received is not available buffer size
+ */
+ byte_count = (Received_Header[4]<<8)|Received_Header[3];
+ if (byte_count > SPI_Context.SPI_Receive_Context.buffer_size)
+ {
+ byte_count = SPI_Context.SPI_Receive_Context.buffer_size;
+ }
+ SPI_Context.SPI_Receive_Context.payload_len = byte_count;
+
+ __HAL_BLUENRG_DMA_CLEAR_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send same Byte */
+
+ /*
+ * Set counter in both DMA
+ */
+ __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmarx, byte_count);
+ __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, byte_count);
+
+ /*
+ * Set memory address in both DMA
+ */
+ __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmarx, (uint32_t)SPI_Context.SPI_Receive_Context.buffer);
+ __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)&dummy_bytes);
+ break;
+
+ default:
+ break;
+ }
+
+ /*
+ * Enable both DMA - Rx First
+ */
+ __HAL_DMA_ENABLE(SPI_Context.hspi->hdmarx);
+ __HAL_DMA_ENABLE(SPI_Context.hspi->hdmatx);
+
+ return;
+}
+
+/**
+ * @brief Receive header
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void ReceiveHeader(SPI_RECEIVE_EVENT_t ReceiveEvent, uint8_t * DataHeader)
+{
+ SPI_Context.SPI_Receive_Context.Spi_Receive_Event = ReceiveEvent;
+
+ __HAL_BLUENRG_DMA_SET_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send Tx packet */
+
+ /*
+ * Set counter in both DMA
+ */
+ __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, HEADER_SIZE);
+ __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmarx, HEADER_SIZE);
+
+ /*
+ * Set memory address in both DMA
+ */
+ __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmarx, (uint32_t)Received_Header);
+ __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)DataHeader);
+
+ return;
+}
+
+/**
+ * @brief BlueNRG SPI request event
+ * @param buffer: the event
+ * @param buff_size: the event size
+ * @retval None
+ */
+void BlueNRG_SPI_Request_Events(uint8_t *buffer, uint8_t buff_size)
+{
+ SPI_Context.SPI_Receive_Context.buffer = buffer;
+ SPI_Context.SPI_Receive_Context.buffer_size = buff_size;
+
+ Enable_SPI_Receiving_Path();
+
+ return;
+}
+
+/**
+ * @brief BlueNRG SPI IRQ Callback
+ * @param None
+ * @retval None
+ */
+void BlueNRG_SPI_IRQ_Callback(void)
+{
+ __disable_irq();
+ if(SPI_Context.Spi_Peripheral_State == SPI_AVAILABLE)
+ {
+ SPI_Context.Spi_Peripheral_State = SPI_BUSY;
+ __enable_irq();
+ Enable_SPI_CS();
+ SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_RX);
+ LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_Sleep);
+ }
+ else
+ {
+ __enable_irq();
+ }
+}
+
+#endif /* __DMA_LP__ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/platform/src/btle.cpp Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,440 @@
+/* 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 "Utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* C File Includes ------------------------------------------------------------------*/
+// ANDREA: Updated includes and changed some types (e.g., tHalUint8 --> uint8_t)
+#include <stdio.h>
+#include <string.h>
+#include "hci.h"
+#include "hci_const.h"
+#include "bluenrg_aci.h"
+#include "bluenrg_hal_aci.h"
+#include "bluenrg_gap.h"
+#include "bluenrg_utils.h"
+
+#include "hal_types.h"
+#include "hal.h"
+#include "gp_timer.h"
+#include "osal.h"
+#include "sm.h"
+#include "debug_platform.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#define IDB04A1 0
+#define IDB05A1 1
+
+// static void btle_handler(/*ble_evt_t * p_ble_evt*/);
+void HCI_Input(tHciDataPacket * hciReadPacket);
+
+//#define BDADDR_SIZE 6
+//tHalUint8 bdaddr[BDADDR_SIZE]= {0xaa, 0x00, 0x00, 0xE1, 0x80, 0x02};
+
+uint16_t g_gap_service_handle = 0;
+uint16_t g_appearance_char_handle = 0;
+uint16_t g_device_name_char_handle = 0;
+
+/* Private variables ---------------------------------------------------------*/
+volatile uint8_t set_connectable = 1;
+// ANDREA
+uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */
+
+Gap::Address_t bleAddr;
+Gap::AddressType_t addr_type = Gap::ADDR_TYPE_PUBLIC;
+
+/**************************************************************************/
+/*!
+ @brief Initialises BTLE and the underlying HW/Device
+ @param isSetAddress boolean if address has been set
+ @param mosi MOSI Pin
+ @param miso MISO Pin
+ @param sclk clock Pin
+ @returns void
+*/
+/**************************************************************************/
+void btle_init(bool isSetAddress)
+{
+ DEBUG("btle_init>>\n\r");
+
+ int ret;
+ uint8_t hwVersion;
+ uint16_t fwVersion;
+ uint16_t service_handle, dev_name_char_handle, appearance_char_handle;
+
+ /* Delay needed only to be able to acces the JTAG interface after reset
+ if it will be disabled later. */
+ Clock_Wait(500);
+
+ /* Initialize the BlueNRG HCI */
+ HCI_Init();
+
+ /* 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;
+ }
+
+ /* The Nucleo board must be configured as SERVER */
+ //check if isSetAddress is set than set address.
+ // ANDREA
+ if(isSetAddress)
+ {
+ BlueNRGGap::getInstance().getAddress(&addr_type, bleAddr);
+
+ Gap::Address_t bdaddr;
+ Osal_MemCpy(bdaddr, bleAddr, BDADDR_SIZE);
+
+ ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
+ CONFIG_DATA_PUBADDR_LEN,
+ bdaddr);
+ } else {
+
+ const Gap::Address_t BLE_address_BE = {0xFD,0x00,0x25,0xAA,0x02,0x04};
+ BlueNRGGap::getInstance().setAddress(Gap::ADDR_TYPE_PUBLIC, BLE_address_BE);
+
+ ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
+ CONFIG_DATA_PUBADDR_LEN,
+ BLE_address_BE);
+ }
+
+ ret = aci_gatt_init();
+ if(ret){
+ PRINTF("GATT_Init failed.\n");
+ }
+ //GAP is always in PERIPHERAL _ROLE as mbed does not support Master role at the moment
+ if (bnrg_expansion_board == IDB05A1) {
+ ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle);
+ } else {
+ ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle);
+ }
+
+ if(ret != BLE_STATUS_SUCCESS){
+ PRINTF("GAP_Init failed.\n");
+ }
+
+ //ANDREA -- 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) {
+ DEBUG("Auth Req set successfully.\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);*/
+
+ return;
+}
+
+void User_Process()
+{
+ if(set_connectable){
+ setConnectable();
+ set_connectable = FALSE;
+ }
+}
+
+void setConnectable(void)
+{
+ tBleStatus ret;
+
+ const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'};
+
+ /* disable scan response */
+ hci_le_set_scan_resp_data(0,NULL);
+
+ //int t = BlueNRGGap::getInstance()::ADV_IND;// advType;
+
+ ret = aci_gap_set_discoverable(BlueNRGGap::getInstance().ADV_IND, 0, 0, PUBLIC_ADDR, NO_WHITE_LIST_USE,
+ sizeof(local_name), local_name, 0, NULL, 0, 0);
+ if (ret != BLE_STATUS_SUCCESS) {
+ DEBUG("Error while setting discoverable mode (%d)\n", ret);
+ }
+
+}
+
+/**************************************************************************/
+/*!
+ @brief Not Used
+
+ @param[in] void
+
+ @returns
+*/
+/**************************************************************************/
+/*
+static void btle_handler()
+{
+
+}
+*/
+
+/*!
+ @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(uint16_t attr_handle, uint8_t data_length, uint8_t *att_data, uint8_t offset)
+{
+ //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::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE;
+ DEBUG("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]);
+ DEBUG("getProperties 0x%x\n\r",p_char->getProperties());
+ if(attr_handle == charHandle+CHAR_VALUE_OFFSET) {
+ currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE;
+ }
+
+ if(attr_handle == charHandle+CHAR_DESC_OFFSET) {
+ currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE;
+ }
+ DEBUG("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) {
+
+ DEBUG("*****NOTIFICATION CASE\n\r");
+ //Now Check if data written in Enable or Disable
+ if((uint16_t)att_data[0]==1) {
+ //DEBUG("Notify ENABLED\n\r");
+ BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, p_char->getValueAttribute().getHandle());
+ } else {
+ //DEBUG("Notify DISABLED\n\r");
+ BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, p_char->getValueAttribute().getHandle());
+ }
+ }
+
+ //Check is attr handle property is WRITEABLE, if yes, 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) {
+
+ DEBUG("*****WRITE CASE\n\r");
+
+ GattWriteCallbackParams writeParams;
+ writeParams.handle = p_char->getValueAttribute().getHandle();
+ writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG?
+ writeParams.len = data_length;
+ writeParams.data = att_data;
+ if (bnrg_expansion_board == IDB05A1) {
+ writeParams.offset = offset;
+ }
+ BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams);
+
+ //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, evt->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().getInitialLength() > 0)) {
+ BlueNRGGattServer::getInstance().write(p_char->getValueAttribute().getHandle(), (uint8_t*)att_data, data_length, false);
+ }
+ }
+ }
+
+}
+
+#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:
+ {
+ DEBUG("EVT_DISCONN_COMPLETE\n");
+
+ evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt;
+
+ BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, BlueNRGGap::REMOTE_USER_TERMINATED_CONNECTION);
+ }
+ break;
+
+ case EVT_LE_META_EVENT:
+ {
+ DEBUG("EVT_LE_META_EVENT\n");
+
+ evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data;
+
+ switch(evt->subevent){
+ // ANDREA
+ case EVT_LE_CONN_COMPLETE:
+ {
+ Gap::AddressType_t peerAddrType = Gap::ADDR_TYPE_PUBLIC;
+ DEBUG("EVT_LE_CONN_COMPLETE\n");
+
+ evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data;
+
+ BlueNRGGap::getInstance().setConnectionHandle(cc->handle);
+ BlueNRGGap::ConnectionParams_t connectionParams;
+ BlueNRGGap::getInstance().getPreferredConnectionParams(&connectionParams);
+ switch (cc->peer_bdaddr_type) {
+ case PUBLIC_ADDR:
+ peerAddrType = Gap::ADDR_TYPE_PUBLIC;
+ break;
+ case STATIC_RANDOM_ADDR:
+ peerAddrType = Gap::ADDR_TYPE_RANDOM_STATIC;
+ break;
+ case RESOLVABLE_PRIVATE_ADDR:
+ peerAddrType = Gap::ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
+ break;
+ case NON_RESOLVABLE_PRIVATE_ADDR:
+ peerAddrType = Gap::ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE;
+ break;
+ }
+ BlueNRGGap::getInstance().processConnectionEvent(cc->handle, Gap::PERIPHERAL, peerAddrType, cc->peer_bdaddr, addr_type, bleAddr, (const BlueNRGGap::ConnectionParams_t *)&connectionParams);
+ }
+ break;
+ }
+ }
+ break;
+
+ case EVT_VENDOR:
+ {
+ evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data;
+ //DEBUG("EVT_VENDOR %d\n", blue_evt->ecode);
+
+ switch(blue_evt->ecode){
+
+ case EVT_BLUE_GATT_READ_PERMIT_REQ:
+ {
+ DEBUG("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r");
+ evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data;
+ BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle-CHAR_VALUE_OFFSET);
+ }
+ break;
+
+ case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED:
+ {
+ DEBUG("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r");
+ /* this callback is invoked when a GATT attribute is modified
+ extract callback data and pass to suitable handler function */
+ if (bnrg_expansion_board == IDB05A1) {
+ evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data;
+ Attribute_Modified_CB(evt->attr_handle, evt->data_length, evt->att_data, evt->offset);
+ } else {
+ evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data;
+ Attribute_Modified_CB(evt->attr_handle, evt->data_length, evt->att_data, 0);
+ }
+ }
+ break;
+
+ //Any cases for Data Sent Notifications?
+ case EVT_BLUE_GATT_NOTIFICATION:
+ //This is only relevant for Client Side Event
+ DEBUG("EVT_BLUE_GATT_NOTIFICATION");
+ break;
+ case EVT_BLUE_GATT_INDICATION:
+ //This is only relevant for Client Side Event
+ DEBUG("EVT_BLUE_GATT_INDICATION");
+ break;
+
+ case EVT_BLUE_GATT_PROCEDURE_COMPLETE:
+ DEBUG("EVT_BLUE_GATT_PROCEDURE_COMPLETE");
+ break;
+ }
+ }
+ break;
+ }
+
+ return ;
+ }
+
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/platform/src/clock.c Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,34 @@
+
+#include "clock.h"
+#include "wait_api.h"
+#include "rtc_time.h"
+
+const uint32_t CLOCK_SECOND = 1000;
+
+/*---------------------------------------------------------------------------*/
+
+void Clock_Init(void)
+{
+ //Not Used
+}
+
+/*---------------------------------------------------------------------------*/
+
+tClockTime Clock_Time(void)
+{
+ return clock();
+}
+
+/*---------------------------------------------------------------------------*/
+/**
+ * Wait for a multiple of 1 ms.
+ *
+ */
+void Clock_Wait(uint32_t i)
+{
+ wait_ms(i);
+}
+/*---------------------------------------------------------------------------*/
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/utils/src/Payload.cpp Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,101 @@
+/* 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 <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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/utils/src/Utils.cpp Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,129 @@
+/* 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 "Utils.h"
+
+#if NEED_CONSOLE_OUTPUT
+Serial pc(USBTX, USBRX);
+#endif /* #if NEED_CONSOLE_OUTPUT */
+
+/**************************************************************************/
+/*!
+ @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power
+
+ @returns value of tx power in dbm actually set
+
+ @params[in] dBMLevel
+ dBMLevel of tx power to be set
+
+ @params[in] dBMLevel
+ dBMLevel of tx power to be set
+
+ @endcode
+*/
+/**************************************************************************/
+double getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) {
+ double dbm = (double) dBMLevel;
+ if(dbm<-18.0) {
+ dbm = -18;
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 0;
+ }
+ else if(dbm>8.0) {
+ dbm = 8;
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 7;
+ }
+
+ // As a policy we are setting tx power level to the higher side
+ if((dbm>-18.0) && (dbm<=-15)) {
+ // set tx power to -15dBM
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 0;
+ }
+ else if((dbm>-15) && (dbm<=-14.7)) {
+ // set tx power to -14.7dBM
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 1;
+ }
+ else if((dbm>-14.7) && (dbm<=-11.7)) {
+ // set tx power to -11.7dBM
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 1;
+ }
+ else if((dbm>-11.7) && (dbm<=-11.4)) {
+ // set tx power to -11.4dBM
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 2;
+ }
+ else if((dbm>-11.4) && (dbm<=-8.4)) {
+ // set tx power to -8.4dBM
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 2;
+ }
+ else if((dbm>-8.4) && (dbm<=-8.1)) {
+ // set tx power to -8.1dBM
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 3;
+ }
+ else if((dbm>-8.1) && (dbm<=-5.1)) {
+ // set tx power to -5.1dBM
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 3;
+ }
+ else if((dbm>-5.1) && (dbm<=-4.9)) {
+ // set tx power to -4.9dBM
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 4;
+ }
+ else if((dbm>-4.9) && (dbm<=-2.1)) {
+ // set tx power to -2.1dBM
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 4;
+ }
+ else if((dbm>-2.1) && (dbm<=-1.6)) {
+ // set tx power to -1.6dBM
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 5;
+ }
+ else if((dbm>-1.6) && (dbm<=1.4)) {
+ // set tx power to -1.6dBM
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 5;
+ }
+ else if((dbm>1.4) && (dbm<=1.7)) {
+ // set tx power to 1.7dBM
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 6;
+ }
+ else if((dbm>1.7) && (dbm<=4.7)) {
+ // set tx power to 4.7dBM
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 6;
+ }
+ else if((dbm>4.7) && (dbm<=5.0)) {
+ // set tx power to 5.0dBM
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 7;
+ }
+ else if((dbm>5.0) && (dbm<=8)) {
+ // set tx power to 8.0dBM
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 7;
+ }
+
+ return dbm;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRGDevice.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,100 @@
+/* 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"
+
+#include "mbed.h"
+#include "blecommon.h"
+#include "BLE.h"
+#include "BlueNRGGap.h"
+#include "BlueNRGGattServer.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(void);
+ 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 *gattClient;
+ }
+
+ virtual SecurityManager& getSecurityManager() {
+ return *sm;
+ }
+
+ virtual const SecurityManager& getSecurityManager() const {
+ return *sm;
+ }
+ ble_error_t reset(void);
+ bool getIsInitialized(void);
+
+ 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();
+
+private:
+ bool isInitialized;
+
+ SPI spi_;
+ DigitalOut nCS_;
+ DigitalOut rst_;
+ InterruptIn irq_;
+
+ //FIXME: TBI (by now just placeholders to let build
+ /*** betzw: placeholders ***/
+ GattClient *gattClient;
+ SecurityManager *sm;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRGGap.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,154 @@
+/* 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__
+
+#include "mbed.h"
+#include "blecommon.h"
+#include "btle.h"
+#include "GapAdvertisingParams.h"
+#include "GapAdvertisingData.h"
+#include <ble/Gap.h>
+
+#define BLE_CONN_HANDLE_INVALID 0x0
+#define BDADDR_SIZE 6
+
+#define BLUENRG_GAP_ADV_INTERVAL_MIN (0)
+#define BLUENRG_GAP_ADV_INTERVAL_MAX (0)
+#define BLE_GAP_ADV_NONCON_INTERVAL_MIN (0)
+
+#define UUID_BUFFER_SIZE 13 //6*2(16-bit UUIDs)+1
+#define ADV_DATA_MAX_SIZE 31
+
+/**************************************************************************/
+/*!
+ \brief
+
+*/
+/**************************************************************************/
+class BlueNRGGap : public Gap
+{
+public:
+ static BlueNRGGap &getInstance() {
+ static BlueNRGGap m_instance;
+ return m_instance;
+ }
+
+ // <<<ANDREA>>>
+ enum AdvType_t {
+ ADV_IND = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED,//Gap::ADV_IND,
+ ADV_DIRECT_IND = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED,//Gap::ADV_DIRECT_IND,
+ ADV_SCAN_IND = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED,//Gap::ADV_SCAN_IND,
+ ADV_NONCONN_IND = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED//Gap::ADV_NONCONN_IND
+ };
+
+ /* Functions that must be implemented from Gap */
+ virtual ble_error_t setAddress(addr_type_t type, const Address_t address);
+ virtual ble_error_t getAddress(addr_type_t *typeP, Address_t address);
+ virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &);
+ virtual ble_error_t startAdvertising(const GapAdvertisingParams &);
+ virtual ble_error_t stopAdvertising(void);
+ virtual ble_error_t stopScan();
+ virtual uint16_t getMinAdvertisingInterval(void) const;
+ virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const;
+ virtual uint16_t getMaxAdvertisingInterval(void) const;
+ 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 setTxPower(int8_t txPower);
+ virtual void getPermittedTxPowerValues(const int8_t **, size_t *);
+ // <<<ANDREA>>>
+
+
+ void setConnectionHandle(uint16_t con_handle);
+ uint16_t getConnectionHandle(void);
+
+ //tHalUint8* getAddress();
+ bool getIsSetAddress();
+
+ Timeout getAdvTimeout(void) const {
+ return advTimeout;
+ }
+ uint8_t getAdvToFlag(void) {
+ return AdvToFlag;
+ }
+ void setAdvToFlag(void);
+
+ void Process(void);
+
+protected:
+ virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams);
+
+private:
+ uint16_t m_connectionHandle;
+ uint8_t bdaddr[BDADDR_SIZE];
+ bool isSetAddress;
+ tBleStatus ret; // FIXME: delete this
+ uint8_t *DeviceName;
+ uint8_t deviceAppearance[2];
+
+ uint8_t *local_name;
+ uint8_t local_name_length;
+
+ bool txPowerAdType;
+
+ uint8_t servUuidlength;
+ uint8_t servUuidData[UUID_BUFFER_SIZE];
+
+ uint8_t AdvLen;
+ uint8_t AdvData[ADV_DATA_MAX_SIZE];
+
+ Timeout advTimeout;
+ bool AdvToFlag;
+
+ BlueNRGGap() {
+ m_connectionHandle = BLE_CONN_HANDLE_INVALID;
+ isSetAddress = false;
+ DeviceName = NULL;
+ }
+
+ BlueNRGGap(BlueNRGGap const &);
+ void operator=(BlueNRGGap const &);
+};
+
+#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRGGattServer.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,119 @@
+/* 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>
+ */
+
+// ANDREA: Changed some types (e.g., tHalUint8 --> uint8_t)
+
+#ifndef __BLUENRG_GATT_SERVER_H__
+#define __BLUENRG_GATT_SERVER_H__
+
+#include "mbed.h"
+#include "blecommon.h"
+#include "btle.h"
+#include "GattService.h"
+#include "ble/GattServer.h"
+#include <vector>
+#include <map>
+
+#define BLE_TOTAL_CHARACTERISTICS 10
+
+// If the char has handle 'x', then the value declaration will have the handle 'x+1'
+// If the char has handle 'x', then the char descriptor declaration will have the handle 'x+2'
+#define CHAR_VALUE_OFFSET 1
+#define CHAR_DESC_OFFSET 2
+
+using namespace std;
+
+class BlueNRGGattServer : public GattServer
+{
+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 */
+ // <<<ANDREA>>>
+ virtual ble_error_t addService(GattService &);
+ virtual ble_error_t readValue(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
+ virtual ble_error_t readValue(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;
+ }
+ // <<<ANDREA>>>
+
+ /* BlueNRG Functions */
+ void eventCallback(void);
+ //void hwCallback(void *pckt);
+ ble_error_t Read_Request_CB(uint16_t handle);
+ 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:
+ static const int MAX_SERVICE_COUNT = 10;
+ uint8_t serviceCount;
+ uint8_t characteristicCount;
+ uint16_t servHandle, charHandle;
+
+ std::map<uint16_t, uint16_t> bleCharHanldeMap; // 1st argument is characteristic, 2nd argument is service
+ GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS];
+ uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS];
+
+ BlueNRGGattServer() {
+ serviceCount = 0;
+ characteristicCount = 0;
+ };
+
+ BlueNRGGattServer(BlueNRGGattServer const &);
+ void operator=(BlueNRGGattServer const &);
+
+ static const int CHAR_DESC_TYPE_16_BIT=0x01;
+ static const int CHAR_DESC_TYPE_128_BIT=0x02;
+ static const int CHAR_DESC_SECURITY_PERMISSION=0x00;
+ static const int CHAR_DESC_ACCESS_PERMISSION=0x03;
+ static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/ble_status.h Tue Oct 06 14:25:08 2015 +0200
@@ -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 <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__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_aci.h Tue Oct 06 14:25:08 2015 +0200 @@ -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__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_aci_const.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,764 @@
+/******************** (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 "compiler.h"
+#include "link_layer.h"
+#include "hci_const.h"
+#include "bluenrg_gatt_server.h"
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+#define OCF_HAL_WRITE_CONFIG_DATA 0x000C
+
+#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_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_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_gap.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,224 @@
+/******************** (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 <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)
+
+/**
+ * @}
+ */
+
+#define MAX_ADV_DATA_LEN (31)
+
+#define DEVICE_NAME_LEN (7)
+#define BD_ADDR_SIZE (6)
+
+/**
+ * @name Privacy flag values
+ * @{
+ */
+#define PRIVACY_ENABLED (0x01)
+#define PRIVACY_DISABLED (0x00)
+/**
+ * @}
+ */
+
+/**
+ * @name Intervals
+ * Intervals in terms of 625 micro sec
+ * @{
+ */
+#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/
+#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/
+#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/
+#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/
+#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/
+#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/
+#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/
+#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/
+/**
+ * @}
+ */
+
+/**
+ * @name Timeout values
+ * @{
+ */
+#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */
+#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */
+/**
+ * @}
+ */
+
+/**
+ * @anchor gap_roles
+ * @name GAP Roles
+ * @{
+*/
+#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01)
+#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02)
+#define GAP_CENTRAL_ROLE_IDB05A1 (0x04)
+#define GAP_OBSERVER_ROLE_IDB05A1 (0x08)
+
+#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01)
+#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02)
+#define GAP_CENTRAL_ROLE_IDB04A1 (0x03)
+#define GAP_OBSERVER_ROLE_IDB04A1 (0x04)
+/**
+ * @}
+ */
+
+/**
+ * @anchor gap_procedure_codes
+ * @name GAP procedure codes
+ * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event
+ * and aci_gap_terminate_gap_procedure() command.
+ * @{
+ */
+#define GAP_LIMITED_DISCOVERY_PROC (0x01)
+#define GAP_GENERAL_DISCOVERY_PROC (0x02)
+#define GAP_NAME_DISCOVERY_PROC (0x04)
+#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08)
+#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10)
+#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20)
+#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40)
+#define GAP_OBSERVATION_PROC_IDB05A1 (0x80)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_gap_aci.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,1211 @@
+/******************** (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 (1.28 s and 2.56 s respectively).
+ * 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)/0.625,
+ * (ADV_INTERVAL_MAX_MS*1000)/0.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.
+ * @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.
+ * @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.
+ * 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. 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 GATT 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_IDB05A1(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__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_gatt_aci.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,1045 @@
+/******************** (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.
+ * @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
+ * @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 uint8_t *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 uint8_t *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;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_gatt_server.h Tue Oct 06 14:25:08 2015 +0200
@@ -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 "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__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_hal_aci.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,157 @@
+/******************** (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 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 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. */
+
+/**
+ * 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__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_l2cap_aci.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,162 @@
+/******************** (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)
+
+/**
+ * The event is given by the L2CAP layer when a connection update request is received from the slave.
+ * The application has to respond by calling aci_l2cap_connection_parameter_update_response().
+ */
+#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802)
+typedef __packed struct _evt_l2cap_conn_upd_req{
+/**
+ * Handle of the connection for which the connection update request has been received.
+ * The same handle has to be returned while responding to the event with the command
+ * aci_l2cap_connection_parameter_update_response().
+ */
+ uint16_t conn_handle;
+ uint8_t event_data_length; /**< Length of following data. */
+/**
+ * This is the identifier which associates the request to the
+ * response. The same identifier has to be returned by the upper
+ * layer in the command aci_l2cap_connection_parameter_update_response().
+ */
+ uint8_t identifier;
+ uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */
+ uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */
+ uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */
+ uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */
+ uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */
+} PACKED evt_l2cap_conn_upd_req;
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_updater_aci.h Tue Oct 06 14:25:08 2015 +0200
@@ -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 <compiler.h>
+
+/**
+ * @defgroup Updater Updater
+ * @brief Updater.
+ * @{
+ */
+
+/**
+ * @defgroup Updater_Functions Updater functions
+ * @brief API for BlueNRG Updater.
+ * @{
+ */
+
+tBleStatus aci_updater_start(void);
+
+tBleStatus aci_updater_reboot(void);
+
+tBleStatus aci_get_updater_version(uint8_t *version);
+
+tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size);
+
+tBleStatus aci_erase_blue_flag(void);
+
+tBleStatus aci_reset_blue_flag(void);
+
+tBleStatus aci_updater_erase_sector(uint32_t address);
+
+tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data);
+
+tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data);
+
+tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc);
+
+tBleStatus aci_updater_hw_version(uint8_t *version);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Updater_Events Updater events
+ * @{
+ */
+/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */
+#define EVT_BLUE_INITIALIZED (0x0001)
+typedef __packed struct _evt_blue_initialized{
+ uint8_t reason_code;
+} PACKED evt_blue_initialized;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+
+#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_utils.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,197 @@
+/******************** (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 "hal_types.h"
+#include "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 Verifies if the bootloader is patched or not. This function shall be used to fix a bug on
+ * the HW bootloader related to the 32 MHz external crystal oscillator.
+ * @retval TRUE if the HW bootloader is already patched, FALSE otherwise
+ */
+uint8_t isHWBootloader_Patched(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__BLUENRG_UTILS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/clock.h Tue Oct 06 14:25:08 2015 +0200 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : 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 <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__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/compiler.h Tue Oct 06 14:25:08 2015 +0200 @@ -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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/debug.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,73 @@
+/**
+ ******************************************************************************
+ * @file 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****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/gp_timer.h Tue Oct 06 14:25:08 2015 +0200
@@ -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 "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__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/hal.h Tue Oct 06 14:25:08 2015 +0200 @@ -0,0 +1,106 @@ +/******************** (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 <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 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__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/hal.h.orig Tue Oct 06 14:25:08 2015 +0200 @@ -0,0 +1,110 @@ +/******************** (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 <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 + */ +<<<<<<< HEAD +//void Hal_Write_Serial(const void* data1, const void* data2, uint16_t n_bytes1, uint16_t n_bytes2); +======= +>>>>>>> 28b9b0106ee91324c03989cd8e448f4f4073ef81 +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 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__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/hal_types.h Tue Oct 06 14:25:08 2015 +0200 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : 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__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/hci.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,239 @@
+/******************** (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 "hal_types.h"
+#include "link_layer.h"
+#include <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_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_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/hci_const.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,564 @@
+/******************************************************************************
+*
+* 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 "compiler.h"
+#include "hal_types.h"
+#include "clock.h"
+#include "link_layer.h"
+
+#include "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];
+} 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_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/link_layer.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,163 @@
+/******************** (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
+ * @{
+ */
+
+// <<<ANDREA: commented defines (see BlueNRGGap.h)>>>
+/**
+ * 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)
+// <<<ANDREA>>>
+
+/**
+ * @}
+ */
+
+/* 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/list.h Tue Oct 06 14:25:08 2015 +0200
@@ -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_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/osal.h Tue Oct 06 14:25:08 2015 +0200 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : 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 <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__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/BlueNRG_HCI/includes/sm.h Tue Oct 06 14:25:08 2015 +0200
@@ -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__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/platform/X-NUCLEO-IDB04A1/stm32_bluenrg_ble.h Tue Oct 06 14:25:08 2015 +0200
@@ -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 "gp_timer.h"
+#include "hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup X-NUCLEO-IDB04A1
+ * @{
+ */
+
+/** @addtogroup STM32_BLUENRG_BLE
+ * @{
+ */
+
+/** @defgroup STM32_BLUENRG_BLE_Exported_Functions
+ * @{
+ */
+
+// FIXME: add prototypes for BlueNRG here
+void BlueNRG_RST(void);
+uint8_t BlueNRG_DataPresent(void);
+void BlueNRG_HW_Bootloader(void);
+int32_t BlueNRG_SPI_Read_All(uint8_t *buffer,
+ uint8_t buff_size);
+int32_t BlueNRG_SPI_Write(uint8_t* data1,
+ uint8_t* data2,
+ uint8_t Nb_bytes1,
+ uint8_t Nb_bytes2);
+void Clear_SPI_EXTI_Flag(void);
+
+void print_csv_time(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32_BLUENRG_BLE_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/platform/X-NUCLEO-IDB04A1/stm32_bluenrg_ble_dma_lp.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,152 @@
+/**
+ ******************************************************************************
+ * @file stm32_bluenrg_ble_dma_lp.h
+ * @author CL
+ * @version V1.0.0
+ * @date 04-July-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_DMA_LP_H
+#define __STM32_BLUENRG_BLE_DMA_LP_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#ifdef USE_STM32F4XX_NUCLEO
+ #include "stm32f4xx_hal.h"
+ #include "stm32f4xx_nucleo.h"
+ #include "stm32f4xx_nucleo_bluenrg_dma_lp.h"
+ #include "stm32f4xx_hal_bluenrg_gpio.h"
+ #include "stm32f4xx_hal_bluenrg_spi.h"
+ #include "stm32f4xx_hal_bluenrg_dma.h"
+#endif /* USE_STM32F4XX_NUCLEO */
+
+#ifdef USE_STM32L0XX_NUCLEO
+ #include "stm32l0xx_hal.h"
+ #include "stm32l0xx_nucleo.h"
+ #include "stm32l0xx_nucleo_bluenrg_dma_lp.h"
+ #include "stm32l0xx_hal_bluenrg_gpio.h"
+ #include "stm32l0xx_hal_bluenrg_spi.h"
+ #include "stm32l0xx_hal_bluenrg_dma.h"
+#endif /* USE_STM32L0XX_NUCLEO */
+
+#include "stm32xx_lpm.h"
+#include "stm32xx_timerserver.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup X-NUCLEO-IDB04A1
+ * @{
+ */
+
+/** @addtogroup STM32_BLUENRG_BLE_DMA_LP
+ * @{
+ */
+
+/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Exported_Constants
+ * @{
+ */
+
+#define SPI_END_RECEIVE_FIX 1 /**< Need some delay after receiving an event to prevent dummy read */
+
+ /**
+ * All timeout below are given in term of Ticks of the TimerServer.
+ * The tick of the timerserver depends on the LPO clock used as input and the
+ * prescaler of the wakeup timer.
+ * In order to get the most efficient implementation, the wakeuptimer prescaler should divide
+ * the input clock by 2
+ *
+ * The values below are based on the LSI clock @37Kz.
+ * For this, the tick is 54us
+ */
+#define SPI_FIX_TIMEOUT 2 /**< 150 us - Note: 2 ticks result into more than 2*54us due to some inaccuracies and latencies */
+#define SPI_TX_TIMEOUT 3 /**< Value to be tuned to prevent trying to send a command to BlueNRG if it is not yet woken up */
+#define SPI_END_RECEIVE_FIX_TIMEOUT 2
+#define BLUENRG_HOLD_TIME_IN_RESET 1
+#define BLUENRG_HOLD_TIME_AFTER_RESET 93 /**< 5ms */
+
+/**
+ * When the SPI does not have any FIFO (STM32L0, etc...), this parameter should be set to 1
+ * When the SPI does have a FIFO, this parameter shall be set to the size of the FIFO in bytes (STM32L4 = 4)
+ */
+#define SPI_FIFO_RX_DEPTH 1
+
+/**
+ * @}
+ */
+
+/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Exported_Functions
+ * @{
+ */
+// FIXME: add prototypes for BlueNRG here
+void BNRG_SPI_Close(void);
+void BNRG_SPI_Init(void);
+void BlueNRG_RST(void);
+void BlueNRG_SPI_Write(uint8_t* header_data,
+ uint8_t* payload_data,
+ uint8_t header_size,
+ uint8_t payload_size);
+void BlueNRG_SPI_Request_Events(uint8_t *buffer, uint8_t buff_size);
+void BlueNRG_DMA_RxCallback(void);
+void BlueNRG_DMA_TxCallback(void);
+void BlueNRG_SPI_IRQ_Callback(void);
+void BNRG_MSP_SPI_Init(SPI_HandleTypeDef * hspi);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32_BLUENRG_BLE_DMA_LP_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/platform/inc/btle.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,50 @@
+/* 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 "hci.h"
+#include "bluenrg_aci.h"
+#include "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;
+
+void btle_init(bool isSetAddress);
+void SPI_Poll(void);
+void User_Process(void);
+void setConnectable(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/platform/inc/debug_platform.h Tue Oct 06 14:25:08 2015 +0200 @@ -0,0 +1,14 @@ +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <string.h> + +//#define DEBUG + +#ifdef DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/utils/inc/Payload.h Tue Oct 06 14:25:08 2015 +0200
@@ -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.
+*/
+
+#include "mbed.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();
+ 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; 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; }
+
+
+};
+
+#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/x-nucleo-idb0xa1/utils/inc/Utils.h Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,57 @@
+/* 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 "hal_types.h"
+#include "mbed.h"
+
+#define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console; */
+ /*it will have an impact on code-size and power consumption. */
+
+#if NEED_CONSOLE_OUTPUT
+//Serial usb(USBTX, USBRX); // tx, rx
+extern Serial pc;
+#define DEBUG(...) { pc.printf(__VA_ARGS__); }
+#else
+#define DEBUG(...) /* nothing */
+#endif /* #if NEED_CONSOLE_OUTPUT */
+
+#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)
+
+
+double getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL);
+
+#endif // __UTIL_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/x_nucleo_idb0xa1_targets.h Tue Oct 06 14:25:08 2015 +0200 @@ -0,0 +1,67 @@ +/** + ****************************************************************************** + * @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 beyond macro 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. +*/ +//#define IDB0XA1_D13_PATCH + +#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) + +#endif // _X_NUCLEO_IDB0XA1_TARGETS_H_
