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.
Dependencies: mbed
Revision 0:599bc564478b, committed 2018-06-29
- Comitter:
- bpd227
- Date:
- Fri Jun 29 01:19:08 2018 +0000
- Commit message:
- first
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/.gitignore Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,33 @@ +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a + +# Executables +*.exe +*.out +*.app + +.yotta.json +build/ +yotta_modules/ +yotta_targets/ +.DS_Store
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/.mbed Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +ROOT=.
Binary file mbed-os-example-ble-master/BLE_BatteryLevel/img/connection.png has changed
Binary file mbed-os-example-ble-master/BLE_BatteryLevel/img/discovery.png has changed
Binary file mbed-os-example-ble-master/BLE_BatteryLevel/img/notifications.png has changed
Binary file mbed-os-example-ble-master/BLE_BatteryLevel/img/register_to_notifications.png has changed
Binary file mbed-os-example-ble-master/BLE_BatteryLevel/img/scan_result.png has changed
Binary file mbed-os-example-ble-master/BLE_BatteryLevel/img/start_scan.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/mbed-os.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/mbed_app.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "target_overrides": { + "K64F": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "NUCLEO_F401RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "DISCO_L475VG_IOT01A": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "ble-batterylevel", + "version": "0.0.1", + "description": "An example of creating and updating a simple GATT Service using the BLE_API", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "dependencies": { + "ble": "^2.0.0" + }, + "targetDependencies": {}, + "bin": "./source" +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/readme.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,68 @@ +This example creates and updates a standard Battery Level service containing a single +GATT characteristic. + +The [battery service transmits](https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml) a device's battery level in percentage, with 100% being a fully charged battery and 0% being a fully drained battery. + +Although the sample application runs on a BLE device, it doesn't show the device's real battery level (because that changes very slowly and will make for a dull example). Instead, it transmits a fake battery level that starts at 50% (half charged). Every half second, it increments the battery level, going in single increments until reaching 100% (as if the battery is charging). It then drops down to 20% to start incrementing again. + +# Running the application + +## Requirements + +The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : + +- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. + +- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Checking for success + +**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. + +1. Build the application and install it on your board as explained in the building instructions. +1. Open the BLE scanner on your phone. +1. Start a scan. + +  + + **figure 1** How to start scan using nRF Master Control Panel 4.0.5 + +1. Find your device; it should be named `BATTERY`. + +  + + **figure 2** Scan results using nRF Master Control Panel 4.0.5 + +1. Establish a connection with your device. + +  + + **figure 3** How to establish a connection using Master Control Panel 4.0.5 + +1. Discover the services and the characteristics on the device. The *Battery service* has the UUID 0x180F and includes the *Battery level* characteristic which has the UUID 0x2A19. + +  + + **figure 4** Representation of the Battery service using Master Control Panel 4.0.5 + +1. Register for the notifications sent by the *Battery level* characteristic. + +  + + **figure 5** How to register to notifications using Master Control Panel 4.0.5 + + +1. You should see the battery level value change every half second. It begins at 50, goes up to 100 (in steps of 1), resets to 20 and so on. + +  + + **figure 6** Notifications view using Master Control Panel 4.0.5 + +If you can see the characteristic, and if its value is incrementing correctly, the application is working properly. +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/#b630517008bbe47592927cc8e5dfcd2e5b9de968
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/.gitignore Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,9 @@ +# vim temporary files +*.sw* + +# yotta files +build +yotta_modules +yotta_targets +.yotta.json +upload.tar.gz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,34 @@ +# BLE-X-NUCLEO-IDB0XA1 + +BLE_API wrapper Library for X-NUCLEO-IDB05A1 BlueNRG (Bluetooth Low Energy) Expansion Board + +## Introduction + +This firmware package implements the port of BLE_API to STMicroelectronics' [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) Bluetooth Low Energy Nucleo Expansion Board. + +### Arduino Connector Compatibility Warning + +X-NUCLEO-IDB05A1 is Arduino compatible with an exception: instead of using pin **D13** for the SPI clock, pin **D3** is used. +The default configuration for this library is having the SPI clock on pin **D3**. + +To be fully Arduino compatible, X-NUCLEO-IDB05A1 needs a small HW patch. + +For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor **R4** and instead soldering zero resistor **R6**. + +In case you patch your board, then you also have to configure this library to use pin **D13** to drive the SPI clock. To this aim you need to compile this driver with macro `BLUENRG_PIN_SPI_SCK=D13` defined. + +If you use pin **D13** for the SPI clock, please be aware that on STM32 Nucleo boards you may **not** drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin **D13**. + +Referring to the current list of tested platforms (see [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) page), the patch is required by [ST-Nucleo-F103RB](https://developer.mbed.org/platforms/ST-Nucleo-F103RB/); [ST-Nucleo-F302R8](https://developer.mbed.org/platforms/ST-Nucleo-F302R8/); [ST-Nucleo-F411RE](https://developer.mbed.org/platforms/ST-Nucleo-F411RE/); [ST-Nucleo-F446RE](https://developer.mbed.org/platforms/ST-Nucleo-F446RE/); and [FRDM-K64F](https://developer.mbed.org/platforms/FRDM-K64F/). + +### Firmware update + +For better performance and compatibility with latest mbed API, you should update firmware of X-NUCLEO-IDB05A1 component by using this simple [application](https://developer.mbed.org/teams/ST/code/BlueNRG-MS-Stack-Updater). + +### Driver configuration + +In order to use the BlueNRG-MS module together with other targets, you need to set the macros defined in file [bluenrg_targets.h](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/bluenrg/bluenrg_targets.h). Please, update the [mbed_lib.json](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/mbed_lib.json) to include the list of extra macros that configure the driver for your target. + +## Example Applications + +To run BLE example applications using X-NUCLEO-IDB05A1 Expansion Board based on mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli), please refer to section [Using ST shield on other targets](https://github.com/ARMmbed/mbed-os-example-ble#using-st-nucleo-shield-on-other-targets) in the official [mbed-os-example-ble](https://github.com/ARMmbed/mbed-os-example-ble) page.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.h + * @author STMicroelectronics + * @brief Header file for BLEDeviceInstanceBase based BlueNRGDevice + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_DEVICE_H__ +#define __BLUENRG_DEVICE_H__ + +#define BLUENRG +#define DEBUG_BLUENRG_USER + +#include "btle.h" + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "ble/BLEInstanceBase.h" +#include "ble/BLE.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" + + +class BlueNRGDevice : public BLEInstanceBase +{ + +public: + BlueNRGDevice(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, PinName irq); + virtual ~BlueNRGDevice(void); + + virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback); + virtual ble_error_t shutdown(void); + virtual const char *getVersion(void); + virtual Gap& getGap(); + virtual const Gap& getGap() const; + virtual GattServer& getGattServer(); + virtual const GattServer& getGattServer() const; + virtual void waitForEvent(void); + + virtual GattClient& getGattClient() { + return BlueNRGGattClient::getInstance(); + } + + virtual SecurityManager& getSecurityManager() { + return *sm; + } + + virtual const SecurityManager& getSecurityManager() const { + return *sm; + } + void reset(void); + virtual bool hasInitialized(void) const { + return isInitialized; + } + + uint8_t getUpdaterHardwareVersion(uint8_t *hw_version); + int updateFirmware(const uint8_t *fw_image, uint32_t fw_size); + bool dataPresent(); + int32_t spiRead(uint8_t *buffer, uint8_t buff_size); + int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2); + void disable_irq(); + void enable_irq(); + + virtual void processEvents(); + +private: + bool isInitialized; + + SPI spi_; + DigitalOut nCS_; + DigitalOut rst_; + InterruptIn irq_; + + //FIXME: TBI (by now just placeholders to let build + /*** betzw: placeholders ***/ + SecurityManager *sm; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ +#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ + +#include "ble/DiscoveredCharacteristic.h" + +class BlueNRGGattClient; /* forward declaration */ + +class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic { +public: + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + + void setLastHandle(GattAttribute::Handle_t lastHandleIn); +}; + +#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGGap.h + * @author STMicroelectronics + * @brief Header file for BlueNRG BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GAP_H__ +#define __BLUENRG_GAP_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/Gap.h" + +#define BLE_CONN_HANDLE_INVALID 0x0 +#define BDADDR_SIZE 6 + +#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020) +#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000) +#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0) + +// Scanning and Connection Params used by Central for creating connection +#define GAP_OBSERVATION_PROC (0x80) + +#define SCAN_P (0x0010) +#define SCAN_L (0x0010) +#define SUPERV_TIMEOUT (0xC80) +#define CONN_P(x) ((int)((x)/1.25f)) +#define CONN_L(x) ((int)((x)/0.625f)) +#define CONN_P1 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_P2 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_L1 (0x0008) +#define CONN_L2 (0x0008) +#define GUARD_INT 5 //msec +#define MIN_INT_CONN 0x0006 //=>7.5msec +#define MAX_INT_CONN 0x0C80 //=>4000msec +#define DEF_INT_CONN 0x0140 //=>400msec (default value for connection interval) + +/**************************************************************************/ +/*! + \brief + +*/ +/**************************************************************************/ +class BlueNRGGap : public Gap +{ +public: + static BlueNRGGap &getInstance() { + static BlueNRGGap m_instance; + return m_instance; + } + + enum Reason_t { + DEVICE_FOUND, + DISCOVERY_COMPLETE + }; + + /* Functions that must be implemented from Gap */ + virtual ble_error_t setAddress(addr_type_t type, const BLEProtocol::AddressBytes_t address); + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address); + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &); + virtual ble_error_t startAdvertising(const GapAdvertisingParams &); + virtual ble_error_t stopAdvertising(void); + virtual ble_error_t stopScan(); + virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);} + virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);} + virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);} + virtual ble_error_t disconnect(DisconnectionReason_t reason); + virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason); + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params); + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); + + virtual ble_error_t setDeviceName(const uint8_t *deviceName); + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); + virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance); + virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP); + + virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode); + virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode); + virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const; + virtual ScanningPolicyMode_t getScanningPolicyMode(void) const; + + virtual ble_error_t setTxPower(int8_t txPower); + virtual void getPermittedTxPowerValues(const int8_t **, size_t *); + + virtual ble_error_t connect(const Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams); + + virtual ble_error_t reset(void); + + void Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI); + ble_error_t createConnection(void); + + void setConnectionHandle(uint16_t con_handle); + uint16_t getConnectionHandle(void); + + bool getIsSetAddress(); + + // ADV timeout handling + Timeout& getAdvTimeout(void) { + return advTimeout; + } + uint8_t getAdvToFlag(void) { + return AdvToFlag; + } + void setAdvToFlag(void); + + // SCAN timeout handling + Timeout& getScanTimeout(void) { + return scanTimeout; + } + uint8_t getScanToFlag(void) { + return ScanToFlag; + } + void setScanToFlag(void); + + void Process(void); + + GapScanningParams* getScanningParams(void); + + virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams); + + void setConnectionInterval(uint16_t interval); + Gap::Role_t getGapRole(void); + void setGapRole(Gap::Role_t role); + +private: + uint16_t m_connectionHandle; + Role_t gapRole; + AddressType_t addr_type; + Address_t _peerAddr; + AddressType_t _peerAddrType; + uint8_t bdaddr[BDADDR_SIZE]; + bool _scanning; + bool _connecting; + bool isSetAddress; + uint8_t deviceAppearance[2]; + + // ADV timeout handling + Timeout advTimeout; + bool AdvToFlag; + + // SCAN timeout handling + Timeout scanTimeout; + bool ScanToFlag; + + static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) { + return (duration * 625) / 1000; + } + + uint16_t scanInterval; + uint16_t scanWindow; + uint16_t advInterval; + uint16_t slaveConnIntervMin; + uint16_t slaveConnIntervMax; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + void setAdvParameters(void); + void setConnectionParameters(void); + + Gap::AdvertisingPolicyMode_t advertisingPolicyMode; + Gap::ScanningPolicyMode_t scanningPolicyMode; + + Whitelist_t whitelistAddresses; + + ble_error_t updateAdvertisingData(void); + + BlueNRGGap() : AdvToFlag(false), ScanToFlag(false) { + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + addr_type = BLEProtocol::AddressType::RANDOM_STATIC; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + isSetAddress = false; + memset(deviceAppearance, 0, sizeof(deviceAppearance)); + } + + BlueNRGGap(BlueNRGGap const &); + void operator=(BlueNRGGap const &); + + GapAdvertisingData _advData; + GapAdvertisingData _scanResponse; +}; + +#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,157 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattClient.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CLIENT_H__ +#define __BLUENRG_GATT_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattConnectionClient.h" + +using namespace std; + +#define MAX_ACTIVE_CONNECTIONS 7 + +class BlueNRGGattClient : public GattClient +{ +public: + static BlueNRGGattClient &getInstance() { + static BlueNRGGattClient m_instance; + return m_instance; + } + + ble_error_t createGattConnectionClient(Gap::Handle_t connectionHandle); + ble_error_t removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason); + + /* Functions that must be implemented from GattClient */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + virtual bool isServiceDiscoveryActive(void) const; + virtual void terminateServiceDiscovery(void); + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback); + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + virtual ble_error_t write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + virtual ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + virtual ble_error_t reset(void); + + void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code); + + void primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(Gap::Handle_t connectionHandle); + + void serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length); + + +protected: + + BlueNRGGattClient(): _connectionPool() {}; + + ServiceDiscovery::TerminationCallback_t terminationCallback; + +private: + + BlueNRGGattClient(BlueNRGGattClient const &); + void operator=(BlueNRGGattClient const &); + + BlueNRGGattConnectionClient *_connectionPool[MAX_ACTIVE_CONNECTIONS]; + uint8_t _numConnections; + + BlueNRGGattConnectionClient * getGattConnectionClient(Gap::Handle_t connectionHandle); + +}; + +#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,185 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattConnectionClient.cpp + * @author STMicroelectronics + * @brief Header file for BlueNRGGattConnectionClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CONNECTION_CLIENT_H__ +#define __BLUENRG_GATT_CONNECTION_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" + +using namespace std; + +#define BLE_TOTAL_DISCOVERED_SERVICES 10 +#define BLE_TOTAL_DISCOVERED_CHARS 10 + +class BlueNRGGattConnectionClient +{ +public: + + enum { + GATT_IDLE, + GATT_SERVICE_DISCOVERY, + GATT_CHAR_DESC_DISCOVERY, + //GATT_CHARS_DISCOVERY_COMPLETE, + //GATT_DISCOVERY_TERMINATED, + GATT_READ_CHAR, + GATT_WRITE_CHAR + }; + + /* Functions that must be implemented from GattClient */ + ble_error_t launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + bool isServiceDiscoveryActive(void) const; + void terminateServiceDiscovery(void); + void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + } + ble_error_t read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + ble_error_t write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + ble_error_t reset(void); + + void gattProcedureCompleteCB(uint8_t error_code); + + void primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(void); + + void serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(uint8_t event_data_length); + +protected: + + BlueNRGGattConnectionClient(BlueNRGGattClient *gattClient, Gap::Handle_t connectionHandle): + discoveredService(), + discoveredChar(), + readCBParams(), + writeCBParams(), + _characteristic() { + + //PRINTF("BlueNRGGattConnectionClient construtor: connHandle=%d\n\r", connectionHandle); + + _gattClient = gattClient; + _connectionHandle = connectionHandle; + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + } + + ServiceDiscovery::ServiceCallback_t serviceDiscoveryCallback; + ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback; + ServiceDiscovery::TerminationCallback_t terminationCallback; + CharacteristicDescriptorDiscovery::DiscoveryCallback_t charDescDiscoveryCallback; + CharacteristicDescriptorDiscovery::TerminationCallback_t charDescTerminationCallback; + +private: + + BlueNRGGattConnectionClient(BlueNRGGattConnectionClient const &); + void operator=(BlueNRGGattConnectionClient const &); + ~BlueNRGGattConnectionClient() {}; + + BlueNRGGattClient *_gattClient; + + Gap::Handle_t _connectionHandle; + DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES]; + BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS]; + + GattReadCallbackParams readCBParams; + GattWriteCallbackParams writeCBParams; + + // The char for which the descriptor discovery has been launched + DiscoveredCharacteristic _characteristic; + + UUID _matchingServiceUUID; + UUID _matchingCharacteristicUUIDIn; + uint8_t _currentState; + uint8_t _numServices, _servIndex; + uint8_t _numChars; + uint8_t _numCharDesc; + + friend class BlueNRGGattClient; +}; + +#endif /* __BLUENRG_GATT_CONNECTION_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_SERVER_H__ +#define __BLUENRG_GATT_SERVER_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattService.h" +#include "ble/GattServer.h" +#include <vector> +#include <map> + +#define BLE_TOTAL_CHARACTERISTICS 10 + +using namespace std; + +class BlueNRGGattServer : public GattServer +{ +public: + static BlueNRGGattServer &getInstance() { + static BlueNRGGattServer m_instance; + return m_instance; + } + + enum HandleEnum_t { + CHAR_HANDLE = 0, + CHAR_VALUE_HANDLE, + CHAR_DESC_HANDLE + }; + + /* Functions that must be implemented from GattServer */ + virtual ble_error_t addService(GattService &); + virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t initializeGATTDatabase(void); + + virtual bool isOnDataReadAvailable() const { + return true; + } + + virtual ble_error_t reset(void); + + /* BlueNRG Functions */ + void eventCallback(void); + //void hwCallback(void *pckt); + ble_error_t Read_Request_CB(uint16_t attributeHandle); + uint8_t Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, + uint8_t data_length, const uint8_t* data + ); + GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle); + void HCIDataWrittenEvent(const GattWriteCallbackParams *params); + void HCIDataReadEvent(const GattReadCallbackParams *params); + void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle); + void HCIDataSentEvent(unsigned count); + +private: + + // compute the number of attribute record needed by a service + static uint16_t computeAttributesRecord(GattService& service); + + + static const int MAX_SERVICE_COUNT = 10; + uint8_t serviceCount; + uint8_t characteristicCount; + uint16_t servHandle, charHandle; + + std::map<uint16_t, uint16_t> bleCharHandleMap; // 1st argument is characteristic, 2nd argument is service + GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS]; + uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS]; + + BlueNRGGattServer() { + serviceCount = 0; + characteristicCount = 0; + }; + + BlueNRGGattServer(BlueNRGGattServer const &); + void operator=(BlueNRGGattServer const &); + + static const int CHAR_DESC_TYPE_16_BIT=0x01; + static const int CHAR_DESC_TYPE_128_BIT=0x02; + static const int CHAR_DESC_SECURITY_PERMISSION=0x00; + static const int CHAR_DESC_ACCESS_PERMISSION=0x03; + static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_CLOCK_H__ +#define __BLE_CLOCK_H__ + +#include <ble_hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __BLE_CLOCK_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file ble_debug.h + * @author CL + * @version V1.0.0 + * @date 04-July-2014 + * @brief This file defines print functions for debug purposes. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLE_DEBUG_H +#define __BLE_DEBUG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> + +/* Exported macro ------------------------------------------------------------*/ +//#define DEBUG +#ifdef DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Print the data travelling over the SPI in the .csv format for the GUI*/ +//#define PRINT_CSV_FORMAT +#ifdef PRINT_CSV_FORMAT +#include <stdio.h> +#define PRINT_CSV(...) printf(__VA_ARGS__) +#else +#define PRINT_CSV(...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __BLE_DEBUG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_gp_timer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : General purpose timer library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_GP_TIMER_H__ +#define __BLE_GP_TIMER_H__ + +#include "ble_clock.h" +#include "ble_status.h" +#ifdef __DMA_LP__ +#include "stm32xx_timerserver.h" +#endif /* __DMA_LP__ */ + +/** + * timer + * + * A structure that represents a timer. Use Timer_Set() to set the timer. + * + */ +struct timer { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + tClockTime start; + tClockTime interval; + +#endif +}; + +typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); + +/** + * Timer_Set + * + * @param[in] t Pointer to a timer structure + * @param[in] interval timeout value + * + * This function sets the timeout value of a timer. + * + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * Timer_Reset + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the time it previously expired. + * + */ +void Timer_Reset(struct timer *t); + +/** + * Timer_Restart + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the current time. + * + */ +void Timer_Restart(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns TRUE if timer is expired, FALSE otherwise. + * + */ +int Timer_Expired(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns the time needed for expiration. + * + * @return Time before timer's expiration. + */ +tClockTime Timer_Remaining(struct timer *t); + +#ifdef __DMA_LP__ +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID); + +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); +#endif /* __DMA_LP__ */ + +#endif /* __BLE_GP_TIMER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,108 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_H__ +#define __BLE_HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void signalEventsToProcess(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __BLE_HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_TYPES_H__ +#define __BLE_HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __BLE_HAL_TYPES_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,126 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.0, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_H_ +#define __BLE_HCI_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ble_hal_types.h" +#include "ble_link_layer.h" +#include <ble_list.h> + +#define HCI_READ_PACKET_SIZE 128 //71 + +/** + * Maximum payload of HCI commands that can be sent. Change this value if needed. + * This value can be up to 255. + */ +#define HCI_MAX_PAYLOAD_SIZE 128 + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_READ_PACKET_SIZE]; + uint8_t data_len; +} tHciDataPacket; + +struct hci_request { + uint16_t ogf; + uint16_t ocf; + int event; + void *cparam; + int clen; + void *rparam; + int rlen; +}; + +typedef enum +{ + BUSY, + AVAILABLE +} HCI_CMD_STATUS_t; + + +/** + * This function must be used to pass the packet received from the HCI + * interface to the BLE Stack HCI state machine. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * + */ +void HCI_Input(tHciDataPacket *hciReadPacket); + +/** + * Initialization function. Must be done before any data can be received from + * BLE controller. + */ +void HCI_Init(void); + +/** + * Callback used to pass events to application. + * + * @param[in] pckt The event. + * + */ +extern void HCI_Event_CB(void *pckt); + +/** + * Processing function that must be called after an event is received from + * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if + * necessary. +*/ +void HCI_Process(void); + +/** + * @brief Check if queue of HCI event is empty or not. + * @note This funtion can be used to check if the event queue from BlueNRG is empty. This + * is useful when checking if it is safe to go to sleep. + * @return TRUE if event queue is empty. FALSE otherwhise. + */ +BOOL HCI_Queue_Empty(void); +/** + * Iterrupt service routine that must be called when the BlueNRG + * reports a packet received or an event to the host through the + * BlueNRG interrupt line. + */ +#ifdef __DMA_LP__ +void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); +void HCI_Process_Notification_Request(void); +void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); +void HCI_Wait_For_Response(void); +#else +void HCI_Isr(void); +void HCI_HandleSPI(void); + +int hci_send_req(struct hci_request *r, BOOL async); +#endif /* __DMA_LP__ */ + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#ifdef __cplusplus +} +#endif + + +#endif /* __BLE_HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,548 @@ +/****************************************************************************** +* +* File Description +* --------------------- +* This file defines constants and functions for HCI layer. +* See Bluetooth Core v 4.0, Vol. 2, Part E. +* +*******************************************************************************/ + +#ifndef __HCI_INTERNAL_H_ +#define __HCI_INTERNAL_H_ + +#include "ble_compiler.h" +#include "ble_hal_types.h" +#include "ble_clock.h" +#include "ble_link_layer.h" +#include "ble_hci.h" + +#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) + + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +typedef __packed struct _hci_uart_pckt{ + uint8_t type; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef __packed struct _hci_command_hdr{ + uint16_t opcode; /* OCF & OGF */ + uint8_t plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef __packed struct _hci_event_pckt{ + uint8_t evt; + uint8_t plen; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef __packed struct _hci_acl_hdr{ + uint16_t handle; /* Handle & Flags(PB, BC) */ + uint16_t dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef __packed struct _disconnect_cp{ + uint16_t handle; + uint8_t reason; +} PACKED disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 + +#define OCF_SET_EVENT_MASK 0x0001 +#define OCF_RESET 0x0003 + +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D +typedef __packed struct _read_transmit_power_level_cp{ + uint16_t handle; + uint8_t type; +} PACKED read_transmit_power_level_cp; +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 +typedef __packed struct _read_transmit_power_level_rp{ + uint8_t status; + uint16_t handle; + int8_t level; +} PACKED read_transmit_power_level_rp; +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 + +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 +#define OCF_HOST_BUFFER_SIZE 0x0033 +#define OCF_HOST_NUM_COMP_PKTS 0x0035 + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef __packed struct _read_local_version_rp{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t manufacturer_name; + uint16_t lmp_pal_subversion; +} PACKED read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_COMMANDS 0x0002 +#define OCF_READ_LOCAL_FEATURES 0x0003 + +#define OCF_READ_BD_ADDR 0x0009 +typedef __packed struct _read_bd_addr_rp{ + uint8_t status; + tBDAddr bdaddr; +} PACKED read_bd_addr_rp; +#define READ_BD_ADDR_RP_SIZE 7 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +#define OCF_READ_RSSI 0x0005 +typedef __packed struct _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef __packed struct _read_rssi_rp{ + uint8_t status; + uint16_t handle; + int8_t rssi; +} PACKED read_rssi_rp; +#define READ_RSSI_RP_SIZE 4 + + +/* LE commands */ +#define OGF_LE_CTL 0x08 + +#define OCF_LE_SET_EVENT_MASK 0x0001 +typedef __packed struct _le_set_event_mask_cp{ + uint8_t mask[8]; +} PACKED le_set_event_mask_cp; +#define LE_SET_EVENT_MASK_CP_SIZE 8 + +#define OCF_LE_READ_BUFFER_SIZE 0x0002 +typedef __packed struct _le_read_buffer_size_rp{ + uint8_t status; + uint16_t pkt_len; + uint8_t max_pkt; +} PACKED le_read_buffer_size_rp; +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 + +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 +typedef __packed struct _le_read_local_supported_features_rp{ + uint8_t status; + uint8_t features[8]; +} PACKED le_read_local_supported_features_rp; +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 + +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 +typedef __packed struct _le_set_random_address_cp{ + tBDAddr bdaddr; +} PACKED le_set_random_address_cp; +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 + +#define OCF_LE_SET_ADV_PARAMETERS 0x0006 +typedef __packed struct _le_set_adv_parameters_cp{ + uint16_t min_interval; + uint16_t max_interval; + uint8_t advtype; + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint8_t chan_map; + uint8_t filter; +} PACKED le_set_adv_parameters_cp; +#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 + +#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 +typedef __packed struct _le_read_adv_channel_tx_power_rp{ + uint8_t status; + int8_t level; +} PACKED le_read_adv_channel_tx_power_rp; +#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 + +#define OCF_LE_SET_ADV_DATA 0x0008 +typedef __packed struct _le_set_adv_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_adv_data_cp; +#define LE_SET_ADV_DATA_CP_SIZE 32 + +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 +typedef __packed struct _le_set_scan_response_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_scan_response_data_cp; +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 + +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A +typedef __packed struct _le_set_advertise_enable_cp{ + uint8_t enable; +} PACKED le_set_advertise_enable_cp; +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 + +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B +typedef __packed struct _le_set_scan_parameters_cp{ + uint8_t type; + uint16_t interval; + uint16_t window; + uint8_t own_bdaddr_type; + uint8_t filter; +} PACKED le_set_scan_parameters_cp; +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 + +#define OCF_LE_SET_SCAN_ENABLE 0x000C +typedef __packed struct _le_set_scan_enable_cp{ + uint8_t enable; + uint8_t filter_dup; +} PACKED le_set_scan_enable_cp; +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 + +#define OCF_LE_CREATE_CONN 0x000D +typedef __packed struct _le_create_connection_cp{ + uint16_t interval; + uint16_t window; + uint8_t initiator_filter; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_create_connection_cp; +#define LE_CREATE_CONN_CP_SIZE 25 + +#define OCF_LE_CREATE_CONN_CANCEL 0x000E + +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F +typedef __packed struct _le_read_white_list_size_rp{ + uint8_t status; + uint8_t size; +} PACKED le_read_white_list_size_rp; +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 + +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 +typedef __packed struct _le_add_device_to_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_add_device_to_white_list_cp; +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 +typedef __packed struct _le_remove_device_from_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_remove_device_from_white_list_cp; +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_CONN_UPDATE 0x0013 +typedef __packed struct _le_connection_update_cp{ + uint16_t handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_connection_update_cp; +#define LE_CONN_UPDATE_CP_SIZE 14 + +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 +typedef __packed struct _le_set_host_channel_classification_cp{ + uint8_t map[5]; +} PACKED le_set_host_channel_classification_cp; +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 + +#define OCF_LE_READ_CHANNEL_MAP 0x0015 +typedef __packed struct _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef __packed struct _le_read_channel_map_rp{ + uint8_t status; + uint16_t handle; + uint8_t map[5]; +} PACKED le_read_channel_map_rp; +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 + +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 +typedef __packed struct _le_read_remote_used_features_cp{ + uint16_t handle; +} PACKED le_read_remote_used_features_cp; +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 + +#define OCF_LE_ENCRYPT 0x0017 +typedef __packed struct _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef __packed struct _le_encrypt_rp{ + uint8_t status; + uint8_t encdata[16]; +} PACKED le_encrypt_rp; +#define LE_ENCRYPT_RP_SIZE 17 + +#define OCF_LE_RAND 0x0018 +typedef __packed struct _le_rand_rp{ + uint8_t status; + uint8_t random[8]; +} PACKED le_rand_rp; +#define LE_RAND_RP_SIZE 9 + +#define OCF_LE_START_ENCRYPTION 0x0019 +typedef __packed struct _le_start_encryption_cp{ + uint16_t handle; + uint8_t random[8]; + uint16_t diversifier; + uint8_t key[16]; +} PACKED le_start_encryption_cp; +#define LE_START_ENCRYPTION_CP_SIZE 28 + +#define OCF_LE_LTK_REPLY 0x001A +typedef __packed struct _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef __packed struct _le_ltk_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_reply_rp; +#define LE_LTK_REPLY_RP_SIZE 3 + +#define OCF_LE_LTK_NEG_REPLY 0x001B +typedef __packed struct _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef __packed struct _le_ltk_neg_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_neg_reply_rp; +#define LE_LTK_NEG_REPLY_RP_SIZE 3 + +#define OCF_LE_READ_SUPPORTED_STATES 0x001C +typedef __packed struct _le_read_supported_states_rp{ + uint8_t status; + uint8_t states[8]; +} PACKED le_read_supported_states_rp; +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 + +#define OCF_LE_RECEIVER_TEST 0x001D +typedef __packed struct _le_receiver_test_cp{ + uint8_t frequency; +} PACKED le_receiver_test_cp; +#define LE_RECEIVER_TEST_CP_SIZE 1 + +#define OCF_LE_TRANSMITTER_TEST 0x001E +typedef __packed struct _le_transmitter_test_cp{ + uint8_t frequency; + uint8_t length; + uint8_t payload; +} PACKED le_transmitter_test_cp; +#define LE_TRANSMITTER_TEST_CP_SIZE 3 + +#define OCF_LE_TEST_END 0x001F +typedef __packed struct _le_test_end_rp{ + uint8_t status; + uint16_t num_pkts; +} PACKED le_test_end_rp; +#define LE_TEST_END_RP_SIZE 3 + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3f + + +/*------------- Events -------------*/ +#define EVT_CONN_COMPLETE 0x03 +typedef __packed struct _evt_conn_complete{ + uint8_t status; + uint16_t handle; + tBDAddr bdaddr; + uint8_t link_type; + uint8_t encr_mode; +} PACKED evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef __packed struct _evt_disconn_complete{ + uint8_t status; + uint16_t handle; + uint8_t reason; +} PACKED evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef __packed struct _evt_encrypt_change{ + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} PACKED evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C + +#define EVT_CMD_COMPLETE 0x0E +typedef __packed struct _evt_cmd_complete{ + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef __packed struct _evt_cmd_status{ + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef __packed struct _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef __packed struct _evt_num_comp_pkts{ + uint8_t num_hndl; + /* variable length part */ +} PACKED evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +/* variable length part of evt_num_comp_pkts. */ +typedef __packed struct _evt_num_comp_pkts_param{ + uint16_t hndl; + uint16_t num_comp_pkts; +} PACKED evt_num_comp_pkts_param; +#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 + +#define EVT_DATA_BUFFER_OVERFLOW 0x1A +typedef __packed struct _evt_data_buffer_overflow{ + uint8_t link_type; +} PACKED evt_data_buffer_overflow; +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 + +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef __packed struct _evt_encryption_key_refresh_complete{ + uint8_t status; + uint16_t handle; +} PACKED evt_encryption_key_refresh_complete; +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 + +#define EVT_LE_META_EVENT 0x3E +typedef __packed struct _evt_le_meta_event{ + uint8_t subevent; + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef __packed struct _evt_le_connection_complete{ + uint8_t status; + uint16_t handle; + uint8_t role; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; +} PACKED evt_le_connection_complete; +#define EVT_LE_CONN_COMPLETE_SIZE 18 + +#define EVT_LE_ADVERTISING_REPORT 0x02 +typedef __packed struct _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t data_length; + uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef __packed struct _evt_le_connection_update_complete{ + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; +} PACKED evt_le_connection_update_complete; +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 + +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +typedef __packed struct _evt_le_read_remote_used_features_complete{ + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} PACKED evt_le_read_remote_used_features_complete; +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 + +#define EVT_LE_LTK_REQUEST 0x05 +typedef __packed struct _evt_le_long_term_key_request{ + uint16_t handle; + uint8_t random[8]; + uint16_t ediv; +} PACKED evt_le_long_term_key_request; +#define EVT_LE_LTK_REQUEST_SIZE 12 + +/** +* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, +* application can use @ref evt_blue_aci structure to parse the packet. +*/ +#define EVT_VENDOR 0xFF + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + + + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); + +typedef enum { + WAITING_TYPE, + WAITING_OPCODE1, + WAITING_OPCODE2, + WAITING_EVENT_CODE, + WAITING_HANDLE, + WAITING_HANDLE_FLAG, + WAITING_PARAM_LEN, + WAITING_DATA_LEN1, + WAITING_DATA_LEN2, + WAITING_PAYLOAD +}hci_state; + +typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); + +/* HCI library functions. */ + +int hci_send_req(struct hci_request *r, BOOL async); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,170 @@ +/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +* File Name : ble_hci_le.h +* Author : AMG RF FW team +* Version : V1.1.0 +* Date : 18-July-2016 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.1, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_LE_H_ +#define __BLE_HCI_LE_H_ + +#include "ble_hal_types.h" +#include "ble_link_layer.h" + +/** + * @defgroup HCI_Error_codes HCI Error codes + * @{ + */ +#define HCI_UNKNOWN_COMMAND 0x01 +#define HCI_NO_CONNECTION 0x02 +#define HCI_HARDWARE_FAILURE 0x03 +#define HCI_PAGE_TIMEOUT 0x04 +#define HCI_AUTHENTICATION_FAILURE 0x05 +#define HCI_PIN_OR_KEY_MISSING 0x06 +#define HCI_MEMORY_FULL 0x07 +#define HCI_CONNECTION_TIMEOUT 0x08 +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a +#define HCI_ACL_CONNECTION_EXISTS 0x0b +#define HCI_COMMAND_DISALLOWED 0x0c +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d +#define HCI_REJECTED_SECURITY 0x0e +#define HCI_REJECTED_PERSONAL 0x0f +#define HCI_HOST_TIMEOUT 0x10 +#define HCI_UNSUPPORTED_FEATURE 0x11 +#define HCI_INVALID_PARAMETERS 0x12 +#define HCI_OE_USER_ENDED_CONNECTION 0x13 +#define HCI_OE_LOW_RESOURCES 0x14 +#define HCI_OE_POWER_OFF 0x15 +#define HCI_CONNECTION_TERMINATED 0x16 +#define HCI_REPEATED_ATTEMPTS 0x17 +#define HCI_PAIRING_NOT_ALLOWED 0x18 +#define HCI_UNKNOWN_LMP_PDU 0x19 +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a +#define HCI_SCO_OFFSET_REJECTED 0x1b +#define HCI_SCO_INTERVAL_REJECTED 0x1c +#define HCI_AIR_MODE_REJECTED 0x1d +#define HCI_INVALID_LMP_PARAMETERS 0x1e +#define HCI_UNSPECIFIED_ERROR 0x1f +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 +#define HCI_UNIT_LINK_KEY_USED 0x26 +#define HCI_QOS_NOT_SUPPORTED 0x27 +#define HCI_INSTANT_PASSED 0x28 +#define HCI_PAIRING_NOT_SUPPORTED 0x29 +#define HCI_TRANSACTION_COLLISION 0x2a +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c +#define HCI_QOS_REJECTED 0x2d +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e +#define HCI_INSUFFICIENT_SECURITY 0x2f +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 +#define HCI_ROLE_SWITCH_PENDING 0x32 +#define HCI_SLOT_VIOLATION 0x34 +#define HCI_ROLE_SWITCH_FAILED 0x35 +#define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 +#define HCI_CONN_REJ_NO_CH_FOUND 0x39 +#define HCI_CONTROLLER_BUSY 0x3A +#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B +#define HCI_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_CONN_TERM_MIC_FAIL 0x3D +#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E +#define HCI_MAC_CONN_FAILED 0x3F +/** + * @} + */ + + +/* + * HCI library functions. + * Each function returns 0 in case of success, otherwise one of the error codes. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(uint8_t enable); + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter); + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter); + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); + +int hci_le_rand(uint8_t random_number[8]); + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); + +int hci_acl_data(const uint8_t * data, uint16_t len); + +int hci_le_set_random_address(tBDAddr bdaddr); + +int hci_read_bd_addr(tBDAddr bdaddr); + +int hci_le_read_white_list_size(uint8_t *size); + +int hci_le_clear_white_list(); + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); + +int hci_le_ltk_request_reply(uint8_t key[16]); + +int hci_le_ltk_request_neg_reply(); + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); + +int hci_le_create_connection_cancel(void); + +int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level); + +int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi); + +int hci_le_read_local_supported_features(uint8_t *features); + +int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); + +int hci_le_read_supported_states(uint8_t states[8]); + +int hci_le_receiver_test(uint8_t frequency); + +int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); + +int hci_le_test_end(uint16_t *num_pkts); + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion); + + + +#endif /* __BLE_HCI_LE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,161 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_link_layer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's link layer. It contains +* definition of functions for link layer, most of which are +* mapped to HCI commands. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef _BLE_LINK_LAYER_H +#define _BLE_LINK_LAYER_H + +#include <ble_status.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + *@name Advertising filter + *Advertising policy for filtering (white list related) + *@{ + */ +#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ +#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ +/** + * @} + */ + + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef uint8_t tBDAddr[6]; + + +/** + *@name Bluetooth address types + * Bluetooth address types + *@{ + */ +#define PUBLIC_ADDR (0) +#define RANDOM_ADDR (1) +#define STATIC_RANDOM_ADDR (1) +#define RESOLVABLE_PRIVATE_ADDR (2) +#define NON_RESOLVABLE_PRIVATE_ADDR (3) +/** + * @} + */ + +/** + *@name Directed advertising types + * Type of advertising during directed advertising + *@{ + */ +#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) +#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) +/** + * @} + */ + +/** + * @name Advertising type + * @{ + */ + +/** + * undirected scannable and connectable + */ +#define ADV_IND (0x00) + +/** + * directed non scannable + */ +#define ADV_DIRECT_IND (0x01) + +/** + * scannable non connectable + */ +#define ADV_SCAN_IND (0x02) + +/** + * non-connectable and no scan response + */ +#define ADV_NONCONN_IND (0x03) + +/** + * scan response + */ +#define SCAN_RSP (0x04) + +/** + * @} + */ + +/* 0X05-0XFF RESERVED */ + +/** + * @name Advertising ranges + * @{ + */ + +/** + * lowest allowed interval value for connectable types(20ms)..multiple of 625us + */ +#define ADV_INTERVAL_LOWEST_CONN (0X0020) + +/** + * highest allowed interval value (10.24s)..multiple of 625us. + */ +#define ADV_INTERVAL_HIGHEST (0X4000) + +/** + * lowest allowed interval value for non connectable types + * (100ms)..multiple of 625us. + */ +#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) + +/** + * @} + */ + +/** + * @name Advertising channels + * @{ + */ +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 +/** + * @} + */ + +/** + * @name Scan_types Scan types + * @{ + */ +#define PASSIVE_SCAN 0 +#define ACTIVE_SCAN 1 +/** + * @} + */ + +/** + * @} + */ + + +#endif /* _BLE_LINK_LAYER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,47 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for linked list library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef _BLE_LIST_H_ +#define _BLE_LIST_H_ + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +uint8_t list_is_empty (tListNode * listHead); + +void list_insert_head (tListNode * listHead, tListNode * node); + +void list_insert_tail (tListNode * listHead, tListNode * node); + +void list_remove_node (tListNode * node); + +void list_remove_head (tListNode * listHead, tListNode ** node ); + +void list_remove_tail (tListNode * listHead, tListNode ** node ); + +void list_insert_node_after (tListNode * node, tListNode * ref_node); + +void list_insert_node_before (tListNode * node, tListNode * ref_node); + +int list_get_size (tListNode * listHead); + +void list_get_next_node (tListNode * ref_node, tListNode ** node); + +void list_get_prev_node (tListNode * ref_node, tListNode ** node); + +#endif /* _BLE_LIST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_OSAL_H__ +#define __BLE_OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __BLE_OSAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,158 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_sm.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's security manager. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_SM_H__ +#define __BLE_SM_H__ + +/****************************************************************************** +* Macros +*****************************************************************************/ + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/* IO capabilities */ +/** + * @anchor IO_capabilities + * @name IO capabilities + * @{ + */ +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define IO_CAP_KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) +/** + * @} + */ + +/** + * @anchor Auth_req + * @name Authentication requirements + * @{ + */ +#define BONDING (0x01) +#define NO_BONDING (0x00) +/** + * @} + */ + +/** + * @anchor MITM_req + * @name MITM protection requirements + * @{ + */ +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor OOB_Data + * @name Out-Of-Band data + * @{ + */ +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) +/** + * @} + */ + +/** + * @anchor Author_req + * @name Authorization requirements + * @{ + */ +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor Conn_authorization + * @name Connection authorization + * @{ + */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) +/** + * @} + */ + +/** + * @anchor Use_fixed_pin + * @name Use fixed pin + * @{ + */ +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +/** + * @} + */ + +/** + * @anchor link_security_status + * @name Link security status + * @{ + */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) +/** + * @} + */ + +/** + * @anchor SMP_pairing_failed_codes + * @name SMP pairing failed reason codes + * @{ + */ +#define PASSKEY_ENTRY_FAILED (0x01) +#define OOB_NOT_AVAILABLE (0x02) +#define AUTH_REQ_CANNOT_BE_MET (0x03) +#define CONFIRM_VALUE_FAILED (0x04) +#define PAIRING_NOT_SUPPORTED (0x05) +#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) +#define CMD_NOT_SUPPORTED (0x07) +#define UNSPECIFIED_REASON (0x08) +#define VERY_EARLY_NEXT_ATTEMPT (0x09) +#define SM_INVALID_PARAMS (0x0A) +/** + * @} + */ + +/** + * @anchor pairing_failed_codes + * @name Pairing failed error codes + * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event + * @{ + */ +#define SM_PAIRING_SUCCESS (0x00) +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,188 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_status.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file with BLE Stack status codes. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_STATUS_H__ +#define __BLE_STATUS_H__ + +#include <ble_hal_types.h> + +/** @addtogroup Middlewares + * @{ + */ + +/** @defgroup ST + * @{ + */ + +/** @defgroup SimpleBlueNRG_HCI + * @{ + */ + +/** @defgroup ble_status Bluetooth Status/Error Codes + * @{ + */ + +typedef uint8_t tBleStatus; + +/* Error Codes as specified by the specification + * according to the spec the error codes range + * from 0x00 to 0x3F + */ +/** + * @name Standard error codes + * @brief Standard error codes. See Core v 4.1, Vol. 2, part D. + * @{ + */ +#define ERR_CMD_SUCCESS (0x00) +#define BLE_STATUS_SUCCESS (0x00) +#define ERR_UNKNOWN_HCI_COMMAND (0x01) +#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) + +#define ERR_AUTH_FAILURE (0x05) +#define ERR_PIN_OR_KEY_MISSING (0x06) +#define ERR_MEM_CAPACITY_EXCEEDED (0x07) +#define ERR_CONNECTION_TIMEOUT (0x08) + +#define ERR_COMMAND_DISALLOWED (0x0C) + +#define ERR_UNSUPPORTED_FEATURE (0x11) +#define ERR_INVALID_HCI_CMD_PARAMS (0x12) +#define ERR_RMT_USR_TERM_CONN (0x13) +#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) +#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) +#define ERR_LOCAL_HOST_TERM_CONN (0x16) + +#define ERR_UNSUPP_RMT_FEATURE (0x1A) + +#define ERR_INVALID_LMP_PARAM (0x1E) +#define ERR_UNSPECIFIED_ERROR (0x1F) + +#define ERR_LL_RESP_TIMEOUT (0x22) +#define ERR_LMP_PDU_NOT_ALLOWED (0x24) + +#define ERR_INSTANT_PASSED (0x28) + +#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) +#define ERR_CONTROLLER_BUSY (0x3A) + +#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) + +#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) + +#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) + + +/** + * @} + */ +/** + * @name Vendor-specific error codes + * @brief Error codes defined by ST related to BlueNRG stack + * @{ + */ +/** + * The command cannot be executed due to the current state of the device. + */ +#define BLE_STATUS_FAILED (0x41) +/** + * Some parameters are invalid. + */ +#define BLE_STATUS_INVALID_PARAMS (0x42) +/** + * It is not allowed to start the procedure (e.g. another the procedure is ongoing + * or cannot be started on the given handle). + */ +#define BLE_STATUS_NOT_ALLOWED (0x46) +/** + * Unexpected error. + */ +#define BLE_STATUS_ERROR (0x47) +#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) + +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +#define BLE_STATUS_INVALID_CID (0x50) + +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) +#define BLE_STATUS_IRK_NOT_FOUND (0x5B) +#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) +#define BLE_STATUS_SEC_DB_FULL (0x5D) +#define BLE_STATUS_DEV_NOT_BONDED (0x5E) +#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) + +#define BLE_STATUS_INVALID_HANDLE (0x60) +#define BLE_STATUS_INVALID_PARAMETER (0x61) +#define BLE_STATUS_OUT_OF_HANDLE (0x62) +#define BLE_STATUS_INVALID_OPERATION (0x63) +#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) +#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) +#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) + +/** + * Returned when no valid slots are available (e.g. when there are no available state machines). + */ +#define BLE_STATUS_NO_VALID_SLOT (0x82) + +/** + * Returned when a scan window shorter than minimum allowed value has been requested (i.e. 2ms) + */ + +#define BLE_STATUS_SCAN_WINDOW_SHORT (0x83) +/** + * Returned when the maximum requested interval to be allocated is shorter then the current + * anchor period and a there is no submultiple for the current anchor period that is between + * the minimum and the maximum requested intervals. + */ + +#define BLE_STATUS_NEW_INTERVAL_FAILED (0x84) +/** + * Returned when the maximum requested interval to be allocated is greater than the current anchor + * period and there is no multiple of the anchor period that is between the minimum and the maximum + * requested intervals. + */ + +#define BLE_STATUS_INTERVAL_TOO_LARGE (0x85) +/** + * Returned when the current anchor period or a new one can be found that is compatible to the + * interval range requested by the new slot but the maximum available length that can be allocated is + * less than the minimum requested slot length. + */ + +#define BLE_STATUS_LENGTH_FAILED (0x86) +/** + * @} + */ + +/** + * @name Library Error Codes + * @brief Error codes defined by ST related to MCU library. + * @{ + */ +#define BLE_STATUS_TIMEOUT (0xFF) +#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) +#define BLE_STATUS_NULL_PARAM (0xF1) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,813 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci_const.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with ACI definitions for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_CONST_H_ +#define __BLUENRG_ACI_CONST_H_ + +#include "ble_compiler.h" +#include "ble_link_layer.h" +#include "ble_hci_const.h" +#include "bluenrg_gatt_server.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define OCF_HAL_GET_FW_BUILD_NUMBER 0x0000 +typedef __packed struct _hal_get_fw_build_number_rp{ + uint8_t status; + uint16_t build_number; +} PACKED hal_get_fw_build_number_rp; +#define HAL_GET_FW_BUILD_NUMBER_RP_SIZE 3 +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +#define OCF_HAL_READ_CONFIG_DATA 0x000D +typedef __packed struct _hal_read_config_data_cp{ + uint8_t offset; +} PACKED hal_read_config_data_cp; +#define HAL_READ_CONFIG_DATA_RP_SIZE 1 +typedef __packed struct _hal_read_config_data_rp{ + uint8_t status; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE]; +} PACKED hal_read_config_data_rp; + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef __packed struct _hal_set_tx_power_level_cp{ + uint8_t en_high_power; + uint8_t pa_level; +} PACKED hal_set_tx_power_level_cp; +#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 + +#define OCF_HAL_DEVICE_STANDBY 0x0013 + +#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014 +typedef __packed struct _hal_le_tx_test_packet_number_rp{ + uint8_t status; + uint32_t number_of_packets; +} PACKED hal_le_tx_test_packet_number_rp; + +#define OCF_HAL_TONE_START 0x0015 +typedef __packed struct _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_HAL_TONE_STOP 0x0016 +#define OCF_HAL_GET_LINK_STATUS 0x0017 +typedef __packed struct _hal_get_link_status_rp{ + uint8_t status; + uint8_t link_status[8]; + uint16_t conn_handle[8]; +} PACKED hal_get_link_status_rp; + +#define OCF_HAL_GET_ANCHOR_PERIOD 0x0019 +typedef __packed struct _hal_get_anchor_period_rp{ + uint8_t status; + uint32_t anchor_period; + uint32_t max_free_slot; +} PACKED hal_get_anchor_period_rp; + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef __packed struct _get_updater_version_rp{ + uint8_t status; + uint8_t version; +} PACKED get_updater_version_rp; +#define GET_UPDATER_VERSION_RP_SIZE 2 + +#define OCF_GET_UPDATER_BUFSIZE 0x0023 +typedef __packed struct _get_updater_bufsize_rp{ + uint8_t status; + uint8_t buffer_size; +} PACKED get_updater_bufsize_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 + +#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 + +#define OCF_UPDATER_ERASE_SECTOR 0x0026 +typedef __packed struct _updater_erase_sector_cp{ + uint32_t address; +} PACKED updater_erase_sector_cp; +#define UPDATER_ERASE_SECTOR_CP_SIZE 4 + +#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 +#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_prog_data_block_cp{ + uint32_t address; + uint16_t data_len; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; +} PACKED updater_prog_data_block_cp; + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef __packed struct _updater_read_data_block_cp{ + uint32_t address; + uint16_t data_len; +} PACKED updater_read_data_block_cp; +#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[VARIABLE_SIZE]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef __packed struct _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef __packed struct _updater_calc_crc_rp{ + uint8_t status; + uint32_t crc; +} PACKED updater_calc_crc_rp; +#define UPDATER_CALC_CRC_RP_SIZE 5 + +#define OCF_UPDATER_HW_VERSION 0x002A +typedef __packed struct _updater_hw_version_rp{ + uint8_t status; + uint8_t version; +} PACKED updater_hw_version_rp; +#define UPDATER_HW_VERSION_RP_SIZE 2 + +#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 + +#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 + +#define OCF_GAP_SET_DISCOVERABLE 0x0083 + +#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 +typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ + uint8_t own_bdaddr_type; + uint8_t directed_adv_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint16_t adv_interv_min; + uint16_t adv_interv_max; +} PACKED gap_set_direct_conectable_cp_IDB05A1; + +typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB04A1; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef __packed struct _gap_set_io_capability_cp{ + uint8_t io_capability; +} PACKED gap_set_io_capability_cp; +#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 + +#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 +typedef __packed struct _gap_set_auth_requirement_cp{ + uint8_t mitm_mode; + uint8_t oob_enable; + uint8_t oob_data[16]; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t bonding_mode; +} PACKED gap_set_auth_requirement_cp; +#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 + +#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 +typedef __packed struct _gap_set_author_requirement_cp{ + uint16_t conn_handle; + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef __packed struct _gap_passkey_response_cp{ + uint16_t conn_handle; + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef __packed struct _gap_authorization_response_cp{ + uint16_t conn_handle; + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 + +#define OCF_GAP_INIT 0x008A +typedef __packed struct _gap_init_cp_IDB05A1{ + uint8_t role; + uint8_t privacy_enabled; + uint8_t device_name_char_len; +} PACKED gap_init_cp_IDB05A1; +#define GAP_INIT_CP_SIZE_IDB05A1 3 + +typedef __packed struct _gap_init_cp_IDB04A1{ + uint8_t role; +} PACKED gap_init_cp_IDB04A1; +#define GAP_INIT_CP_SIZE_IDB04A1 1 +typedef __packed struct _gap_init_rp{ + uint8_t status; + uint16_t service_handle; + uint16_t dev_name_char_handle; + uint16_t appearance_char_handle; +} PACKED gap_init_rp; +#define GAP_INIT_RP_SIZE 7 + +#define OCF_GAP_SET_NON_CONNECTABLE 0x008B +typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ + uint8_t advertising_event_type; + uint8_t own_address_type; +#endif +} PACKED gap_set_non_connectable_cp_IDB05A1; + +typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp_IDB04A1; + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef __packed struct _gap_set_undirected_connectable_cp{ + uint8_t adv_filter_policy; + uint8_t own_addr_type; +} PACKED gap_set_undirected_connectable_cp; +#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 + +#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D +typedef __packed struct _gap_slave_security_request_cp{ + uint16_t conn_handle; + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef __packed struct _gap_delete_ad_type_cp{ + uint8_t ad_type; +} PACKED gap_delete_ad_type_cp; +#define GAP_DELETE_AD_TYPE_CP_SIZE 1 + +#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 +typedef __packed struct _gap_get_security_level_rp{ + uint8_t status; + uint8_t mitm_protection; + uint8_t bonding; + uint8_t oob_data; + uint8_t passkey_required; +} PACKED gap_get_security_level_rp; +#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 + +#define OCF_GAP_SET_EVT_MASK 0x0091 +typedef __packed struct _gap_set_evt_mask_cp{ + uint16_t evt_mask; +} PACKED gap_set_evt_mask_cp; +#define GAP_SET_EVT_MASK_CP_SIZE 2 + +#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 + +#define OCF_GAP_TERMINATE 0x0093 +typedef __packed struct _gap_terminate_cp{ + uint16_t handle; + uint8_t reason; +} PACKED gap_terminate_cp; +#define GAP_TERMINATE_CP_SIZE 3 + +#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 + +#define OCF_GAP_ALLOW_REBOND_DB 0x0095 + +typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ + uint16_t conn_handle; +} PACKED gap_allow_rebond_cp_IDB05A1; + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef __packed struct _gap_start_limited_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_limited_discovery_proc_cp; +#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 +typedef __packed struct _gap_start_general_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_general_discovery_proc_cp; +#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 +typedef __packed struct _gap_start_name_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_name_discovery_proc_cp; +#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 + +#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 + +#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; + +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t use_reconn_addr; + tBDAddr reconn_addr; +} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; + +#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B +#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 +typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t num_whitelist_entries; + uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; +} PACKED gap_start_selective_conn_establish_proc_cp; + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef __packed struct _gap_create_connection_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_create_connection_cp; +#define GAP_CREATE_CONNECTION_CP_SIZE 24 + +#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D + +#define OCF_GAP_START_CONNECTION_UPDATE 0x009E +typedef __packed struct _gap_start_connection_update_cp{ + uint16_t conn_handle; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_connection_update_cp; +#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 + +#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F +typedef __packed struct _gap_send_pairing_request_cp{ + uint16_t conn_handle; + uint8_t force_rebond; +} PACKED gap_send_pairing_request_cp; +#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 + +#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 +typedef __packed struct _gap_resolve_private_address_cp{ + tBDAddr address; +} PACKED gap_resolve_private_address_cp; +#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 +typedef __packed struct _gap_resolve_private_address_rp{ + uint8_t status; + tBDAddr address; +} PACKED gap_resolve_private_address_rp; + +#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 +#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 +typedef __packed struct _gap_set_broadcast_mode_cp{ + uint16_t adv_interv_min; + uint16_t adv_interv_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; +} PACKED gap_set_broadcast_mode_cp; + +#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 +typedef __packed struct _gap_start_observation_proc_cp{ + uint16_t scan_interval; + uint16_t scan_window; + uint8_t scan_type; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_observation_proc_cp; + +#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 +typedef __packed struct _gap_get_bonded_devices_rp{ + uint8_t status; + uint8_t num_addr; + uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; +} PACKED gap_get_bonded_devices_rp; + +#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 +typedef __packed struct _gap_is_device_bonded_cp{ + uint8_t peer_address_type; + tBDAddr peer_address; +} PACKED gap_is_device_bonded_cp; + + +#define OCF_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef __packed struct _gatt_add_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_serv_rp; +#define GATT_ADD_SERV_RP_SIZE 3 + +#define OCF_GATT_INCLUDE_SERV 0x0103 +typedef __packed struct _gatt_include_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_include_serv_rp; +#define GATT_INCLUDE_SERV_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR 0x0104 +typedef __packed struct _gatt_add_char_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_rp; +#define GATT_ADD_CHAR_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR_DESC 0x0105 +typedef __packed struct _gatt_add_char_desc_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_desc_rp; +#define GATT_ADD_CHAR_DESC_RP_SIZE 3 + +#define OCF_GATT_UPD_CHAR_VAL 0x0106 + +#define OCF_GATT_DEL_CHAR 0x0107 +typedef __packed struct _gatt_del_char_cp{ + uint16_t service_handle; + uint16_t char_handle; +} PACKED gatt_del_char_cp; +#define GATT_DEL_CHAR_CP_SIZE 4 + +#define OCF_GATT_DEL_SERV 0x0108 +typedef __packed struct _gatt_del_serv_cp{ + uint16_t service_handle; +} PACKED gatt_del_serv_cp; +#define GATT_DEL_SERV_CP_SIZE 2 + +#define OCF_GATT_DEL_INC_SERV 0x0109 +typedef __packed struct _gatt_del_inc_serv_cp{ + uint16_t service_handle; + uint16_t inc_serv_handle; +} PACKED gatt_del_inc_serv_cp; +#define GATT_DEL_INC_SERV_CP_SIZE 4 + +#define OCF_GATT_SET_EVT_MASK 0x010A +typedef __packed struct _gatt_set_evt_mask_cp{ + uint32_t evt_mask; +} PACKED gatt_set_evt_mask_cp; +#define GATT_SET_EVT_MASK_CP_SIZE 4 + +#define OCF_GATT_EXCHANGE_CONFIG 0x010B +typedef __packed struct _gatt_exchange_config_cp{ + uint16_t conn_handle; +} PACKED gatt_exchange_config_cp; +#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 + +#define OCF_ATT_FIND_INFO_REQ 0x010C +typedef __packed struct _att_find_info_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED att_find_info_req_cp; +#define ATT_FIND_INFO_REQ_CP_SIZE 6 + +#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D +#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 +typedef __packed struct _att_find_by_type_value_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[2]; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU - 7]; +} PACKED att_find_by_type_value_req_cp; + +#define OCF_ATT_READ_BY_TYPE_REQ 0x010E +#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_type_req_cp; + +#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F +#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_group_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_group_type_req_cp; + +#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 +#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val +typedef __packed struct _att_prepare_write_req_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t value_offset; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU-5]; +} PACKED att_prepare_write_req_cp; + +#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 +typedef __packed struct _att_execute_write_req_cp{ + uint16_t conn_handle; + uint8_t execute; +} PACKED att_execute_write_req_cp; +#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 + +#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 +typedef __packed struct _gatt_disc_all_prim_serivces_cp{ + uint16_t conn_handle; +} PACKED gatt_disc_all_prim_services_cp; +#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 + +#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 +typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ + uint16_t conn_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_disc_prim_service_by_uuid_cp; +#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid + +#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 +typedef __packed struct _gatt_disc_find_included_services_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED gatt_find_included_services_cp; +#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 + +#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 +typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ + uint16_t conn_handle; + uint16_t start_attr_handle; + uint16_t end_attr_handle; +} PACKED gatt_disc_all_charac_of_serv_cp; +#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 + +#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 + +#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ + uint16_t conn_handle; + uint16_t char_val_handle; + uint16_t char_end_handle; +} PACKED gatt_disc_all_charac_descriptors_cp; +#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 + +#define OCF_GATT_READ_CHARAC_VAL 0x0118 +typedef __packed struct _gatt_read_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_val_cp; +#define GATT_READ_CHARAC_VAL_CP_SIZE 4 + +#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 +typedef __packed struct _gatt_read_using_charac_uuid_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_read_using_charac_uuid_cp; +#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID + +#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A +typedef __packed struct _gatt_read_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_val_cp; +#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 + +#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B +#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles +typedef __packed struct _gatt_read_multiple_charac_val_cp{ + uint16_t conn_handle; + uint8_t num_handles; + uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_read_multiple_charac_val_cp; + +#define OCF_GATT_WRITE_CHAR_VALUE 0x011C + +#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D +#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_write_long_charac_val_cp; + +#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E +#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_charac_reliable_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; +} PACKED gatt_write_charac_reliable_cp; + +#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F +#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; +} PACKED gatt_write_long_charac_desc_cp; + +#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 +typedef __packed struct _gatt_read_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_desc_cp; +#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 + +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 +typedef __packed struct _gatt_read_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_desc_cp; +#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 +#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 3]; +} PACKED gatt_write_without_resp_cp; + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 +#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_signed_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 13]; +} PACKED gatt_signed_write_without_resp_cp; + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 +typedef __packed struct _gatt_confirm_indication_cp{ + uint16_t conn_handle; +} PACKED gatt_confirm_indication_cp; +#define GATT_CONFIRM_INDICATION_CP_SIZE 2 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef __packed struct _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 +typedef __packed struct _gatt_set_security_permission_cp{ + uint16_t service_handle; + uint16_t attr_handle; + uint8_t security_permission; +} PACKED gatt_set_security_permission_cp; +#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_GATT_READ_HANDLE_VALUE 0x012A +typedef __packed struct _gatt_read_handle_val_cp{ + uint16_t attr_handle; +} PACKED gatt_read_handle_val_cp; +#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 +typedef __packed struct _gatt_read_handle_val_rp{ + uint8_t status; + uint16_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; +} PACKED gatt_read_handle_val_rp; + +#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B +typedef __packed struct _gatt_read_handle_val_offset_cp{ + uint16_t attr_handle; + uint8_t offset; +} PACKED gatt_read_handle_val_offset_cp; +#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 +typedef __packed struct _gatt_read_handle_val_offset_rp{ + uint8_t status; + uint8_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; +} PACKED gatt_read_handle_val_offset_rp; + +#define OCF_GATT_UPD_CHAR_VAL_EXT 0x012C +#define GATT_UPD_CHAR_VAL_EXT_CP_SIZE 10 // without value +typedef __packed struct _gatt_upd_char_val_ext_cp{ + uint16_t service_handle; + uint16_t char_handle; + uint8_t update_type; + uint16_t char_length; + uint16_t value_offset; + uint8_t value_length; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_UPD_CHAR_VAL_EXT_CP_SIZE]; +} PACKED gatt_upd_char_val_ext_cp; + +#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 +typedef __packed struct _l2cap_conn_param_update_req_cp{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_update_req_cp; +#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 + +#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint16_t min_ce_length; + uint16_t max_ce_length; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; + +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; + +/** + * @defgroup BlueNRG_Events BlueNRG events (vendor specific) + * @{ + */ + +/** + * Vendor specific event for BlueNRG. + */ +typedef __packed struct _evt_blue_aci{ + uint16_t ecode; /**< One of the BlueNRG event codes. */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_blue_aci; + + +/** + * @} + */ + +#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gap.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GAP layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BNRG_GAP_H__ +#define __BNRG_GAP_H__ + +#include <ble_link_layer.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + * @name GAP UUIDs + * @{ + */ +#define GAP_SERVICE_UUID (0x1800) +#define DEVICE_NAME_UUID (0x2A00) +#define APPEARANCE_UUID (0x2A01) +#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) +#define RECONNECTION_ADDR_UUID (0x2A03) +#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) +/** + * @} + */ + +/** + * @name Characteristic value lengths + * @{ + */ +#define DEVICE_NAME_CHARACTERISTIC_LEN (8) +#define APPEARANCE_CHARACTERISTIC_LEN (2) +#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) +#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) +#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) +/** + * @} + */ + +/*------------- AD types for adv data and scan response data ----------------*/ + +/** + * @defgroup AD_Types AD Types + * @brief AD Types + * @{ + */ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +/** + * @anchor Flags_AD_Type_bits + * @name Flags AD Type bits + * @brief Bits in Flags AD Type + * @{ + */ +#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) +#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) +#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) +#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) +#define FLAG_BIT_LE_BR_EDR_HOST (0x10) +/** + * @} + */ + +/** + * @name Service UUID AD types + * @{ + */ +#define AD_TYPE_16_BIT_SERV_UUID (0x02) +#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) +#define AD_TYPE_32_BIT_SERV_UUID (0x04) +#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) +#define AD_TYPE_128_BIT_SERV_UUID (0x06) +#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) +/** + * @} + */ + +/* LOCAL NAME AD types */ +/** + * @name Local name AD types + * @{ + */ +#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) +#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) +/** + * @} + */ + +/* TX power level AD type*/ +#define AD_TYPE_TX_POWER_LEVEL (0x0A) + +/* Class of device */ +#define AD_TYPE_CLASS_OF_DEVICE (0x0D) + +/* security manager TK value AD type */ +#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) + +/* security manager OOB flags */ +#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) + +/* slave connection interval AD type */ +#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) + +/* service solicitation UUID list Ad types*/ +/** + * @name Service solicitation UUID list AD types + * @{ + */ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) +#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) +/** + * @} + */ + +/* service data AD type */ +#define AD_TYPE_SERVICE_DATA (0x16) + +/* manufaturer specific data AD type */ +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/* appearance AD type */ +#define AD_TYPE_APPEARANCE (0x19) + +/* advertising interval AD type */ +#define AD_TYPE_ADVERTISING_INTERVAL (0x1A) + +/** + * @} + */ + +#define MAX_ADV_DATA_LEN (31) + +#define DEVICE_NAME_LEN (7) +#define BD_ADDR_SIZE (6) + +/** + * @name Privacy flag values + * @{ + */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) +/** + * @} + */ + +/** + * @name Intervals + * Intervals in terms of 625 micro sec + * @{ + */ +#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ +#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ +#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ +#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ +#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ +#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ +#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ +#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ +/** + * @} + */ + +/** + * @name Timeout values + * @{ + */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ +/** + * @} + */ + +/** + * @anchor gap_roles + * @name GAP Roles + * @{ +*/ +#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) +#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) + +#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) +#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) +/** + * @} + */ + +/** + * @anchor gap_procedure_codes + * @name GAP procedure codes + * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event + * and aci_gap_terminate_gap_procedure() command. + * @{ + */ +#define GAP_LIMITED_DISCOVERY_PROC (0x01) +#define GAP_GENERAL_DISCOVERY_PROC (0x02) +#define GAP_NAME_DISCOVERY_PROC (0x04) +#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) +#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) +#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) +#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) +#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1231 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gap_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GAP_ACI_H__ +#define __BLUENRG_GAP_ACI_H__ + +/** + *@addtogroup GAP GAP + *@brief GAP layer. + *@{ + */ + +/** + *@defgroup GAP_Functions GAP functions + *@brief API for GAP layer. + *@{ + */ + +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". + * @param privacy_enabled Enable (1) or disable (0) privacy. + * @param device_name_char_len Length of the device name characteristic + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, + uint8_t device_name_char_len, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Privacy Flag (peripheral role only) + * @li Reconnection Address (peripheral role only) + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB04A1(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); + +/** + * @brief Set the Device in non-discoverable mode. + * @note This command will disable the LL advertising. + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_discoverable(void); + +/** + * @brief Put the device in limited discoverable mode + * (as defined in GAP specification volume 3, section 9.2.3). + * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. + * The advertising can be disabled at any time by issuing + * aci_gap_set_non_discoverable() command. + * The AdvIntervMin and AdvIntervMax parameters are optional. If both + * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). + * Host can set the Local Name, a Service UUID list and the Slave Connection + * Minimum and Maximum. If provided, these data will be inserted into the + * advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() + * separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following + * standard AD types: + * @li AD Flags + * @li TX Power Level + * + * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates + * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. + * + * Example: + * @code + * + * #define ADV_INTERVAL_MIN_MS 100 + * #define ADV_INTERVAL_MAX_MS 200 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, + * (ADV_INTERVAL_MAX_MS*1000)/0.625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * sizeof(serviceUUIDList), serviceUUIDList, + * 0, 0); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 250 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 500 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg NO_WHITE_LIST_USE + * @arg WHITE_LIST_FOR_ONLY_SCAN + * @arg WHITE_LIST_FOR_ONLY_CONN + * @arg WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +/** + * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4). + * @note The device will be discoverable until the Host issue Aci_Gap_Set_Non_Discoverable command. + * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses + * the default values for advertising intervals (1.28 s and 2.56 s respectively for IDB04A1). + * When using connectable undirected advertising events:\n + * @li Adv_Interval_Min = 30 ms + * @li Adv_Interval_Max = 60 ms + * \nWhen using non-connectable advertising events or scannable undirected advertising events:\n + * @li Adv_Interval_Min = 100 ms + * @li Adv_Interval_Max = 150 ms + * Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided, + * these data will be inserted into the advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following standard AD types: + * @li AD Flags + * @li TX Power Level + * + * Usage example: + * + * @code + * + * #define ADV_INTERVAL_MIN_MS 800 + * #define ADV_INTERVAL_MAX_MS 900 + * #define CONN_INTERVAL_MIN_MS 100 + * #define CONN_INTERVAL_MAX_MS 300 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625, + * (ADV_INTERVAL_MAX_MS*1000)/625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * 0, NULL, + * (CONN_INTERVAL_MIN_MS*1000)/1250, + * (CONN_INTERVAL_MAX_MS*1000)/1250); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 1.28 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 2.56 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ONLY_SCAN + * @arg @ref WHITE_LIST_FOR_ONLY_CONN + * @arg @ref WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); + +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @param adv_interv_min Minimum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @param adv_interv_max Maximum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max); +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); + +/** + * @brief Set the IO capabilities of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param io_capability One of the allowed codes for IO Capability: + * @arg @ref IO_CAP_DISPLAY_ONLY + * @arg @ref IO_CAP_DISPLAY_YES_NO + * @arg @ref IO_CAP_KEYBOARD_ONLY + * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT + * @arg @ref IO_CAP_KEYBOARD_DISPLAY + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_io_capability(uint8_t io_capability); + +/** + * @brief Set the authentication requirements for the device. + * @note If the oob_enable is set to 0, oob_data will be ignored. + * This command has to be given only when the device is not in a connected state. + * @param mitm_mode MITM mode: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @param oob_enable If OOB data are present or not: + * @arg @ref OOB_AUTH_DATA_ABSENT + * @arg @ref OOB_AUTH_DATA_PRESENT + * @param oob_data Out-Of-Band data + * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process + * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process + * @param use_fixed_pin If application wants to use a fixed pin or not: + * @arg @ref USE_FIXED_PIN_FOR_PAIRING + * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING + * If a fixed pin is not used, it has to be provided by the application with + * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will + * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is + * accepted. + * @param bonding_mode One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode); + /** + * @brief Set the authorization requirements of the device. + * @note This command has to be given when connected to a device if authorization is required to access services + * which require authorization. + * @param conn_handle Handle of the connection. + * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required + * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables + * the authorization requirement in the device and when a remote device + * tries to read/write a characeristic with authorization requirements, the stack will + * send back an error response with "Insufficient authorization" error code. + * After pairing is complete a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event + * will be sent to the Host. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); + +/** + * @brief Provide the pass key that will be used during pairing. + * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param conn_handle Connection handle + * @param passkey Pass key that will be used during the pairing process. Must be a number between + * 0 and 999999. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); + +/** + * @brief Authorize a device to access attributes. + * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. + * + * @param conn_handle Connection handle + * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) + * @arg @ref CONNECTION_REJECTED : Reject (reject connection) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); + +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @param own_address_type If Privacy is disabled, then the peripheral address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the peripheral address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); + +/** + * @brief Put the device into undirected connectable mode. + * @note If privacy is enabled in the device, a resolvable private address is generated and used + * as the advertiser's address. If not, the address of the type specified in own_addr_type + * is used for advertising. + * @param own_addr_type Type of our address used during advertising: + * if BLUENRG (IDB04A1) + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * else if BLUENRG_MS (IDB05A1) + * If Privacy is disabled: + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled: + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_filter_policy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ALL + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); + +/** + * @brief Send a slave security request to the master. + * @note This command has to be issued to notify the master of the security requirements of the slave. + * The master may encrypt the link, initiate the pairing procedure, or reject the request. + * @param conn_handle Connection handle + * @param bonding One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @param mitm_protection If MITM protection is required or not: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); + +/** + * @brief Update advertising data. + * @note This command can be used to update the advertising data for a particular AD type. + * If the AD type specified does not exist, then it is added to the advertising data. + * If the overall advertising data length is more than 31 octets after the update, then + * the command is rejected and the old data is retained. + * @param AdvLen Length of AdvData array + * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification + * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. + * Example + * @code + * tBleStatus ret; + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; + * + * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * 8, local_name, 3, serviceUUIDList, 0, 0); + * ret = aci_gap_update_adv_data(5, manuf_data); + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); + +/** + * @brief Delete an AD Type + * @note This command can be used to delete the specified AD type from the advertisement data if + * present. + * @param ad_type One of the allowed AD types (see @ref AD_Types) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); + +/** + * @brief Get the current security settings + * @note This command can be used to get the current security settings of the device. + * @param mitm_protection @arg 0: Not required + * @arg 1: Required + * @param bonding @arg 0: No bonding mode + * @arg 1: Bonding mode + * @param oob_data @arg 0: Data absent + * @arg 1: Data present + * @param passkey_required @arg 0: Not required + * @arg 1: Fixed pin is present which is being used + * @arg 2: Passkey required for pairing. An event will be generated + * when required. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required); + +/** + * @brief Add addresses of bonded devices into the controller's whitelist. + * @note The command will return an error if there are no devices in the database or if it was unable + * to add the device into the whitelist. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_configure_whitelist(void); + +/** + * @brief Terminate a connection. + * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. + * @param conn_handle Connection handle + * @param reason Reason for requesting disconnection. The error code can be any of ones as specified + * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); + +/** + * @brief Clear the security database. + * @note All the devices in the security database will be removed. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_clear_security_database(void); + +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @param conn_handle + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB04A1(void); + +/** + * @brief Start the limited discovery procedure. + * @note The controller is commanded to start active scanning. When this procedure is started, + * only the devices in limited discoverable mode are returned to the upper layers. + * The procedure is terminated when either the upper layers issue a command to terminate the + * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code + * set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated + * due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC. + * The device found when the procedure is ongoing is returned to the upper layers through the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the general discovery procedure. + * @note The controller is commanded to start active scanning. The procedure is terminated when + * either the upper layers issue a command to terminate the procedure by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC + * or a timeout happens. When the procedure is terminated due to any of the above reasons, + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to + * @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to + * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the name discovery procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. Once a connection is established, GATT procedure is started to read the + * device name characteristic. When the read is completed (successfully or unsuccessfully), + * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also + * contains the name of the device if the device name was read successfully. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Start the auto connection establishment procedure. + * @note The devices specified are added to the white list of the controller and a LE_Create_Connection + * call will be made to the controller by GAP with the initiator filter policy set to + * use whitelist to determine which advertiser to connect to. When a command is issued to + * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the + * controller by GAP. + * The procedure is terminated when either a connection is successfully established with one of + * the specified devices in the white list or the procedure is explicitly terminated by issuing + * the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start a general connection establishment procedure. + * @note The host enables scanning in the controller with the scanner filter policy set + * to accept all advertising packets and from the scanning results all the devices + * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * The upper layer then has to select one of the devices to which it wants to connect + * by issuing the command aci_gap_create_connection(). The procedure is terminated + * when a connection is established or the upper layer terminates the procedure by + * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates); +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); + +/** + * @brief Start a selective connection establishment procedure. + * @note The GAP adds the specified device addresses into white list and enables scanning in + * the controller with the scanner filter policy set to accept packets only from + * devices in whitelist. All the devices found are sent to the upper layer by the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the + * devices to which it wants to connect by issuing the command aci_gap_create_connection(). + * On completion of the procedure a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated + * with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * The procedure is terminated when a connection is established or the upper layer terminates + * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure + * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start the direct connection establishment procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. The procedure can be terminated explicitly by the upper layer by issuing + * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the + * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller + * by GAP. + * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can + * be explicitly terminated by the upper layer by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is + * returned with the procedure code set to the corresponding procedure. + * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes"). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); + +/** + * @brief Start the connection parameter update procedure. + * @note Allowed by the Central to update the connection parameter of the specified connection. + * A Link Layer Connection Update procedure is started on the controller. + * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to + * the upper layer. + * @param conn_handle Handle of the connection for which the update procedure has to be started. + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Send a pairing request. + * @note Send the SM pairing request to start a pairing process from a Central. The authentication + * requirements and IO capabilities should be set before issuing this command using + * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). + * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. + * @param conn_handle Handle of the connection for which the pairing request has to be sent. + * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded + * @arg 0x01: Pairing request will be sent even if the device was previously bonded + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param[in] address Address to be resolved. + * @param[out] actual_address The public or static random address of the peer device, distributed during pairing phase. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); + +/** + * @brief This command gets the list of bonded devices. + * @note It returns the number of addresses and the corresponding address types and values. + * Example: + * @code + * tBleStatus ret; + * uint8_t num_devices = 0; + * uint8_t device_list[12*7]; + * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); + * for(int i = 0; i < num_devices; i+=7){ + * uint8_t addr_type = device_list[i]; + * uint8_t addr = device_list[i+1]; + * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); + * } + * @endcode + * + * @param[out] num_devices The number of bonded devices. + * @param[out] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address + * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. + * @param device_list_size Maximum size of the device_list buffer used to return the device list. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); + +/** + * @brief Puts the device into broadcast mode + * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address + * as specified in the own_addr_type parameter of the command. + * @param adv_interv_min Minimum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_interv_max Maximum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param own_addr_type If Privacy is disabled, the broadcaster address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the broadcaster address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_data_length Length of the advertising data in the advertising packet + * @param adv_data Advertising data used by the device while advertising + * @param num_whitelist_entries Number of devices to be added to whitelist + * @param addr_array It will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Starts an observation procedure, when the device is in Observer role. + * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer + * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth + * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. + * The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. + * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param own_address_type If Privacy is disabled, then the scanner address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the scanner address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates); + +/** + * @brief The command finds whether a device is bonded. + * @note If the device is using a resolvable private address and it has been bonded, then the command will return + * BLE_STATUS_SUCCESS. + * @param peer_address_type The address type of the peer device + * @arg @ref PUBLIC_ADDR. + * @arg @ref RANDOM_ADDR. + * @param peer_address Address used by the peer device while advertising. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address); + + +/** + * @} + */ + +/** + * @defgroup GAP_Events GAP events + * @{ + */ + +/** + * This event is generated by the controller when the limited discoverable + * mode ends due to timeout (180 seconds). No parameters in the event. + */ +#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) + + +/** + * This event is generated when the pairing process has completed successfully + * or a pairing procedure timeout has occurred or the pairing has failed. + * This is to notify the application that we have paired with a remote device + * so that it can take further actions or to notify that a timeout has occurred + * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. + */ +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +typedef __packed struct _evt_gap_pairing_cmplt{ + uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ + /** + * 0x00: Pairing Success. Pairing with a remote device was successful\n + * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n + * 0x02: Pairing Failed. The pairing failed with the remote device. + */ + uint8_t status; +} PACKED evt_gap_pairing_cmplt; + + +/** + * This event is generated by the Security manager to the application when a pass key is required for pairing. + * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. + * See @ref _evt_gap_pass_key_req. + */ +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +typedef __packed struct _evt_gap_pass_key_req{ + uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ +} PACKED evt_gap_pass_key_req; + + +/** + * This event is generated by the Security manager to the application when the application + * has set that authorization is required for reading/writing of attributes. This event will + * be generated as soon as the pairing is complete. When this event is received, + * aci_gap_authorization_response() command should be used by the application. + * See @ref _evt_gap_author_req. + */ +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +typedef __packed struct _evt_gap_author_req{ + uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ +} PACKED evt_gap_author_req; + +/** + * This event is generated when the slave security request is successfully sent to the master. + * No parameters for this event. + */ +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) + +/** + * This event is generated on the slave when a aci_gap_slave_security_request() is called to reestablish the bond + * with a master but the master has lost the bond. When this event is received, the upper layer has to issue the + * command aci_gap_allow_rebond() in order to allow the slave to continue the pairing process with the master. + * On the master this event is raised when aci_gap_send_pairing_request() is called to reestablish a bond with a slave + * but the slave has lost the bond. In order to create a new bond the master has to launch aci_gap_send_pairing_request() + * with force_rebond set to 1. + * No parameters for this event + */ +#define EVT_BLUE_GAP_BOND_LOST (0X0405) + +/** + * The event is given by the GAP layer to the upper layers when a device is discovered during scanning + * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. + */ +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef __packed struct _evt_gap_device_found{ + uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ + uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ + tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ + uint8_t data_length; /**< Length of advertising or scan response data. */ + uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ +} PACKED evt_gap_device_found; + +/** + * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated + * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. + */ +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef __packed struct _evt_gap_procedure_complete{ + uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ + /** + * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed + * due to authentication requirements). + */ + uint8_t status; + /** + * Procedure specific data.\n + * @li For Name Discovery Procedure:\n + * the name of the peer device if the procedure completed successfully. + * @li For General Connection Establishment Procedure:\n + * The reconnection address written to the peripheral device if the peripheral is privacy enabled + */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_gap_procedure_complete; + +/** + * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral + * is not able to resolve the private address of the peer device after connecting to it. + */ +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) +typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ + uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ +} PACKED evt_gap_addr_not_resolved_IDB05A1; +/** + * This event is raised when the reconnection address is generated during the general connection + * establishment procedure. The same address is set into the peer device also as a part of the general + * connection establishment procedure. In order to make use of the reconnection address the next time + * while connecting to the bonded peripheral, the application needs to use this reconnection address + * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() + * and aci_gap_start_auto_conn_establish_proc(). + */ +#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) +typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ + uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ +} PACKED evt_gap_reconnection_addr_IDB04A1; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1128 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GATT_ACI_H__ +#define __BLUENRG_GATT_ACI_H__ + +#include "bluenrg_gatt_server.h" + +/** + *@addtogroup GATT GATT + *@brief GATT layer. + *@{ + */ + +/** + *@defgroup GATT_Functions GATT functions + *@brief API for GATT layer. + *@{ + */ + +/** + * @brief Initialize the GATT layer for server and client roles. + * @note It adds also the GATT service with Service Changed Characteristic. + * Until this command is issued the GATT channel will not process any commands + * even if the connection is opened. This command has to be given + * before using any of the GAP features. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_init(void); + +/** + * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs + * to reserve the handle ranges for this service using max_attr_records parameter. This + * parameter specifies the maximum number of attribute records that can be added to this + * service (including the service attribute, include attribute, characteristic attribute, + * characteristic value attribute and characteristic descriptor attribute). Handle of the + * created service is returned. + * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors + * are allocated from the attribute pool. + * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field + * @param service_type Primary or secondary service. See @ref Service_type "Service Type". + * @param max_attr_records Maximum number of attribute records that can be added to this service + * (including the service declaration itself) + * @param[out] serviceHandle Handle of the Service. When this service is added to the service, + * a handle is allocated by the server to this service. Server also + * allocates a range of handles for this service from serviceHandle to + * <serviceHandle + max_attr_records>. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, + const uint8_t* service_uuid, + uint8_t service_type, + uint8_t max_attr_records, + uint16_t *serviceHandle); + +/** + * @brief Include a service given by included_start_handle and included_end_handle to another service + * given by service_handle. Attribute server creates an INCLUDE definition attribute and return + * the handle of this attribute in included_handle. + * @param service_handle Handle of the service to which another service has to be included + * @param included_start_handle Start Handle of the service which has to be included in service + * @param included_end_handle End Handle of the service which has to be included in service + * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". + * @param[in] included_uuid 16-bit or 128-bit UUID. + * @param[out] included_handle Handle of the include declaration. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle); + +/** + * @brief Add a characteristic to a service. + * @param serviceHandle Handle of the service to which the characteristic has to be added. + * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param charUuid 16-bit or 128-bit UUID. + * @param charValueLen Maximum length of the characteristic value. + * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, + * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". + * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @arg GATT_DONT_NOTIFY_EVENTS + * @arg GATT_NOTIFY_ATTRIBUTE_WRITE + * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP + * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. + * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client + * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE + * properties. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle); + +/** + * Add a characteristic descriptor to a service. + * @param serviceHandle Handle of the service to which the characteristic belongs + * @param charHandle Handle of the characteristic to which description has to be added. + * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG + * (Well_known_UUIDs) or a user-defined one. + * @param descValueMaxLen The maximum length of the descriptor value + * @param descValueLen Current Length of the characteristic descriptor value + * @param[in] descValue Value of the characteristic description + * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". + * @arg ATTR_NO_ACCESS + * @arg ATTR_ACCESS_READ_ONLY + * @arg ATTR_ACCESS_WRITE_REQ_ONLY + * @arg ATTR_ACCESS_READ_WRITE + * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE + * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param[out] descHandle Handle of the Characteristic Descriptor. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle); + +/** + * @brief Update a characteristic value in a service. + * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. The command is queued into the + * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, + * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or + * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate + * than what is allowed by the link. Throughput on BLE link depends on connection interval and + * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() + * for more info on how to suggest new connection parameters from a slave). If the application does not + * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function + * returns @ref BLE_STATUS_SUCCESS or any other error code.\n + * Example:\n + * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some + * notifications will be lost. + * @code + * tBleStatus Free_Fall_Notify(void) + * { + * uint8_t val; + * tBleStatus ret; + * + * val = 0x01; + * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); + * + * if (ret != BLE_STATUS_SUCCESS){ + * PRINTF("Error while updating FFall characteristic.\n") ; + * return BLE_STATUS_ERROR ; + * } + * return BLE_STATUS_SUCCESS; + * } + * @endcode + * Here if BlueNRG buffer become full, the application try again to send the notification. + * @code + * struct timer t; + * Timer_Set(&t, CLOCK_SECOND*10); + * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ + * // Radio is busy (buffer full). + * if(Timer_Expired(&t)) + * break; + * } + * @endcode + * + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic + * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, + * and the attribute value is of variable length, then the length of the attribute will + * be set to the charValueLen. If the charValOffset is set to a value greater than 0, + * then the length of the attribute will be set to the maximum length as specified for + * the attribute while adding the characteristic. + * @param charValueLen Length of the characteristic value in octets + * @param[in] charValue Characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue); +/** + * @brief Delete the specified characteristic from the service. + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); + +/** + * @brief Delete the specified service from the GATT server database. + * @param servHandle Handle of the service to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_service(uint16_t servHandle); + +/** + * @brief Delete the Include definition from the service. + * @param servHandle Handle of the service to which Include definition belongs + * @param includeServHandle Handle of the Included definition to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); + +/** + * @brief Perform an ATT MTU exchange procedure. + * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP + * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated + * to indicate the end of the procedure. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); + +/** + * @brief Send a @a Find @a Information @a Request. + * @note This command is used to obtain the mapping of attribute handles with their associated + * types. The responses of the procedure are given through the + * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by + * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range of attributes to be discovered on the server + * @param end_handle Ending handle of the range of attributes to be discovered on the server + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send a @a Find @a By @a Type @a Value @a Request + * @note The Find By Type Value Request is used to obtain the handles of attributes that + * have a given 16-bit UUID attribute type and a given attribute value. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid 2 octet UUID to find (little-endian) + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). + * @param attr_val Attribute value to find + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send a @a Read @a By @a Type @a Request + * @note The Read By Type Request is used to obtain the values of attributes where the attribute type + * is known but the handle is not known. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Read @a By @a Group @a Type @a Request + * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute + * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping + * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Prepare @a Write @a Request + * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param attr_handle The handle of the attribute to be written + * @param value_offset The offset of the first octet to be written + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). + * @param attr_val The value of the attribute to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send an @a Execute @a Write @a Request + * @note The Execute Write Request is used to request the server to write or cancel the write of all the + * prepared values currently held in the prepare queue from this client. + * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param execute @arg 0x00 Cancel all prepared writes + * @arg 0x01 Immediately write all pending prepared values. + * @return Value indicating success or error code. + */ +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); + +/** + * @brief This command will start the GATT client procedure to discover all primary services on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +/** + * @brief Start the procedure to discover the primary services of the specified UUID on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to find all included services. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle Start handle of the service + * @param end_handle End handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Start the procedure to discover all the characteristics of a given service. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_attr_handle Start attribute handle of the service + * @param end_attr_handle End attribute handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +/** + * @brief Start the procedure to discover all the characteristics specified by a UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Start attribute handle of the service + * @param end_handle End attribute handle of the service + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); + +/** + * @brief Start the procedure to discover all characteristic descriptors on the server. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. + * @param conn_handle Connection handle for which the command is given. + * @param char_val_handle Starting handle of the characteristic + * @param char_end_handle End handle of the characteristic + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +/** + * @brief Start the procedure to read the attribute value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to read all the characteristics specified by the UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range to be searched + * @param end_handle End handle of the range to be searched + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start a procedure to read multiple characteristic values from a server. + * @note This sub-procedure is used to read multiple Characteristic Values from a server when the + * client knows the Characteristic Value Handles. + * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param num_handles The number of handles for which the value has to be read + * @param set_of_handles The handles for which the attribute value has to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles); + +/** + * @brief Start the procedure to write a characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to write a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start the procedure to write a characteristic reliably. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to write a long characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP + * event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic descriptor + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start the procedure to write a characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to read the descriptor specified. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the descriptor to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to write a characteristic value without waiting for any response from the server. + * @note No events are generated after this command is executed. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 3) + * @param[in] attr_val Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start a signed write without response from the server. + * @note The procedure i used to write a characteristic value with an authentication signature without waiting + * for any response from the server. It cannot be used when the link is encrypted. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 13). + * @param attr_val Value to be written + * @return Value indicating success or error code + */ +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Confirm an indication + * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); + +/** + * @brief Allow or reject a write request from a client. + * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, + * then the status has to be set to 1 and the error code has to be set to the error code that has to be + * passed to the client. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n + * 0x01: The value cannot be written to the attribute specified by the attr_handle. + * @param err_code The error code that has to be passed to the client in case the write has to be rejected. + * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val); + +/** + * @brief Allow the GATT server to send a response to a read request from a client. + * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ + * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response + * can be sent to the client. So if the application wishes to update any of the attributes before + * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value + * and then give this command. The application should perform the required operations within 30 seconds, + * otherwise the GATT procedure will go to timeout. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_allow_read(uint16_t conn_handle); + +/** + * @brief Set the security permission for the attribute handle specified. + * @note Currently the setting of security permission is allowed only for client configuration descriptor. + * @param service_handle Handle of the service which contains the attribute whose security + * permission has to be modified. + * @param attr_handle Handle of the attribute whose security permission has to be modified. + * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission); + +/** + * @brief This command sets the value of the descriptor specified by charDescHandle. + * @param servHandle Handle of the service which contains the descriptor. + * @param charHandle Handle of the characteristic which contains the descriptor. + * @param charDescHandle Handle of the descriptor whose value has to be set. + * @param charDescValOffset Offset from which the descriptor value has to be updated. + * @param charDescValueLen Length of the descriptor value + * @param[in] charDescValue descriptor value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue); + +/** + * @brief Reads the value of the attribute handle specified from the local GATT database. + * @param attr_handle Handle of the attribute to read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + + /** + * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. + * @param attr_handle Handle of the attribute to read + * @param offset Offset from which the value needs to be read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); +/** + * @brief Update the value of a characteristic and sends notifications or indications. + * @note This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute + * up to 512 bytes and indicate selectively the generation of indications and notifications. + * @param service_handle Handle of the service to which the characteristic belongs. + * @param char_handle Handle of the characteristic + * @param update_type Bitmask that controls generation of notifications and indications. It can be a combination + * @arg @ref NOTIFICATION (0x01): send notification, if enabled. + * @arg @ref INDICATION (0x02): send indication, if enabled. + * If set to 0 no notifications or indications are sent. + * @param char_length Total length of the characteristic value. In case of a variable size characteristic, + * this field specifies the new length of the characteristic value after the update; + * in case of fixed length characteristic this field is ignored. + * @param value_offset The offset from which the attribute value has to be updated + * @param value_length Length of the value to be updated + * @param[out] value Updated characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value); + +/** + * @} + */ + + +/** + * @defgroup GATT_Events GATT events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** + * This event (if enabled, see @ref Gatt_Event_Mask "Gatt Event Mask") is raised to the application + * by the GATT server when a client modifies any attribute on the server, as consequence of one of + * the following GATT procedures: + * @li write without response + * @li signed write without response + * @li write characteristic value + * @li write long characteristic value + * @li reliable write. + * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. + */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint16_t offset; /**< Offset from which the write has been performed by the peer device */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB05A1; + +typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB04A1; + +/** + * This event is generated by the client/server to the application on a GATT timeout (30 seconds). + * See @ref _evt_gatt_procedure_timeout. + */ +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +typedef __packed struct _evt_gatt_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ +} PACKED evt_gatt_procedure_timeout; + +/** + * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). + * See @ref _evt_att_exchange_mtu_resp. + */ +#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) +typedef __packed struct _evt_att_exchange_mtu_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data (always 1). */ + uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ +} PACKED evt_att_exchange_mtu_resp; + +/** + * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and + * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. + */ +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef __packed struct _evt_att_find_information_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ + /** + * A sequence of handle-uuid pairs.\n + * @li if format=1, each pair is:\n + * [2 octets for handle, 2 octets for UUIDs] \n + * @li if format=2, each pair is:\n + * [2 octets for handle, 16 octets for UUIDs] + */ + uint8_t handle_uuid_pair[VARIABLE_SIZE]; +} PACKED evt_att_find_information_resp; + +/** + * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See + * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. + */ +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +typedef __packed struct _evt_att_find_by_type_val_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + /** + * Handles Information List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] + */ + uint8_t handles_info_list[VARIABLE_SIZE]; +} PACKED evt_att_find_by_type_val_resp; + +/** + * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and + * aci_gatt_disc_all_charac_of_serv(). + * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. + */ +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef __packed struct _evt_att_read_by_type_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ + /** + * Attribute Data List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] + */ + uint8_t handle_value_pair[VARIABLE_SIZE]; +} PACKED evt_att_read_by_type_resp; + +/** + * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). + * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. + */ +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +typedef __packed struct _evt_att_read_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ +} PACKED evt_att_read_resp; + +/** + * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). + * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. + */ +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +typedef __packed struct _evt_att_read_blob_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ +} PACKED evt_att_read_blob_resp; + +/** + * This event is generated in response to a @a Read @a Multiple @a Request. + * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. + */ +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +typedef __packed struct _evt_att_read_mult_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ +} PACKED evt_att_read_mult_resp; + +/** + * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). + * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. + */ +#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) +typedef __packed struct _evt_att_read_by_group_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_data_length; /**< The size of each Attribute Data. */ + /** + * A list of Attribute Data where the attribute data is composed by: + * @li 2 octets for Attribute Handle + * @li 2 octets for End Group Handle + * @li (attribute_data_length - 4) octets for Attribute Value + */ + uint8_t attribute_data_list[VARIABLE_SIZE]; +} PACKED evt_att_read_by_group_resp; + +/** + * This event is generated in response to a @a Prepare @a Write @a Request. + * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. + */ +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +typedef __packed struct _evt_att_prepare_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attribute_handle; /**< The handle of the attribute to be written. */ + uint16_t offset; /**< The offset of the first octet to be written. */ + uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ +} PACKED evt_att_prepare_write_resp; + +/** + * This event is generated in response to an @a Execute @a Write @a Request. + * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. + */ +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +typedef __packed struct _evt_att_exec_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Always 0. */ +} PACKED evt_att_exec_write_resp; + +/** + * This event is generated when an indication is received from the server. + * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. + */ +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +typedef __packed struct _evt_gatt_indication{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_indication; + +/** + * This event is generated when a notification is received from the server. + * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. + */ +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef __packed struct _evt_gatt_notification{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_attr_notification; + +/** + * This event is generated when a GATT client procedure completes either with error or successfully. + * See @ref _evt_gatt_procedure_complete. + */ +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef __packed struct _evt_gatt_procedure_complete{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ + uint8_t data_length; /**< Length of error_code field (always 1). */ + /** + * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). + */ + uint8_t error_code; +} PACKED evt_gatt_procedure_complete; + +/** + * This event is generated when an Error Response is received from the server. The error response can be given + * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended + * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. + */ +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +typedef __packed struct _evt_gatt_error_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t req_opcode; /**< The request that generated this error response. */ + uint16_t attr_handle; /**< The attribute handle that generated this error response. */ + uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ +} PACKED evt_gatt_error_resp; + +/** + * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using + * Characteristic UUID" procedure. + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. + */ +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + /** + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. + */ + uint8_t attr_value[VARIABLE_SIZE]; +} PACKED evt_gatt_disc_read_char_by_uuid_resp; + +/** + * This event is given to the application when a write request, write command or signed write command + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * If the write is rejected by the application, then the value of the attribute will not be modified. + * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. + * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef __packed struct _evt_gatt_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_write_permit_req; + +/** + * This event is given to the application when a read request or read blob request is received by the server + * from the client. This event will be given to the application only if the event bit for this event generation + * is set when the characteristic was added. + * On receiving this event, the application can update the value of the handle if it desires and when done + * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef __packed struct _evt_gatt_read_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ + uint8_t data_length; /**< Length of offset field. */ + uint16_t offset; /**< Contains the offset from which the read has been requested */ +} PACKED evt_gatt_read_permit_req; + +/** + * This event is given to the application when a read multiple request or read by type request is received + * by the server from the client. This event will be given to the application only if the event bit for this + * event generation is set when the characteristic was added. + * On receiving this event, the application can update the values of the handles if it desires and when done + * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_multi_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) +typedef __packed struct _evt_gatt_read_multi_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ +} PACKED evt_gatt_read_multi_permit_req; + +/** + * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2). + * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES. + * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value(). + * See @ref evt_gatt_tx_pool_vailable. + * + */ +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE (0x0C16) +typedef __packed struct _evt_gatt_tx_pool_available{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t available_buffers; /**< Length of data field. */ +} PACKED evt_gatt_tx_pool_available; + +/** + * This event is raised on the server when the client confirms the reception of an indication. + */ +#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT (0x0C17) +typedef __packed struct _evt_gatt_server_confirmation{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ +} PACKED evt_gatt_server_confirmation; +/** + * This event is given to the application when a prepare write request + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * Based on the response from the application, the attribute value will be modified by the stack. + * If the write is rejected by the application, then the value of the attribute will not be modified + * and an error response will be sent to the client, with the error code as specified by the application. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ (0x0C18) +typedef __packed struct _evt_gatt_prepare_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint16_t offset; /**< The offset from which the prepare write has been requested */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_prepare_write_permit_req; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,229 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gatt_server.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GATT server layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BNRG_GATT_SERVER_H__ +#define __BNRG_GATT_SERVER_H__ + +#include "ble_compiler.h" +#include "ble_status.h" + +/** + *@addtogroup GATT GATT + *@{ + */ + +/** + * @anchor Well-Known_UUIDs + * @name Well-Known UUIDs + * @{ + */ +#define PRIMARY_SERVICE_UUID (0x2800) +#define SECONDARY_SERVICE_UUID (0x2801) +#define INCLUDE_SERVICE_UUID (0x2802) +#define CHARACTERISTIC_UUID (0x2803) +#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) +#define CHAR_USER_DESC_UUID (0x2901) +#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) +#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) +#define CHAR_FORMAT_DESC_UUID (0x2904) +#define CHAR_AGGR_FMT_DESC_UUID (0x2905) +#define GATT_SERVICE_UUID (0x1801) +#define GAP_SERVICE_UUID (0x1800) +#define SERVICE_CHANGED_UUID (0x2A05) +/** + * @} + */ + +/** + * @anchor Access_permissions + * @name Access permissions + * Access permissions for an attribute + * @{ + */ +#define ATTR_NO_ACCESS (0x00) +#define ATTR_ACCESS_READ_ONLY (0x01) +#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) +#define ATTR_ACCESS_READ_WRITE (0x03) +#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) +#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) +/** + * Allows all write procedures + */ +#define ATTR_ACCESS_WRITE_ANY (0x0E) +/** + * @} + */ + +/** + * @anchor Char_properties + * @name Characteristic properties. + * @{ + */ +#define CHAR_PROP_BROADCAST (0x01) +#define CHAR_PROP_READ (0x02) +#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) +#define CHAR_PROP_WRITE (0x08) +#define CHAR_PROP_NOTIFY (0x10) +#define CHAR_PROP_INDICATE (0x20) +#define CHAR_PROP_SIGNED_WRITE (0x40) +#define CHAR_PROP_EXT (0x80) +/** + * @} + */ + + +/** + * @anchor Security_permissions + * @name Security permissions for an attribute. + * @{ + */ +#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ +#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ +#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ +#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ +/** + * @} + */ + +/** + * @anchor UUID_Types + * @name Type of UUID (16 bit or 128 bit). + * @{ + */ +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) +/** + * @} + */ + +/** + * @anchor Service_type + * @name Type of service (primary or secondary) + * @{ + */ +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) +/** + * @} + */ + +/** + * @anchor Gatt_Event_Mask + * @name Gatt Event Mask + * Type of event generated by GATT server + * @{ + */ +#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ +#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. + An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ +#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd + or a signed write cmd are received by the server for this attribute. + An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ +#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is + received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ +/** + * @} + */ + +/** + * @name Type of characteristic length + * See aci_gatt_add_char() + * @{ + */ +#define CHAR_VALUE_LEN_CONSTANT (0x00) +#define CHAR_VALUE_LEN_VARIABLE (0x01) +/** + * @} + */ + + +/** + * @name Encryption key size + * @{ + */ +/** + * Minimum encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Maximum encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) +/** + * @} + */ + +/** + * @name Characteristic Presentation Format + * @{ + */ +typedef __packed struct _charactFormat { + uint8_t format; + int8_t exp; + uint16_t unit; + uint8_t name_space; + uint16_t desc; +} PACKED charactFormat; + +/** + * @} + */ + +/** + * @name Format + * @{ + */ +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F +/** + * @} + */ + +/** + * @name Unit + * @{ + */ +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 +/** + * @} + */ + + +/** + * ATT MTU size + */ +#define ATT_MTU (23) + +/** + * @} + */ + + /** + * @name Update type of aci_gatt_upd_char_val_ext(). + * @{ + */ + +#define NOTIFICATION 1 +#define INDICATION 2 + +#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,385 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hal_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with HCI commands for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_HAL_ACI_H__ +#define __BLUENRG_HAL_ACI_H__ + +/** + *@addtogroup HAL HAL + *@brief Hardware Abstraction Layer. + *@{ + */ + +/** + * @defgroup HAL_Functions HAL functions + * @brief API for BlueNRG HAL layer. + * @{ + */ + +/** + * @brief This command retrieves the buid number of the firmware. + * @param[out] build_number Build number identifying the firmware release. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number); + +/** + * @brief This command writes a value to a low level configure data structure. + * @note It is useful to setup directly some low level parameters for the system at runtime. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * + * @param len Length of data to be written + * @param[out] val Data to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val); + +/** + * @brief This command requests the value in the low level configure data structure. + * The number of read bytes changes for different Offset. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * @param data_len Length of the data buffer + * @param[out] data_len_out_p length of the data returned by the read. + * @param[out] data Read data + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data); + +/** + * @brief This command sets the TX power level of the BlueNRG. + * @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines + * the output power level (dBm). + * When the system starts up or reboots, the default TX power level will be used, which is + * the maximum value of 8dBm. Once this command is given, the output power will be changed + * instantly, regardless if there is Bluetooth communication going on or not. For example, + * for debugging purpose, the BlueNRG can be set to advertise all the time and use this + * command to observe the signal strength changing. The system will keep the last received + * TX power level from the command, i.e. the 2nd command overwrites the previous TX power + * level. The new TX power level remains until another Set TX Power command, or the system + * reboots.\n + * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the + * right value, depending on the selected hardware configuration for the RF network: + * normal mode or high power mode. + * @param pa_level Can be from 0 to 7. Set the PA level value. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +/** + * @brief This command returns the number of packets sent in Direct Test Mode. + * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets + * have been transmitted. This command can be used to check how many packets have been sent + * during the Direct TX test.\n + * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again. + * The counter is not cleared until the next Direct TX test starts. + * @param[out] number_of_packets Number of packets sent during the last Direct TX test. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets); + +/** + * @brief Put the device in standby mode. + * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the + * device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode, + * the device can still wake up itself with the internal timer. But in standby mode, this timer is + * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command + * sent via SPI bus. + * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code + * ERR_COMMAND_DISALLOWED will be returned. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_device_standby(void); + +/** + * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. + * @note The frequency sine wave at the specific channel may be used for test purpose only. + * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. + * This command shouldn't be used when normal Bluetooth activities are ongoing. + * The tone should be stopped by aci_hal_tone_stop() command. + * + * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the + * channel central frequency minus 250 kHz. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +/** + * This command is used to stop the previously started aci_hal_tone_start() command. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_stop(void); + +/** + * @brief This command returns the status of all the connections. + * @note This command returns the status of the 8 Bluetooth low energy links managed by the device. + * @param[out] link_status Array of link status (8 links). See @ref Link_Status. + * @param[out] conn_handle Array of connection handles for each link. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]); + +/** + * @brief This command returns the anchor period and the largest available slot. + * @note This command returns information about the anchor period to help application in selecting + * slot timings when operating in multi-link scenarios. + * @param anchor_period Current anchor period (multiple of 0.625 ms). + * @param max_free_slot Maximum available time (multiple of 0.625 ms) that can be allocated for a new slot. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot); + +/** + * @} + */ + +/** + * @defgroup HAL_Events HAL events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_HAL_INITIALIZED (0x0001) +typedef __packed struct _evt_hal_initialized{ + uint8_t reason_code; /**< Reset reason. See @ref Reset_Reasons */ +} PACKED evt_hal_initialized; + +/** + * This event is generated when an overflow occurs in the event queue read by the external microcontroller. + * This is normally caused when the external microcontroller does not read pending events. + * The returned bitmap indicates which event has been lost. Please note that one bit set to 1 indicates one or + * more occurrences of the particular events. The event EVT_BLUE_HAL_EVENTS_LOST cannot be lost and it will + * be inserted in the event queue as soon as a position is freed in the event queue. This event should not + * happen under normal operating condition where external microcontroller promptly reads events signaled by + * IRQ pin. It is provided to detected unexpected behavior of the external microcontroller or to allow + * application to recover situations where critical events are lost. + */ +#define EVT_BLUE_HAL_EVENTS_LOST_IDB05A1 (0x0002) +typedef __packed struct _evt_hal_events_lost{ + uint8_t lost_events[8]; /**< Bitmap of lost events. Each bit indicates one or more occurrences of the specific event. See @ref Lost_Events */ +} PACKED evt_hal_events_lost_IDB05A1; + + +/** + * This event is given to the application after the @ref ACI_BLUE_INITIALIZED_EVENT + * when a system crash is detected. This events returns system crash information for debugging purposes. + * Information reported are useful to understand the root cause of the crash. + */ +#define EVT_BLUE_HAL_CRASH_INFO_IDB05A1 (0x0003) +typedef __packed struct _evt_hal_crash_info{ + uint8_t crash_type; /**< Type of crash: Assert failed (0), NMI Fault (1), Hard Fault (2) */ + uint32_t sp; /**< SP register */ + uint32_t r0; /**< R0 register */ + uint32_t r1; /**< R1 register */ + uint32_t r2; /**< R2 register */ + uint32_t r3; /**< R3 register */ + uint32_t r12; /**< R12 register */ + uint32_t lr; /**< LR register */ + uint32_t pc; /**< PC register */ + uint32_t xpsr; /**< xPSR register */ + uint8_t debug_data_len; /**< length of debug_data field */ + uint8_t debug_data[VARIABLE_SIZE]; /**< Debug data */ +} PACKED evt_hal_crash_info_IDB05A1; + + +/** + * @} + */ + + +/** + * @anchor Reset_Reasons + * @name Reset Reasons + * See @ref EVT_BLUE_HAL_INITIALIZED. + * @{ + */ +#define RESET_NORMAL 1 /**< Normal startup. */ +#define RESET_UPDATER_ACI 2 /**< Updater mode entered with ACI command */ +#define RESET_UPDATER_BAD_FLAG 3 /**< Updater mode entered due to a bad BLUE flag */ +#define RESET_UPDATER_PIN 4 /**< Updater mode entered with IRQ pin */ +#define RESET_WATCHDOG 5 /**< Reset caused by watchdog */ +#define RESET_LOCKUP 6 /**< Reset due to lockup */ +#define RESET_BROWNOUT 7 /**< Brownout reset */ +#define RESET_CRASH 8 /**< Reset caused by a crash (NMI or Hard Fault) */ +#define RESET_ECC_ERR 9 /**< Reset caused by an ECC error */ +/** + * @} + */ + + +/** + * @defgroup Config_vals Offsets and lengths for configuration values. + * @brief Offsets and lengths for configuration values. + * See aci_hal_write_config_data(). + * @{ + */ + +/** + * @name Configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ +#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ +#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ +#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ +#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. + It can be written only if aci_hal_write_config_data() is the first command after reset. */ +#define CONFIG_DATA_RANDOM_ADDRESS (0x80) /**< Stored static random address. Read-only. */ + +/** + * Select the BlueNRG mode configurations.\n + * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) + * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) + * @li Mode 3: master/slave, 8 connections, RAM1 and RAM2. + * @li Mode 4: master/slave, 4 connections, RAM1 and RAM2 simultaneous scanning and advertising. + */ +#define CONFIG_DATA_MODE_OFFSET (0x2D) + +#define CONFIG_DATA_WATCHDOG_DISABLE (0x2F) /**< Set to 1 to disable watchdog. It is enabled by default. */ +/** + * @} + */ + +/** + * @name Length for configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_LEN (6) +#define CONFIG_DATA_DIV_LEN (2) +#define CONFIG_DATA_ER_LEN (16) +#define CONFIG_DATA_IR_LEN (16) +#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) +#define CONFIG_DATA_MODE_LEN (1) +#define CONFIG_DATA_WATCHDOG_DISABLE_LEN (1) +/** + * @} + */ + +/** + * @anchor Link_Status + * @name Status of the link + * See @ref aci_hal_get_link_status(). + * @{ + */ +#define STATUS_IDLE 0 +#define STATUS_ADVERTISING 1 +#define STATUS_CONNECTED_AS_SLAVE 2 +#define STATUS_SCANNING 3 +#define STATUS_CONNECTED_AS_MASTER 5 +#define STATUS_TX_TEST 6 +#define STATUS_RX_TEST 7 +/** + * @} + */ + +/** + * @} + */ + + /** + * @anchor Lost_Events + * @name Lost events bitmap + * See @ref EVT_BLUE_HAL_EVENTS_LOST. + * @{ + */ +#define EVT_DISCONN_COMPLETE_BIT 0 +#define EVT_ENCRYPT_CHANGE_BIT 1 +#define EVT_READ_REMOTE_VERSION_COMPLETE_BIT 2 +#define EVT_CMD_COMPLETE_BIT 3 +#define EVT_CMD_STATUS_BIT 4 +#define EVT_HARDWARE_ERROR_BIT 5 +#define EVT_NUM_COMP_PKTS_BIT 6 +#define EVT_ENCRYPTION_KEY_REFRESH_BIT 7 +#define EVT_BLUE_HAL_INITIALIZED_BIT 8 +#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE_BIT 9 +#define EVT_BLUE_GAP_PAIRING_CMPLT_BIT 10 +#define EVT_BLUE_GAP_PASS_KEY_REQUEST_BIT 11 +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST_BIT 12 +#define EVT_BLUE_GAP_SECURITY_REQ_INITIATED_BIT 13 +#define EVT_BLUE_GAP_BOND_LOST_BIT 14 +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE_BIT 15 +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_BIT 16 +#define EVT_BLUE_L2CAP_CONN_UPDATE_RESP_BIT 17 +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT_BIT 18 +#define EVT_BLUE_L2CAP_CONN_UPDATE_REQ_BIT 19 +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_BIT 20 +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT_BIT 21 +#define EVT_BLUE_EXCHANGE_MTU_RESP_BIT 22 +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP_BIT 23 +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP_BIT 24 +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP_BIT 25 +#define EVT_BLUE_ATT_READ_RESP_BIT 26 +#define EVT_BLUE_ATT_READ_BLOB_RESP_BIT 27 +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP_BIT 28 +#define EVT_BLUE_ATT_READ_BY_GROUP_RESP_BIT 29 +#define EVT_BLUE_ATT_WRITE_RESP_BIT 30 +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP_BIT 31 +#define EVT_BLUE_ATT_EXEC_WRITE_RESP_BIT 32 +#define EVT_BLUE_GATT_INDICATION_BIT 33 +#define EVT_BLUE_GATT_NOTIFICATION_BIT 34 +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE_BIT 35 +#define EVT_BLUE_GATT_ERROR_RESP_BIT 36 +#define EVT_BLUE_GATT_DISC_READ_CHARAC_BY_UUID_RESP_BIT 37 +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ_BIT 38 +#define EVT_BLUE_GATT_READ_PERMIT_REQ_BIT 39 +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ_BIT 40 +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_BIT 41 +#define EVT_BLUE_GATT_SERVER_RX_CONFIRMATION_BIT 42 +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ_BIT 43 +#define EVT_LL_CONNECTION_COMPLETE_BIT 44 +#define EVT_LL_ADVERTISING_REPORT_BIT 45 +#define EVT_LL_CONNECTION_UPDATE_COMPLETE_BIT 46 +#define EVT_LL_READ_REMOTE_USED_FEATURES_BIT 47 +#define EVT_LL_LTK_REQUEST_BIT 48 +/** + * @} + */ + +/** + * @name Hardware error event codes + * See @ref EVT_HARDWARE_ERROR. + * @{ + */ +/** + * Error on the SPI bus has been detected, most likely caused by incorrect SPI configuration on the external micro-controller. + */ +#define SPI_FRAMING_ERROR 0 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define RADIO_STATE_ERROR 1 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define TIMER_OVERRUN_ERROR 2 + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,166 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_l2cap_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with L2CAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_L2CAP_ACI_H__ +#define __BLUENRG_L2CAP_ACI_H__ + +/** + *@addtogroup L2CAP L2CAP + *@brief L2CAP layer. + *@{ + */ + +/** + *@defgroup L2CAP_Functions L2CAP functions + *@brief API for L2CAP layer. + *@{ + */ + +/** + * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. + * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request + * (accepts or rejects). + * @param conn_handle Connection handle on which the connection parameter update request has to be sent. + * @param interval_min Defines minimum value for the connection event interval in the following manner: + * connIntervalMin = interval_min x 1.25ms + * @param interval_max Defines maximum value for the connection event interval in the following manner: + * connIntervalMax = interval_max x 1.25ms + * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). + * @param timeout_multiplier Defines connection timeout parameter in the following manner: + * timeout_multiplier x 10ms. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier); +/** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param min_ce_length Minimum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_ce_length Maximum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept); + /** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept); + +/** + * @} + */ + +/** + * @defgroup L2CAP_Events L2CAP events + * @{ + */ + +/** + * This event is generated when the master responds to the L2CAP connection update request packet. + * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. + */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef __packed struct _evt_l2cap_conn_upd_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ +/** + * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. + * @li 0x01 in case of Command Reject. + */ + uint8_t code; + uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ + uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ +/** + * Result code (parameters accepted or rejected) in case of Connection Parameter Update + * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). + */ + uint16_t result; +} PACKED evt_l2cap_conn_upd_resp; + +/** + * This event is generated when the master does not respond to the connection update request + * within 30 seconds. + */ +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) +typedef __packed struct _evt_l2cap_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */ +} PACKED evt_l2cap_procedure_timeout; + +/** + * The event is given by the L2CAP layer when a connection update request is received from the slave. + * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). + */ +#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) +typedef __packed struct _evt_l2cap_conn_upd_req{ +/** + * Handle of the connection for which the connection update request has been received. + * The same handle has to be returned while responding to the event with the command + * aci_l2cap_connection_parameter_update_response(). + */ + uint16_t conn_handle; + uint8_t event_data_length; /**< Length of following data. */ +/** + * This is the identifier which associates the request to the + * response. The same identifier has to be returned by the upper + * layer in the command aci_l2cap_connection_parameter_update_response(). + */ + uint8_t identifier; + uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ + uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ +} PACKED evt_l2cap_conn_upd_req; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_updater_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with updater commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_UPDATER_ACI_H__ +#define __BLUENRG_UPDATER_ACI_H__ + +#include <ble_compiler.h> + +/** + * @defgroup Updater Updater + * @brief Updater. + * @{ + */ + +/** + * @defgroup Updater_Functions Updater functions + * @brief API for BlueNRG Updater. + * @{ + */ + +tBleStatus aci_updater_start(void); + +tBleStatus aci_updater_reboot(void); + +tBleStatus aci_get_updater_version(uint8_t *version); + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); + +tBleStatus aci_erase_blue_flag(void); + +tBleStatus aci_reset_blue_flag(void); + +tBleStatus aci_updater_erase_sector(uint32_t address); + +tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); + +tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); + +tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); + +tBleStatus aci_updater_hw_version(uint8_t *version); + +/** + * @} + */ + +/** + * @defgroup Updater_Events Updater events + * @{ + */ +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_INITIALIZED (0x0001) +typedef __packed struct _evt_blue_initialized{ + uint8_t reason_code; +} PACKED evt_blue_initialized; +/** + * @} + */ + +/** + * @} + */ + + + +#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,204 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_utils.h +* Author : AMS - VMA, RF Application Team +* Version : V1.0.1 +* Date : 03-October-2014 +* Description : Header file for BlueNRG utility functions +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + * @file bluenrg_utils.h + * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description + * + * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> +**/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLUENRG_UTILS_H +#define __BLUENRG_UTILS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ble_hal_types.h" +#include "ble_compiler.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct{ + uint8_t stack_mode; + uint8_t day; + uint8_t month; + uint8_t year; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint16_t hs_startup_time; /* In system time units*/ +} IFR_config2_TypeDef; + +/** + * Structure inside IFR for configuration options. + */ +typedef __packed struct{ + uint8_t cold_ana_act_config_table[64]; + uint8_t hot_ana_config_table[64]; + uint8_t stack_mode; + uint8_t gpio_config; + uint8_t rsrvd1[2]; + uint32_t rsrvd2[3]; + uint32_t max_conn_event_time; + uint32_t ls_crystal_period; + uint32_t ls_crystal_freq; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint8_t rsrvd3; + uint16_t hs_startup_time; /* In system time units*/ + uint8_t rsrvd4[2]; + uint32_t uid; + uint8_t rsrvd5; + uint8_t year; + uint8_t month; + uint8_t day; + uint32_t unused[5]; +} PACKED IFR_config_TypeDef; + +/* Exported constants --------------------------------------------------------*/ +extern const IFR_config_TypeDef IFR_config; + +/* Exported macros -----------------------------------------------------------*/ +#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)+1) +#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) + +/* Convert 2 digit BCD number to an integer */ +#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) + +/* Convert 2 digit number to a BCD number */ +#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) + +/** + * Return values + */ +#define BLE_UTIL_SUCCESS 0 +#define BLE_UTIL_UNSUPPORTED_VERSION 1 +#define BLE_UTIL_WRONG_IMAGE_SIZE 2 +#define BLE_UTIL_ACI_ERROR 3 +#define BLE_UTIL_CRC_ERROR 4 +#define BLE_UTIL_PARSE_ERROR 5 +#define BLE_UTIL_WRONG_VERIFY 6 + +/* Exported functions ------------------------------------------------------- */ +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int program_device(const uint8_t *fw_image, uint32_t fw_size); + +/** + * @brief Read raw data from IFR (3 64-bytes blocks). + * @param data Pointer to the buffer that will contain the read data. + * Its size must be 192 bytes. This data can be parsed by + * parse_IFR_data_config(). + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION) + */ +int read_IFR(uint8_t data[192]); + +/** + * @brief Verify raw data from IFR (3 64-bytes blocks). + * @param ifr_data Pointer to the buffer that will contain the data to verify. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) + */ +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); + +/** + * @brief Program raw data to IFR (3 64-bytes blocks). + * @param ifr_image Pointer to the buffer that will contain the data to program. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful + */ +int program_IFR(const IFR_config_TypeDef *ifr_image); + +/** + * @brief Parse IFR raw data. + * @param data Pointer to the raw data: last 64 bytes read from IFR sector. + * @param IFR_config Data structure that will be filled with parsed data. + * @retval None + */ +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); + +/** + * @brief Check for the correctness of parsed data. + * @param IFR_config Data structure filled with parsed data. + * @retval int It returns 0 if successful, or PARSE_ERROR in case data is + * not correct. + */ +int IFR_validate(IFR_config2_TypeDef *IFR_config); + +/** + * @brief Modify IFR data. (Last 64-bytes block). + * @param IFR_config Structure that contains the new parameters inside the + * IFR configuration data. + * @note It is highly recommended to parse the IFR configuration from + * a working IFR block (this should be done with parse_IFR_data_config()). + * Then it is possible to write the new parameters inside the IFR_config + * structure. + * @param data Pointer to the buffer that contains the original data. It + * will be modified according to the new data in the IFR_config + * structure. Then this data must be written in the last + * 64-byte block in the IFR. + * Its size must be 64 bytes. + * @retval None + */ +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); + +/** + * @brief Get BlueNRG hardware and firmware version + * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). + * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN + * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. + * @retval Status of the call + */ +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); + +/** + * @brief Get BlueNRG updater version + * @param version This parameter returns the updater version. If the updadter version is 0x03 + * the chip has the updater old, needs to update the bootloader. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterVersion(uint8_t *version); + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version); + +/** + * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on + * the HW bootloader related to the 32 MHz external crystal oscillator. + * @retval TRUE if the HW bootloader is already patched, FALSE otherwise + */ +uint8_t isHWBootloader_Patched(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__BLUENRG_UTILS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file bluenrg_targets.h + * @author AST / EST + * @version V0.0.1 + * @date 24-July-2015 + * @brief This header file is intended to manage the differences between + * the different supported base-boards which might mount the + * X_NUCLEO_IDB0XA1 BlueNRG BLE Expansion Board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent from recursive inclusion --------------------------------*/ +#ifndef _BLUENRG_TARGETS_H_ +#define _BLUENRG_TARGETS_H_ + +#if !defined(BLUENRG_PIN_SPI_MOSI) +#define BLUENRG_PIN_SPI_MOSI (D11) +#endif +#if !defined(BLUENRG_PIN_SPI_MISO) +#define BLUENRG_PIN_SPI_MISO (D12) +#endif +#if !defined(BLUENRG_PIN_SPI_nCS) +#define BLUENRG_PIN_SPI_nCS (A1) +#endif +#if !defined(BLUENRG_PIN_SPI_RESET) +#define BLUENRG_PIN_SPI_RESET (D7) +#endif +#if !defined(BLUENRG_PIN_SPI_IRQ) +#define BLUENRG_PIN_SPI_IRQ (A0) +#endif + +/* NOTE: Refer to README for further details regarding BLUENRG_PIN_SPI_SCK */ +#if !defined(BLUENRG_PIN_SPI_SCK) +#define BLUENRG_PIN_SPI_SCK (D3) +#endif + +/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv) + * Mode 0x01: slave or master, 1 connection + * Mode 0x02: slave or master, 1 connection + * Mode 0x03: master/slave, 8 connections + * Mode 0x04: master/slave, 4 connections (simultaneous scanning and advertising) + * Check Table 285 of + * BlueNRG-MS Bluetooth LE stack application command interface (ACI) User Manual (UM1865) at st.com + */ +#if !defined(BLUENRG_STACK_MODE) +#define BLUENRG_STACK_MODE (0x04) +#endif + +#endif // _BLUENRG_TARGTES_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef _BTLE_H_ +#define _BTLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "bluenrg_aci.h" +#include "ble_hci_const.h" +#include "bluenrg_hal_aci.h" +#include "stm32_bluenrg_ble.h" +#include "bluenrg_gap.h" +#include "bluenrg_gatt_server.h" + +extern uint16_t g_gap_service_handle; +extern uint16_t g_appearance_char_handle; +extern uint16_t g_device_name_char_handle; +extern uint16_t g_preferred_connection_parameters_char_handle; + +void btleInit(void); +void SPI_Poll(void); +void User_Process(void); +void setConnectable(void); +void setVersionString(uint8_t hwVersion, uint16_t fwVersion); +const char* getVersionString(void); +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type); + + +extern int btle_handler_pending; +extern void btle_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.h + * @author CL + * @version V1.0.1 + * @date 15-June-2014 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_BLUENRG_BLE_H +#define __STM32_BLUENRG_BLE_H + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdint.h> +#include "ble_gp_timer.h" +#include "ble_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup X-NUCLEO-IDB04A1 + * @{ + */ + +/** @addtogroup STM32_BLUENRG_BLE + * @{ + */ + +/** @defgroup STM32_BLUENRG_BLE_Exported_Functions + * @{ + */ + +// FIXME: add prototypes for BlueNRG here +void BlueNRG_RST(void); +uint8_t BlueNRG_DataPresent(void); +void BlueNRG_HW_Bootloader(void); +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size); +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, + uint8_t Nb_bytes1, + uint8_t Nb_bytes2); +void Clear_SPI_EXTI_Flag(void); + +void print_csv_time(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_BLUENRG_BLE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_debug.h" + +#ifndef __PAYLOAD_H__ +#define __PAYLOAD_H__ + +class UnitPayload +{ +public: + uint8_t length; + uint8_t id; + uint8_t *data; + uint8_t *idptr; + + + + void set_length(uint8_t l) { + length=l; + } + + void set_id(uint8_t i) { + id=i; + } + + void set_data(uint8_t* data1) { + for(int j=0;j<length;j++) + { + data[j]=data1[j]; + } + } + + uint8_t get_length() { + return length; + } + + uint8_t get_id() { + return id; + } + + uint8_t* get_data() { + return data; + } + +}; + +class Payload { + UnitPayload *payload; + int stringLength; + int payloadUnitCount; + +public: + Payload(const uint8_t *tokenString, uint8_t string_ength); + Payload(); + ~Payload(); + uint8_t getPayloadUnitCount(); + + uint8_t getIDAtIndex(int index); + uint8_t getLengthAtIndex(int index); + uint8_t* getDataAtIndex(int index); + int8_t getInt8AtIndex(int index); + uint16_t getUint16AtIndex(int index); + uint8_t* getSerializedAdDataAtIndex(int index); +}; + + +class PayloadUnit { +private: + uint8_t* lenPtr; + uint8_t* adTypePtr; + uint8_t* dataPtr; + +public: + PayloadUnit() { + lenPtr = NULL; + adTypePtr = NULL; + dataPtr = NULL; + } + + PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { + lenPtr = len; + adTypePtr = adType; + dataPtr = data; + } + + void setLenPtr(uint8_t *len) { + lenPtr = len; + } + + void setAdTypePtr(uint8_t *adType) { + adTypePtr = adType; + } + + void setDataPtr(uint8_t *data) { + dataPtr = data; + } + + uint8_t* getLenPtr() { + return lenPtr; + } + + uint8_t* getAdTypePtr() { + return adTypePtr; + } + + uint8_t* getDataPtr() { + return dataPtr; + } + + void printDataAsHex() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("0x%x ", dataPtr[i]); + } + PRINTF("\n"); + } + + void printDataAsString() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("%c", dataPtr[i]); + } + PRINTF("\n"); + } + +}; + +class PayloadPtr { +private: + PayloadUnit *unit; + int payloadUnitCount; +public: + PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + int stringLength = string_ength; + payloadUnitCount = 0; + + int index = 0; + while(index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + // allocate memory to unit + unit = new PayloadUnit[payloadUnitCount]; + int i = 0; + int nextUnitOffset = 0; + + while(i<payloadUnitCount) { + unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); + unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); + unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); + + nextUnitOffset += *unit[i].getLenPtr()+1; + i++; + + } + } + + PayloadUnit getUnitAtIndex(int index) { + return unit[index]; + } + + int getPayloadUnitCount() { return payloadUnitCount; } + + ~PayloadPtr() { + if(unit) delete[] unit; + + unit = NULL; + } +}; + +#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include "ble_status.h" +#include "ble_hal_types.h" + +#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do {\ + uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ + }while(0) + + +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); + +#endif // __UTIL_H__ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/mbed_lib.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "bluenrg", + "target_overrides": { + "K64F": { + "target.macros_add": ["BLUENRG_PIN_SPI_SCK=D13"] + }, + "DISCO_L475VG_IOT01A": { + "target.macros_add": ["BLUENRG_PIN_SPI_MOSI=PC_12", + "BLUENRG_PIN_SPI_MISO=PC_11", + "BLUENRG_PIN_SPI_nCS=PD_13", + "BLUENRG_PIN_SPI_RESET=PA_8", + "BLUENRG_PIN_SPI_IRQ=PE_6", + "BLUENRG_PIN_SPI_SCK=PC_10"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,37 @@ +{ + "name": "x-nucleo-idb0xa1", + "version": "2.2.0", + "description": "ST driver for the mbed BLE API.", + "keywords": [ + "expansion", + "board", + "x-nucleo", + "nucleo", + "ST", + "STM", + "Bluetooth", + "BLE" + ], + "author": "Andrea Palmieri", + "repository": { + "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git", + "type": "git" + }, + "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "extraIncludes": [ + "x-nucleo-idb0xa1", + "x-nucleo-idb0xa1/utils", + "x-nucleo-idb0xa1/platform", + "x-nucleo-idb0xa1/bluenrg-hci" + ], + "dependencies": { + "mbed-drivers": ">=0.11.3", + "ble": "^2.7.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,474 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.cpp + * @author STMicroelectronics + * @brief Implementation of BLEDeviceInstanceBase + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGDevice + * @brief BlueNRG BLE_API Device Adaptation + * @{ + */ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGDevice.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" + +#include "btle.h" +#include "ble_utils.h" +#include "ble_osal.h" + +#include "ble_debug.h" +#include "stm32_bluenrg_ble.h" + +extern "C" { + #include "ble_hci.h" + #include "bluenrg_utils.h" +} + +#define HEADER_SIZE 5 +#define MAX_BUFFER_SIZE 255 + +/** + * The singleton which represents the BlueNRG transport for the BLEDevice. + * + * See file 'bluenrg_targets.h' for details regarding the peripheral pins used! + */ +#include "bluenrg_targets.h" + +BlueNRGDevice bluenrgDeviceInstance(BLUENRG_PIN_SPI_MOSI, + BLUENRG_PIN_SPI_MISO, + BLUENRG_PIN_SPI_SCK, + BLUENRG_PIN_SPI_nCS, + BLUENRG_PIN_SPI_RESET, + BLUENRG_PIN_SPI_IRQ); + +/** +* BLE-API requires an implementation of the following function in order to +* obtain its transport handle. +*/ +BLEInstanceBase * +createBLEInstance(void) +{ + return (&bluenrgDeviceInstance); +} + +/**************************************************************************/ +/** + @brief Constructor + * @param mosi mbed pin to use for MOSI line of SPI interface + * @param miso mbed pin to use for MISO line of SPI interface + * @param sck mbed pin to use for SCK line of SPI interface + * @param cs mbed pin to use for not chip select line of SPI interface + * @param rst mbed pin to use for BlueNRG reset + * @param irq mbed pin for BlueNRG IRQ +*/ +/**************************************************************************/ +BlueNRGDevice::BlueNRGDevice(PinName mosi, + PinName miso, + PinName sck, + PinName cs, + PinName rst, + PinName irq) : + isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq) +{ + // Setup the spi for 8 bit data, low clock polarity, + // 1-edge phase, with an 8MHz clock rate + spi_.format(8, 0); + spi_.frequency(8000000); + + // Deselect the BlueNRG chip by keeping its nCS signal high + nCS_ = 1; + + wait_us(500); + + // Prepare communication between the host and the BlueNRG SPI interface + HCI_Init(); + + // Set the interrupt handler for the device + irq_.mode(PullDown); // set irq mode + irq_.rise(&HCI_Isr); +} + +/**************************************************************************/ +/** + @brief Destructor +*/ +/**************************************************************************/ +BlueNRGDevice::~BlueNRGDevice(void) +{ +} + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param hw_version The HW version is written to this parameter + * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise + */ +uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version) +{ + uint8_t status; + + status = getBlueNRGUpdaterHWVersion(hw_version); + + return (status); +} + +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns BLE_STATUS_SUCCESS on success, or a number + * not equal to 0 in case of error + * (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size) +{ + int status = program_device(fw_image, fw_size); + + return (status); +} + + +/** + * @brief Initialises anything required to start using BLE + * @param[in] instanceID + * The ID of the instance to initialize. + * @param[in] callback + * A callback for when initialization completes for a BLE + * instance. This is an optional parameter set to NULL when not + * supplied. + * + * @return BLE_ERROR_NONE if the initialization procedure was started + * successfully. + */ +ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback) +{ + if (isInitialized) { + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_ALREADY_INITIALIZED + }; + callback.call(&context); + return BLE_ERROR_ALREADY_INITIALIZED; + } + + // Init the BlueNRG/BlueNRG-MS stack + btleInit(); + + isInitialized = true; + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_NONE + }; + callback.call(&context); + + return BLE_ERROR_NONE; +} + + +/** + @brief Resets the BLE HW, removing any existing services and + characteristics + @param[in] void + @returns void +*/ +void BlueNRGDevice::reset(void) +{ + /* Reset BlueNRG SPI interface. Hold reset line to 0 for 1500us */ + rst_ = 0; + wait_us(1500); + rst_ = 1; + + /* Wait for the radio to come back up */ + wait_us(5000); +} + +/*! + @brief Wait for any BLE Event like BLE Connection, Read Request etc. + @param[in] void + @returns char * +*/ +void BlueNRGDevice::waitForEvent(void) +{ + bool must_return = false; + + do { + bluenrgDeviceInstance.processEvents(); + + if(must_return) return; + + __WFE(); /* it is recommended that SEVONPEND in the + System Control Register is NOT set */ + must_return = true; /* after returning from WFE we must guarantee + that conrol is given back to main loop before next WFE */ + } while(true); + +} + +/*! + @brief get GAP version + @brief Get the BLE stack version information + @param[in] void + @returns char * + @returns char * +*/ +const char *BlueNRGDevice::getVersion(void) +{ + return getVersionString(); +} + +/**************************************************************************/ +/*! + @brief get reference to GAP object + @param[in] void + @returns Gap& +*/ +/**************************************************************************/ +Gap &BlueNRGDevice::getGap() +{ + return BlueNRGGap::getInstance(); +} + +const Gap &BlueNRGDevice::getGap() const +{ + return BlueNRGGap::getInstance(); +} + +/**************************************************************************/ +/*! + @brief get reference to GATT server object + @param[in] void + @returns GattServer& +*/ +/**************************************************************************/ +GattServer &BlueNRGDevice::getGattServer() +{ + return BlueNRGGattServer::getInstance(); +} + +const GattServer &BlueNRGDevice::getGattServer() const +{ + return BlueNRGGattServer::getInstance(); +} + +/**************************************************************************/ +/*! + @brief shut down the BLE device + @param[out] error if any +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::shutdown(void) { + PRINTF("BlueNRGDevice::reset\n"); + + if (!isInitialized) { + return BLE_ERROR_INITIALIZATION_INCOMPLETE; + } + + /* Reset the BlueNRG device first */ + reset(); + + /* Shutdown the BLE API and BlueNRG glue code */ + ble_error_t error; + + /* GattServer instance */ + error = BlueNRGGattServer::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* GattClient instance */ + error = BlueNRGGattClient::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* Gap instance */ + error = BlueNRGGap::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + isInitialized = false; + + PRINTF("BlueNRGDevice::reset complete\n"); + return BLE_ERROR_NONE; + +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size) +{ + uint16_t byte_count; + uint8_t len = 0; + uint8_t char_ff = 0xff; + volatile uint8_t read_char; + + uint8_t i = 0; + volatile uint8_t tmpreg; + + uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00}; + uint8_t header_slave[HEADER_SIZE]; + + /* Select the chip */ + nCS_ = 0; + + /* Read the header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = (uint8_t)(tmpreg); + } + + if (header_slave[0] == 0x02) { + /* device is ready */ + byte_count = (header_slave[4]<<8)|header_slave[3]; + + if (byte_count > 0) { + + /* avoid to read more data that size of the buffer */ + if (byte_count > buff_size){ + byte_count = buff_size; + } + + for (len = 0; len < byte_count; len++){ + read_char = spi_.write(char_ff); + buffer[len] = read_char; + } + } + } + /* Release CS line to deselect the chip */ + nCS_ = 1; + + // Add a small delay to give time to the BlueNRG to set the IRQ pin low + // to avoid a useless SPI read at the end of the transaction + for(volatile int i = 0; i < 2; i++)__NOP(); + +#ifdef PRINT_CSV_FORMAT + if (len > 0) { + print_csv_time(); + for (int i=0; i<len; i++) { + PRINT_CSV(" %02x", buffer[i]); + } + PRINT_CSV("\n"); + } +#endif + + return len; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRGDevice::spiWrite(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t result = 0; + uint32_t i; + volatile uint8_t tmpreg; + + unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00}; + + disable_irq(); + + /* CS reset */ + nCS_ = 0; + + /* Exchange header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = tmpreg; + } + + if (header_slave[0] == 0x02) { + /* SPI is ready */ + if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { + + /* Buffer is big enough */ + for (i = 0; i < Nb_bytes1; i++) { + spi_.write(*(data1 + i)); + } + for (i = 0; i < Nb_bytes2; i++) { + spi_.write(*(data2 + i)); + } + } else { + /* Buffer is too small */ + result = -2; + } + } else { + /* SPI is not ready */ + result = -1; + } + + /* Release CS line */ + //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); + nCS_ = 1; + + enable_irq(); + + return result; +} + +bool BlueNRGDevice::dataPresent() +{ + return (irq_ == 1); +} + +void BlueNRGDevice::disable_irq() +{ + irq_.disable_irq(); +} + +void BlueNRGDevice::enable_irq() +{ + irq_.enable_irq(); +} + +void BlueNRGDevice::processEvents() { + btle_handler(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,68 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattClient.h" + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + uuid = uuidIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + + void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) { + lastHandle = lastHandleIn; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1477 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file BlueNRGGap.cpp + * @author STMicroelectronics + * @brief Implementation of BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGap + * @brief BlueNRG BLE_API GAP Adaptation + * @{ + */ + +#include "BlueNRGDevice.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_payload.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/* + * Utility to process GAP specific events (e.g., Advertising timeout) + */ +void BlueNRGGap::Process(void) +{ + if(AdvToFlag) { + AdvToFlag = false; + stopAdvertising(); + } + + if(ScanToFlag) { + ScanToFlag = false; + stopScan(); + } +} + +/**************************************************************************/ +/*! + @brief Sets the advertising parameters and payload for the device. + Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API + + @params[in] advData + The primary advertising data payload + @params[in] scanResponse + The optional Scan Response payload if the advertising + type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED + in \ref GapAdveritinngParams + + @returns \ref ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @retval BLE_ERROR_BUFFER_OVERFLOW + The proposed action would cause a buffer overflow. All + advertising payloads must be <= 31 bytes, for example. + + @retval BLE_ERROR_NOT_IMPLEMENTED + A feature was requested that is not yet supported in the + nRF51 firmware or hardware. + + @retval BLE_ERROR_PARAM_OUT_OF_RANGE + One of the proposed values is outside the valid range. + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) +{ + PRINTF("BlueNRGGap::setAdvertisingData\n\r"); + /* Make sure we don't exceed the advertising payload length */ + if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + PRINTF("Exceeded the advertising payload length\n\r"); + return BLE_ERROR_BUFFER_OVERFLOW; + } + + /* Make sure we have a payload! */ + if (advData.getPayloadLen() != 0) { + PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); + + /* Align the GAP Service Appearance Char value coherently + This setting is duplicate (see below GapAdvertisingData::APPEARANCE) + since BLE API has an overloaded function for appearance + */ + STORE_LE_16(deviceAppearance, advData.getAppearance()); + setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0])); + + + for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { + loadPtr.getUnitAtIndex(index); + + PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); + PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); + + switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { + /**< TX Power Level (in dBm) */ + case GapAdvertisingData::TX_POWER_LEVEL: + { + PRINTF("Advertising type: TX_POWER_LEVEL\n\r"); + int8_t enHighPower = 0; + int8_t paLevel = 0; + + int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); + tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); +#ifdef DEBUG + PRINTF("dbm=%d, ret=%d\n\r", dbm, ret); + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); +#endif + if(ret == BLE_STATUS_SUCCESS) { + aci_hal_set_tx_power_level(enHighPower, paLevel); + } + break; + } + /**< Appearance */ + case GapAdvertisingData::APPEARANCE: + { + PRINTF("Advertising type: APPEARANCE\n\r"); + + GapAdvertisingData::Appearance appearanceP; + memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2); + + PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]); + /* Align the GAP Service Appearance Char value coherently */ + setAppearance(appearanceP); + break; + } + + } // end switch + + } //end for + + } + + // update the advertising data in the shield if advertising is running + if (state.advertising == 1) { + tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS != ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload()); + if (ret) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + } + + _advData = advData; + _scanResponse = scanResponse; + + return BLE_ERROR_NONE; +} + +/* + * Utility to set ADV timeout flag + */ +void BlueNRGGap::setAdvToFlag(void) { + AdvToFlag = true; + signalEventsToProcess(); +} + +/* + * ADV timeout callback + */ +#ifdef AST_FOR_MBED_OS +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().stopAdvertising(); +} +#else +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().setAdvToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getAdvTimeout(); + t.detach(); /* disable the callback from the timeout */ +} +#endif /* AST_FOR_MBED_OS */ + +/* + * Utility to set SCAN timeout flag + */ +void BlueNRGGap::setScanToFlag(void) { + ScanToFlag = true; + signalEventsToProcess(); +} + +static void scanTimeoutCB(void) +{ + BlueNRGGap::getInstance().setScanToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getScanTimeout(); + t.detach(); /* disable the callback from the timeout */ +} + +/**************************************************************************/ +/*! + @brief Starts the BLE HW, initialising any services that were + added before this function was called. + + @param[in] params + Basic advertising details, including the advertising + delay, timeout and how the device should be advertised + + @note All services must be added before calling this function! + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ + +ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) +{ + tBleStatus ret; + int err; + + /* Make sure we support the advertising type */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { + /* ToDo: This requires a proper security implementation, etc. */ + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /* Check interval range */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { + /* Min delay is slightly longer for unconnectable devices */ + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } else { + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } + + /* Check timeout is zero for Connectable Directed */ + if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { + /* Timeout must be 0 with this type, although we'll never get here */ + /* since this isn't implemented yet anyway */ + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* Check timeout for other advertising types */ + if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && + (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* + * Advertising filter policy setting + * FIXME: the Security Manager should be implemented + */ + AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode(); + if(mode != ADV_POLICY_IGNORE_WHITELIST) { + ret = aci_gap_configure_whitelist(); + if(ret != BLE_STATUS_SUCCESS) { + PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret); + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } + + uint8_t advFilterPolicy = NO_WHITE_LIST_USE; + switch(mode) { + case ADV_POLICY_FILTER_SCAN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN; + break; + case ADV_POLICY_FILTER_CONN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN; + break; + case ADV_POLICY_FILTER_ALL_REQS: + advFilterPolicy = WHITE_LIST_FOR_ALL; + break; + default: + advFilterPolicy = NO_WHITE_LIST_USE; + break; + } + + /* Check the ADV type before setting scan response data */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED || + params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) { + + /* set scan response data */ + PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen()); + ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS!=ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + } else { + hci_le_set_scan_resp_data(0, NULL); + } + + setAdvParameters(); + PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType()); + + err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload()); + + if (err) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + + tBDAddr dummy_addr = { 0 }; + uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval; + uint16_t advIntervalMax = advIntervalMin + 1; + + err = hci_le_set_advertising_parameters( + advIntervalMin, + advIntervalMax, + params.getAdvertisingType(), + addr_type, + 0x00, + dummy_addr, + /* all channels */ 7, + advFilterPolicy + ); + + if (err) { + PRINTF("impossible to set advertising parameters\n\r"); + PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1); + PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy); + return BLE_ERROR_INVALID_PARAM; + } + + err = hci_le_set_advertise_enable(0x01); + if (err) { + PRINTF("impossible to start advertising\n\r"); + return BLE_ERROR_UNSPECIFIED; + } + + if(params.getTimeout() != 0) { + PRINTF("!!! attaching adv to!!!\n"); +#ifdef AST_FOR_MBED_OS + minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000)); +#else + advTimeout.attach(advTimeoutCB, params.getTimeout()); +#endif + } + + return BLE_ERROR_NONE; + +} + + +/**************************************************************************/ +/*! + @brief Stops the BLE HW and disconnects from any devices + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::stopAdvertising(void) +{ + if(state.advertising == 1) { + + int err = hci_le_set_advertise_enable(0); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + PRINTF("Advertisement stopped!!\n\r") ; + //Set GapState_t::advertising state + state.advertising = 0; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason) +{ + tBleStatus ret; + + ret = aci_gap_terminate(connectionHandle, reason); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_COMMAND_DISALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason) +{ + return disconnect(m_connectionHandle, reason); +} + +/**************************************************************************/ +/*! + @brief Sets the 16-bit connection handle + + @param[in] conn_handle + Connection Handle which is set in the Gap Instance + + @returns void +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionHandle(uint16_t conn_handle) +{ + m_connectionHandle = conn_handle; +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit connection handle + + @param[in] void + + @returns uint16_t + Connection Handle of the Gap Instance +*/ +/**************************************************************************/ +uint16_t BlueNRGGap::getConnectionHandle(void) +{ + return m_connectionHandle; +} + +/**************************************************************************/ +/*! + @brief Sets the BLE device address. SetAddress will reset the BLE + device and re-initialize BTLE. Will not start advertising. + + @param[in] type + Type of Address + + @param[in] address[6] + Value of the Address to be set + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address) +{ + if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if(type == BLEProtocol::AddressType::PUBLIC){ + tBleStatus ret = aci_hal_write_config_data( + CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + address + ); + if(ret != BLE_STATUS_SUCCESS) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } else if (type == BLEProtocol::AddressType::RANDOM_STATIC) { + // ensure that the random static address is well formed + if ((address[5] & 0xC0) != 0xC0) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // thanks to const correctness of the API ... + tBDAddr random_address = { 0 }; + memcpy(random_address, address, sizeof(random_address)); + int err = hci_le_set_random_address(random_address); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // It is not possible to get the bluetooth address when it is set + // store it locally in class data member + memcpy(bdaddr, address, sizeof(bdaddr)); + } else { + // FIXME random addresses are not supported yet + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + // if we're here then the address was correctly set + // commit it inside the addr_type + addr_type = type; + isSetAddress = true; + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Returns boolean if the address of the device has been set + or not + + @returns bool + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +bool BlueNRGGap::getIsSetAddress() +{ + return isSetAddress; +} + +/**************************************************************************/ +/*! + @brief Returns the address of the device if set + + @returns Pointer to the address if Address is set else NULL + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) +{ + uint8_t bdaddr[BDADDR_SIZE]; + uint8_t data_len_out; + + // precondition, check that pointers in input are valid + if (typeP == NULL || address == NULL) { + return BLE_ERROR_INVALID_PARAM; + } + + if (addr_type == BLEProtocol::AddressType::PUBLIC) { + tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr); + if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) { + return BLE_ERROR_UNSPECIFIED; + } + } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) { + // FIXME hci_read_bd_addr and + // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1 + // does not work, use the address stored in class data member + memcpy(bdaddr, this->bdaddr, sizeof(bdaddr)); + } else { + // FIXME: should be implemented with privacy features + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + *typeP = addr_type; + memcpy(address, bdaddr, BDADDR_SIZE); + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief obtains preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + + if (!g_preferred_connection_parameters_char_handle) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // Peripheral preferred connection parameters are an array of 4 uint16_t + uint8_t parameters_packed[parameter_size * 4]; + uint16_t bytes_read = 0; + + tBleStatus err = aci_gatt_read_handle_value( + g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE, + sizeof(parameters_packed), + &bytes_read, + parameters_packed + ); + + PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read); + + // check that the read succeed and the result have the expected length + if (err || bytes_read != sizeof(parameters_packed)) { + return BLE_ERROR_UNSPECIFIED; + } + + // memcpy field by field + memcpy(¶ms->minConnectionInterval, parameters_packed, parameter_size); + memcpy(¶ms->maxConnectionInterval, ¶meters_packed[parameter_size], parameter_size); + memcpy(¶ms->slaveLatency, ¶meters_packed[2 * parameter_size], parameter_size); + memcpy(¶ms->connectionSupervisionTimeout, ¶meters_packed[3 * parameter_size], parameter_size); + + return BLE_ERROR_NONE; +} + + +/**************************************************************************/ +/*! + @brief sets preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + uint8_t parameters_packed[parameter_size * 4]; + + // ensure that parameters are correct + // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC + if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) && + params->minConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) && + params->maxConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (params->slaveLatency > 0x01F3) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) && + params->connectionSupervisionTimeout != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // copy the parameters inside the byte array + memcpy(parameters_packed, ¶ms->minConnectionInterval, parameter_size); + memcpy(¶meters_packed[parameter_size], ¶ms->maxConnectionInterval, parameter_size); + memcpy(¶meters_packed[2 * parameter_size], ¶ms->slaveLatency, parameter_size); + memcpy(¶meters_packed[3 * parameter_size], ¶ms->connectionSupervisionTimeout, parameter_size); + + tBleStatus err = aci_gatt_update_char_value( + g_gap_service_handle, + g_preferred_connection_parameters_char_handle, + /* offset */ 0, + sizeof(parameters_packed), + parameters_packed + ); + + if (err) { + PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ; + switch (err) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief updates preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) +{ + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(gapRole == Gap::CENTRAL) { + ret = aci_gap_start_connection_update(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout, + CONN_L1, CONN_L2); + } else { + ret = aci_l2cap_connection_parameter_update_request(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout); + } + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case ERR_COMMAND_DISALLOWED: + case BLE_STATUS_NOT_ALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sets the Device Name Characteristic + + @param[in] deviceName + pointer to device name to be set + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) +{ + tBleStatus ret; + uint8_t nameLen = 0; + + nameLen = strlen((const char*)deviceName); + PRINTF("DeviceName Size=%d\n\r", nameLen); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_device_name_char_handle, + 0, + nameLen, + deviceName); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Gets the Device Name Characteristic + + @param[in] deviceName + pointer to device name + + @param[in] lengthP + pointer to device name length + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) +{ + tBleStatus ret; + + ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + *lengthP, + (uint16_t *)lengthP, + deviceName); + PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } +} + +/**************************************************************************/ +/*! + @brief Sets the Device Appearance Characteristic + + @param[in] appearance + device appearance + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance) +{ + tBleStatus ret; + uint8_t deviceAppearance[2]; + + STORE_LE_16(deviceAppearance, appearance); + PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_appearance_char_handle, + 0, 2, (uint8_t *)deviceAppearance); + if (BLE_STATUS_SUCCESS == ret){ + return BLE_ERROR_NONE; + } + + PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Gets the Device Appearance Characteristic + + @param[in] appearance + pointer to device appearance value + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) +{ + tBleStatus ret; + uint16_t lengthP = 2; + + ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + lengthP, + &lengthP, + (uint8_t*)appearanceP); + PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + +} + +GapScanningParams* BlueNRGGap::getScanningParams(void) +{ + return &_scanningParams; +} + +static void makeConnection(void) +{ + BlueNRGGap::getInstance().createConnection(); +} + +void BlueNRGGap::Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI) +{ + switch (reason) { + case DEVICE_FOUND: + { + GapAdvertisingParams::AdvertisingType_t type; + bool isScanResponse = false; + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * Private Random Address + * => scan_results = FALSE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type); + if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV || + (addr_type == RESOLVABLE_PRIVATE_ADDR || + addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) { + return; + } + + switch(adv_type) { + case ADV_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + break; + case ADV_DIRECT_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED; + break; + case ADV_SCAN_IND: + case SCAN_RSP: + type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED; + isScanResponse = true; + break; + case ADV_NONCONN_IND: + type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED; + break; + default: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + } + + PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n", + *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + if(!_connecting) { + processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data); + } + PRINTF("!!!After processAdvertisementReport\n\r"); + } + break; + + case DISCOVERY_COMPLETE: + // The discovery is complete. If this is due to a stop scanning (i.e., the device + // we are interested in has been found) and a connection has been requested + // then we start the device connection. + PRINTF("DISCOVERY_COMPLETE\n\r"); + _scanning = false; + + // Since the DISCOVERY_COMPLETE event can be received during the scanning interval, + // we need to delay the starting of connection + uint16_t delay = (_scanningParams.getInterval()*0.625); + +#ifdef AST_FOR_MBED_OS + if(_connecting) { + minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay)); + } +#else + Clock_Wait(delay); + if(_connecting) { + makeConnection(); + } +#endif /* AST_FOR_MBED_OS */ + + break; + } +} + +ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) +{ + + tBleStatus ret = BLE_STATUS_SUCCESS; + + // Stop ADV before scanning + /* + if (state.advertising == 1) { + stopAdvertising(); + } + */ + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * White List is empty + * => scan operation = FAILURE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + uint8_t whiteListSize = whitelistAddresses.size; + if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + ret = btleStartRadioScan(scanningParams.getActiveScanning(), + scanningParams.getInterval(), + scanningParams.getWindow(), + addr_type); + + PRINTF("Scanning...\n\r"); + PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000); + PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000); + //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval()); + //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1); + //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2); + if (BLE_STATUS_SUCCESS == ret){ + PRINTF("Observation Procedure Started\n"); + _scanning = true; + + if(scanningParams.getTimeout() != 0) { + PRINTF("!!! attaching scan to!!!\n"); + scanTimeout.attach(scanTimeoutCB, scanningParams.getTimeout()); + } + + return BLE_ERROR_NONE; + } + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + switch (ret) { + case BLE_STATUS_INVALID_CID: + PRINTF("Observation Procedure not implemented!!!\n\r"); + return BLE_ERROR_NOT_IMPLEMENTED; + default: + PRINTF("Observation Procedure failed (0x%02X)\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } + +} + +ble_error_t BlueNRGGap::stopScan() { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(_scanning) { + ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC); + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Discovery Procedure Terminated\n"); + return BLE_ERROR_NONE; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief set Tx power level + @param[in] txPower Transmission Power level + @returns ble_error_t +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setTxPower(int8_t txPower) +{ + tBleStatus ret; + + int8_t enHighPower = 0; + int8_t paLevel = 0; + + ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + ret = aci_hal_set_tx_power_level(enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief get permitted Tx power values + @param[in] values pointer to pointer to permitted power values + @param[in] num number of values +*/ +/**************************************************************************/ +void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { + static const int8_t permittedTxValues[] = { + -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8 + }; + + *valueArrayPP = permittedTxValues; + *countP = sizeof(permittedTxValues) / sizeof(int8_t); +} + +/**************************************************************************/ +/*! + @brief Set advertising parameters according to the current state + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setAdvParameters(void) +{ + uint32_t advIntMS; + + if(state.connected == 1) { + advIntMS = (conn_min_interval*1.25)-GUARD_INT; + advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS); + + PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval); + } else { + advInterval = _advParams.getIntervalInADVUnits(); + } +} + +/**************************************************************************/ +/*! + @brief Set connection parameters according to the current state (ADV and/or SCAN) + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionParameters(void) +{ + if (state.connected == 1) { + + PRINTF("state.connected=1\r\n"); + scanInterval = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(conn_min_interval*1.25); + scanWindow = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(((conn_min_interval*1.25)/100)*60); // scanWin ~= 60%(scanInt) + + } else if (state.advertising == 1) { + + if (_scanningParams.getInterval() < advInterval) { + PRINTF("state.adv=1 scanInterval<advInterval\r\n"); + scanInterval = advInterval; + scanWindow = advInterval; + } else { + PRINTF("state.adv=1 scanInterval>=advInterval\r\n"); + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + } + + if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms + conn_min_interval = MAX_INT_CONN; + conn_max_interval = MAX_INT_CONN; + } else { + conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + } + + } else { + + PRINTF("state.adv = 0\r\n"); + + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) || + SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms + conn_min_interval = DEF_INT_CONN; + conn_max_interval = DEF_INT_CONN; + } else { + conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + } + } + PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval)); + PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow)); + PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25)); + PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25)); + +} + +ble_error_t BlueNRGGap::createConnection () +{ + tBleStatus ret; + + /* + Before creating connection, set parameters according + to previous or current procedure (ADV and/or SCAN) + */ + setConnectionParameters(); + + /* + Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, + Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max + */ + ret = aci_gap_create_connection(scanInterval, + scanWindow, + _peerAddrType, + (unsigned char*)_peerAddr, + addr_type, + conn_min_interval, conn_max_interval, 0, + SUPERV_TIMEOUT, CONN_L1, CONN_L1); + + //_connecting = false; + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Connection started.\n"); + _connecting = false; + return BLE_ERROR_NONE; + } +} + +ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) +{ + /* avoid compiler warnings about unused variables */ + (void)connectionParams; + + setScanParams(scanParams->getInterval(), + scanParams->getWindow(), + scanParams->getTimeout(), + scanParams->getActiveScanning() + ); + + // Save the peer address + for(int i=0; i<BDADDR_SIZE; i++) { + _peerAddr[i] = peerAddr[i]; + } + _peerAddrType = peerAddrType; + + _connecting = true; + + if(_scanning) { + stopScan(); + } else { + PRINTF("Calling createConnection from connect()\n\r"); + return createConnection(); + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the advertising policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode) +{ + advertisingPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the scanning policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode) +{ + scanningPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Get the current advertising policy filter mode. + + @returns The advertising policy filter mode. +*/ +/**************************************************************************/ +Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const +{ + return advertisingPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Get the current scanning policy filter mode. + + @returns The scanning policy filter mode. + +*/ +/**************************************************************************/ +Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const +{ + return scanningPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGap's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::reset(void) +{ + PRINTF("BlueNRGGap::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (Gap::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + AdvToFlag = false; + ScanToFlag = false; + + /* Clear derived class members */ + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + return BLE_ERROR_NONE; +} + +void BlueNRGGap::setConnectionInterval(uint16_t interval) { + conn_min_interval = interval; + conn_max_interval = interval; +} + +Gap::Role_t BlueNRGGap::getGapRole(void) +{ + return (gapRole); +} + +void BlueNRGGap::setGapRole(Gap::Role_t role) +{ + gapRole = role; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,403 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTClient + * @brief BlueNRG BLE_API GattClient Adaptation + * @{ + */ + +#include "BlueNRGGattClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +#include <new> +#include <assert.h> + +ble_error_t BlueNRGGattClient::createGattConnectionClient(Gap::Handle_t connectionHandle) +{ + if(MAX_ACTIVE_CONNECTIONS <= _numConnections) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + for(uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + + if(_connectionPool[i] == NULL) { + BlueNRGGattConnectionClient *gattConnectionClient = new(std::nothrow) BlueNRGGattConnectionClient(this, connectionHandle); + + if (gattConnectionClient == NULL) { + return BLE_ERROR_NO_MEM; + } + + _connectionPool[i] = gattConnectionClient; + _connectionPool[i]->onServiceDiscoveryTermination(terminationCallback); + _numConnections++; + + PRINTF("createGattConnectionClient: _connectionPool index=%d\r\n", i); + PRINTF("createGattConnectionClient: succesfully added new gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + break; + } + } + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattClient::removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason) +{ + + PRINTF("removeGattConnectionClient: connectionHandle=%d reason=0x%x\r\n", connectionHandle, reason); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("removeGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("removeGattConnectionClient: Found gattConnectionClient\r\n"); + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + PRINTF("removeGattConnectionClient: succesfully removed gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + + break; + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + + return BLE_ERROR_NONE; +} + +BlueNRGGattConnectionClient * BlueNRGGattClient::getGattConnectionClient(Gap::Handle_t connectionHandle) { + PRINTF("getGattConnectionClient\r\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("getGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("getGattConnectionClient: Found gattConnectionClient\r\n"); + return _connectionPool[i]; + } + } + + return NULL; +} + +void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code) { + + if(error_code != BLE_STATUS_SUCCESS) { + return; + } + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->gattProcedureCompleteCB(error_code); +} + +void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServicesCB(event_data_length, + attribute_data_length, + attribute_data_list); +} + +void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServiceCB(event_data_length, + handles_info_list); +} + +ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->findServiceChars(); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharsCB(event_data_length, + handle_value_pair_length, + handle_value_pair); +} + +void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharByUUIDCB(event_data_length, + attr_handle, + attr_value); +} + +void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->discAllCharacDescCB(event_data_length, + format, + handle_uuid_pair); +} + +void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charReadCB(event_data_length, + attribute_value); +} + +void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWritePrepareCB(event_data_length, + attribute_handle, + offset, + part_attr_value); +} + +void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWriteExecCB(event_data_length); +} + +ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattClient launchServiceDiscovery\n\r"); + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->launchServiceDiscovery(sc, cc, matchingServiceUUID, matchingCharacteristicUUIDIn); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, matchingServiceUUID); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, startHandle, endHandle); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +bool BlueNRGGattClient::isServiceDiscoveryActive(void) const +{ + bool isSDActive = false; + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + isSDActive |= _connectionPool[i]->isServiceDiscoveryActive(); + } + } + + return isSDActive; +} + +void BlueNRGGattClient::terminateServiceDiscovery(void) +{ + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + _connectionPool[i]->terminateServiceDiscovery(); + } + } +} + +void BlueNRGGattClient::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; ++i) { + if (_connectionPool[i]) { + _connectionPool[i]->onServiceDiscoveryTermination(callback); + } + } +} + +ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->read(attributeHandle, offset); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->write(cmd, attributeHandle, length, value); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(characteristic.getConnectionHandle()); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverCharacteristicDescriptors(characteristic, discoveryCallback, terminationCallback); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattClient's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattClient::reset(void) +{ + PRINTF("BlueNRGGattClient::reset\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if(_connectionPool[i] != NULL) { + _connectionPool[i]->reset(); + + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + } + } + + return BLE_ERROR_NONE; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,816 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGattConnectionClient + * @brief BlueNRG GattConnectionClient Adaptation + * @{ + */ + +#include "BlueNRGGattConnectionClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" +#include "ble_debug.h" + +// #define PRINTF printf + +static uint8_t props_mask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 + }; + +void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code) +{ + if(error_code != BLE_STATUS_SUCCESS) { + _currentState = GATT_IDLE; + return; + } + + // Service Discovery complete +/* + if(_currentState != GATT_IDLE && + _currentState != GATT_DISCOVERY_TERMINATED && + _currentState != GATT_WRITE_CHAR && + _currentState != GATT_READ_CHAR) { +*/ + if(_currentState == GATT_SERVICE_DISCOVERY) { + findServiceChars(); + return; + } + + if(_currentState == GATT_CHAR_DESC_DISCOVERY) { + _currentState = GATT_IDLE; + if(charDescTerminationCallback != NULL) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { + _characteristic, + BLE_ERROR_NONE + }; + charDescTerminationCallback(¶ms); + } + return; + } + + // Read complete + if(_currentState == GATT_READ_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processReadResponse(&readCBParams); + free((void*)(readCBParams.data)); + readCBParams.data = NULL; + return; + } + + // Write complete + if(_currentState == GATT_WRITE_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); + return; + } +} + +void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numAttr; + + numAttr = (event_data_length - 1) / attribute_data_length; + + offset = 0; + for (i=0; i<numAttr; i++) { + startHandle = attribute_data_list[offset]; + endHandle = attribute_data_list[offset+2]; + + // UUID Type + if (attribute_data_length == 6) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4]; + PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(attribute_data_list+offset+4, UUID::LSB); + +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + + } + + PRINTF("Setup serviceIndex = %d\n\r", _numServices); + discoveredService[_numServices].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += attribute_data_length; + } + + PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr); + +} + +void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numHandlePairs; + + numHandlePairs = (event_data_length - 1) / 2; + + offset = 0; + for (i=0; i<numHandlePairs; i++) { + startHandle = handles_info_list[offset]; + endHandle = handles_info_list[offset+2]; + + PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle); + + + if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle); + uuid = _matchingServiceUUID.getShortUUID(); + } else { +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02x", longUUIDBytes[i]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB); + } + + discoveredService[i].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += 4; + } +} + +void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) +{ + // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + uint8_t i, numChar, offset; + + numChar = (event_data_length - 1) / handle_value_pair_length; + + PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar); + + offset = 0; + for (i=0; i<numChar; i++) { + // UUID Type + if (handle_value_pair_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(handle_value_pair+offset+5, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & handle_value_pair[offset+2]); + p._read = (props_mask[1] & handle_value_pair[offset+2])>>1; + p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2; + p._write = (props_mask[3] & handle_value_pair[offset+2])>>3; + p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4; + p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5; + p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = handle_value_pair[offset+2]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = handle_value_pair[offset]; + valueHandle = handle_value_pair[offset+3]; + lastHandle = valueHandle+1; + PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle); + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; + + offset += handle_value_pair_length; + } +} + +void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) +{ + // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + + PRINTF("serviceCharByUUIDCB\n\r"); + + // UUID Type + if (event_data_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = attr_value[4]<<8|attr_value[3]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(attr_value+3, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & attr_value[0]); + p._read = (props_mask[1] & attr_value[0])>>1; + p._writeWoResp = (props_mask[2] & attr_value[0])>>2; + p._write = (props_mask[3] & attr_value[0])>>3; + p._notify = (props_mask[4] & attr_value[0])>>4; + p._indicate = (props_mask[5] & attr_value[0])>>5; + p._authSignedWrite = (props_mask[6] & attr_value[0])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = attr_value[0]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = attr_handle; + valueHandle = attr_value[1]; + lastHandle = valueHandle+1; + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + // update the last handle and call the characteristic discovery callback for previous char + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; +} + +ble_error_t BlueNRGGattConnectionClient::findServiceChars(void) +{ + PRINTF("findServiceChars\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + + DiscoveredService *service; + + // complete the discovery of the last characteristic of the previous service. + // Its last handle wasn't known before this point + // update the handle and call the characteristic discovery callback. + if (_servIndex != 0 && _numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle()); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars = 0; + + // We finished chars discovery for all services + if(_servIndex >= _numServices) { + PRINTF("!!!We finished chars discovery for all services!!!\n\r"); + //_currentState = GATT_CHARS_DISCOVERY_COMPLETE; + + terminateServiceDiscovery(); + + return BLE_ERROR_NONE; + } + + service = &discoveredService[_servIndex]; + /* + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID()); + } else { + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); + } + */ + + if(serviceDiscoveryCallback) { + serviceDiscoveryCallback(service); + } + + PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex); + //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle()); + + if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) { + PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r"); + ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle()); + } else { + + uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID()); + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; +#ifdef DEBUG + PRINTF("findServiceChars C UUID-"); + for(unsigned i = 0; i < 2; i++) { + PRINTF("%02X", short_uuid[i]); + } + PRINTF("\n\r"); +#endif + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID(); +#ifdef DEBUG + PRINTF("(findServiceChars) C UUID-"); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", uuid[i]); + } + PRINTF("\r\n"); +#endif + } + + ret = aci_gatt_disc_charac_by_uuid(_connectionHandle, + service->getStartHandle(), + service->getEndHandle(), + uuid_type, + uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _servIndex++; + } + + PRINTF("findServiceChars ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + unsigned j; + + if(isServiceDiscoveryActive()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if(!sc && !cc) { + // nothing to do + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r"); + return BLE_ERROR_NONE; + } + + serviceDiscoveryCallback = sc; + characteristicDiscoveryCallback = cc; + _matchingServiceUUID = matchingServiceUUID; + _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn; + + //reset services + _numServices = 0; + _numChars = 0; + _servIndex = 0; + for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) { + discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE); + } + + if(matchingServiceUUID == BLE_UUID_UNKNOWN) { + + // Wildcard: search for all services + PRINTF("Wildcard: search for all services\r\n"); + ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle); + + } else { + PRINTF("search for specific services\r\n"); + + uint8_t type = matchingServiceUUID.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID()); +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x"); + for(j = 0; j < 2; j++) { + PRINTF("%02X", short_uuid[j]); + } + PRINTF("\n\r"); +#endif + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; + + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)matchingServiceUUID.getBaseUUID(); + +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x"); + for(j = 0; j < 16; j++) { + PRINTF("%02X", uuid[j]); + } + PRINTF("\n\r"); +#endif + } + + // search for specific service by UUID + ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_SERVICE_DISCOVERY; + } + + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)matchingServiceUUID; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)startHandle; + (void)endHandle; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const +{ + if(_currentState == GATT_SERVICE_DISCOVERY) { + return true; + } + + return false; +} + +void BlueNRGGattConnectionClient::terminateServiceDiscovery(void) +{ + _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED; + + if (terminationCallback) { + terminationCallback(_connectionHandle); + } +} + +void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value) +{ + // copy the data read, they will be forwarded to the user once the procedure + // has completed + readCBParams.connHandle = _connectionHandle; + readCBParams.offset = 0; + readCBParams.len = event_data_length; + readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length)); + memcpy((void*)(readCBParams.data), attribute_value, event_data_length); +} + +ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + /* avoid compiler warnings about unused variables */ + (void)offset; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // Save the attribute_handle not provided by evt_att_read_resp + gattc->readCBParams.handle = attributeHandle; + + ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle); + + if(ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_READ_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } +} + +void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) +{ + // Update the write response params + writeCBParams.handle = attribute_handle; + writeCBParams.offset = offset; + writeCBParams.len = event_data_length-4; //(?) + writeCBParams.data = part_attr_value; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length) +{ + /* avoid compiler warnings about unused variables */ + (void)event_data_length; + + writeCBParams.connHandle = _connectionHandle; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + /* avoid compiler warnings about unused variables */ + (void)cmd; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // We save the write response params (used by the callback) because + // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE + gattc->writeCBParams.connHandle = _connectionHandle; + gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD; + gattc->writeCBParams.handle = attributeHandle; + gattc->writeCBParams.offset = 0; + gattc->writeCBParams.len = length; + gattc->writeCBParams.data = value; + + ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); + + if (ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_WRITE_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } + +} + +void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + GattAttribute::Handle_t attHandle; + UUID uuid; + uint8_t i, numCharacDesc, offset, handle_uuid_length; + + handle_uuid_length = 4; //Handle + UUID_16 + if (format == 2) + handle_uuid_length = 18; //Handle + UUID_128 + + numCharacDesc = (event_data_length - 1) / handle_uuid_length; + + offset = 0; + + PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n", + event_data_length, format); + + + for (i=0; i<numCharacDesc; i++) { + memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle)); + + // UUID Type + if (handle_uuid_length == 4) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2]; + PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB); +#ifdef DEBUG + PRINTF("D UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + } + + if(charDescDiscoveryCallback != NULL) { + CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { + _characteristic, + DiscoveredCharacteristicDescriptor( + _characteristic.getGattClient(), + _connectionHandle, + attHandle, + uuid + ) + }; + charDescDiscoveryCallback(¶ms); + } + + _numCharDesc++; + + offset += handle_uuid_length; + } +} + +ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { + + tBleStatus ret; + + if(_currentState != GATT_IDLE) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + charDescDiscoveryCallback = discoveryCallback; + charDescTerminationCallback = terminationCallback; + + GattAttribute::Handle_t valueHandle = characteristic.getValueHandle(); + GattAttribute::Handle_t lastHandle = characteristic.getLastHandle(); + + PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle); + ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle); + + if (ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_CHAR_DESC_DISCOVERY; + _characteristic = characteristic; + return BLE_ERROR_NONE; + } + switch (ret) { + case BLE_STATUS_INVALID_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattConnectionClient::reset(void) { + PRINTF("BlueNRGGattConnectionClient::reset\n"); + + /* Clear all state, including private members */ + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + _numServices = 0; + _servIndex = 0; + _numChars = 0; + _numCharDesc = 0; + + /* Clear class members */ + memset(discoveredService, 0, sizeof(discoveredService)); + memset(discoveredChar, 0, sizeof(discoveredChar)); + + // free response if allocated + if(readCBParams.data) { + free((void*)(readCBParams.data)); + } + + return BLE_ERROR_NONE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,755 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTSERVER + * @brief BlueNRG BLE_API GattServer Adaptation + * @{ + */ + +#include "BlueNRGGattServer.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/**************************************************************************/ +/*! + @brief Adds a new service to the GATT table on the peripheral + + @params[in] service + Pointer to instance of the Gatt Server to add + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::addService(GattService &service) +{ + /* ToDo: Make sure we don't overflow the array, etc. */ + /* ToDo: Make sure this service UUID doesn't already exist (?) */ + /* ToDo: Basic validation */ + + tBleStatus ret; + uint8_t type; + uint16_t short_uuid; + uint8_t primary_short_uuid[2]; + uint8_t primary_base_uuid[16]; + uint8_t char_base_uuid[16]; + const uint8_t *base_uuid; + const uint8_t *base_char_uuid; + + uint8_t charsCount = service.getCharacteristicCount(); + const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount; + + // check that there is enough characteristics left in the + // characteristic array. + if (charsCount > available_characteristics) { + PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics); + return BLE_ERROR_NO_MEM; + } + + const uint16_t maxAttrRecords = computeAttributesRecord(service); + + type = (service.getUUID()).shortOrLong(); + PRINTF("AddService(): Type:%d\n\r", type); + + /* Add the service to the BlueNRG */ + short_uuid = (service.getUUID()).getShortUUID(); + STORE_LE_16(primary_short_uuid, short_uuid); + + if(type==UUID::UUID_TYPE_LONG) { + base_uuid = (service.getUUID()).getBaseUUID(); + + COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]); + } + + ret = BLE_STATUS_SUCCESS; + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_serv(UUID_TYPE_16, + primary_short_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_serv(UUID_TYPE_128, + primary_base_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_OUT_OF_HANDLE: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case ERR_UNSPECIFIED_ERROR: + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_ERROR: + default: + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + + + service.setHandle(servHandle); + //serviceHandleVector.push_back(servHandle); + PRINTF("added servHandle handle =%u\n\r", servHandle); + uint16_t bleCharacteristic; + + //iterate to include all characteristics + for (uint8_t i = 0; i < charsCount; i++) { + GattCharacteristic *p_char = service.getCharacteristic(i); + uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); + + uint8_t int_8_uuid[2]; + STORE_LE_16(int_8_uuid, char_uuid); + + type = (p_char->getValueAttribute().getUUID()).shortOrLong(); + + if(type==UUID::UUID_TYPE_LONG) { + base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); +#ifdef DEBUG + for(uint8_t j=0; j<16; j++) { + PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]); + } + PRINTF("\n\r"); +#endif + COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]); + } + + PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); + /* + * Gatt_Evt_Mask -> HardCoded (0) + * Encryption_Key_Size -> Hardcoded (16) + * isVariable (variable length value field) -> Hardcoded (1) + */ + uint8_t Gatt_Evt_Mask = 0x0; + + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP; + } + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; + } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_16, + int_8_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_128, + char_base_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + case BLE_STATUS_CHARAC_ALREADY_EXISTS: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); + + p_characteristics[characteristicCount++] = p_char; + /* Set the characteristic value handle */ + p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE); + PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle()); + + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + ble_error_t err = write(p_char->getValueAttribute().getHandle(), + p_char->getValueAttribute().getValuePtr(), + p_char->getValueAttribute().getLength(), false /* localOnly */); + if (err) { + PRINTF("ERROR HERE !!!!\r\n"); + return err; + } + } + + // add descriptors now + uint16_t descHandle = 0; + PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); + + for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { + GattAttribute *descriptor = p_char->getDescriptor(descIndex); + uint8_t desc_uuid[16] = { 0 }; + + + uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT; + STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID()); + + if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) { + desc_uuid_type = CHAR_DESC_TYPE_128_BIT; + const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID(); + + COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]); + } + + ret = aci_gatt_add_char_desc(service.getHandle(), + bleCharacteristic, + desc_uuid_type, + desc_uuid, + descriptor->getMaxLength(), + descriptor->getLength(), + descriptor->getValuePtr(), + CHAR_DESC_SECURITY_PERMISSION, + CHAR_DESC_ACCESS_PERMISSION, + GATT_NOTIFY_ATTRIBUTE_WRITE, + MIN_ENCRY_KEY_SIZE, + CHAR_ATTRIBUTE_LEN_IS_FIXED, + &descHandle); + PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); + + switch (ret) { + case BLE_STATUS_SUCCESS: + PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); + descriptor->setHandle(descHandle); + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_INVALID_OPERATION: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + } + + serviceCount++; + + //FIXME: There is no GattService pointer array in GattServer. + // There should be one? (Only the user is aware of GattServices!) Report to forum. + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on char handle + + @param[in] attributeHandle + The handle of the GattCharacteristic to read from + @param[in] buffer + Buffer to hold the the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes read into the buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) +{ + tBleStatus ret; + uint16_t charHandle = attributeHandle; + + ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer); + + if(ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on the connection + and char handle + + @param[in] connectionHandle + The handle of the connection + @param[in] attributeHandle + The handle of the GattCharacteristic to write to + @param[in] buffer + Data to use when updating the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes in buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + uint8_t buffer[], + uint16_t *lengthP) { + + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)attributeHandle; + (void)buffer; + (void)lengthP; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t, + const uint8_t[], + uint16_t, bool localOnly) { + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)localOnly; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly) +{ + /* avoid compiler warnings about unused variables */ + (void)localOnly; + + // check that the len of the data to write are compatible with the characteristic + GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle); + if (!characteristic) { + PRINTF("characteristic not found\r\n"); + return BLE_ERROR_INVALID_PARAM; + } + + // if the attribute handle is the attribute handle of the characteristic value then + // write the value + if (attributeHandle == characteristic->getValueHandle()) { + // assert the len in input is correct for this characteristic + const GattAttribute& value_attribute = characteristic->getValueAttribute(); + + // reject write if the lenght exceed the maximum lenght of this attribute + if (value_attribute.getMaxLength() < len) { + PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + // reject write if the attribute size is fixed and the lenght in input is different than the + // length of the attribute. + if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) { + PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + tBleStatus ret; + + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + + PRINTF("updating bleCharacteristic valueHandle=%u,\ + corresponding serviceHandle=%u len=%d\n\r", + attributeHandle, bleCharHandleMap.find(charHandle)->second, len); + + /* + * If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. + */ + ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } else { + // write this handle has a descriptor handle + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + uint16_t service_handle = bleCharHandleMap.find(charHandle)->second; + + tBleStatus ret = aci_gatt_set_desc_value( + service_handle, + charHandle, + attributeHandle, + 0, + len, + buffer + ); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } +} + +/**************************************************************************/ +/*! + @brief Reads a value according to the handle provided + + @param[in] attributeHandle + The handle of the attribute to read from + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle) +{ + uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); + + GattReadCallbackParams readParams; + readParams.handle = attributeHandle; + + //PRINTF("readParams.handle = %d\n\r", readParams.handle); + HCIDataReadEvent(&readParams); + + //EXIT: + if(gapConnectionHandle != 0){ + //PRINTF("Calling aci_gatt_allow_read\n\r"); + aci_gatt_allow_read(gapConnectionHandle); + } + + return BLE_ERROR_NONE; +} + +// ask if the write request should be accepted of rejected +// return 0 in case of success or an ATT error response in +// case of faillure +uint8_t BlueNRGGattServer::Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length, + const uint8_t* data) { + + GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle); + if(!characteristic) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF; + } + + // check if the data length is in range + if (characteristic->getValueAttribute().getMaxLength() < data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + // if the length of the characteristic value is fixed + // then the data in input should be of that length + if (characteristic->getValueAttribute().hasVariableLength() == false && + characteristic->getValueAttribute().getMaxLength() != data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + GattWriteAuthCallbackParams params = { + connection_handle, + attr_handle, + /* offset */ 0, + data_length, + data, + /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED + }; + + return characteristic->authorizeWrite(¶ms) & 0xFF; +} + +/**************************************************************************/ +/*! + @brief Returns the GattCharacteristic according to the handle provided + + @param[in] attrHandle + The handle of the attribute + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) +{ + GattCharacteristic *p_char = NULL; + int i; + uint16_t handle, handle_1; + + PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle); + for(i=0; i<characteristicCount; i++) + { + handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + PRINTF("handle(%d)=%d\n\r", i, handle); + if(i==characteristicCount-1)//Last Characteristic check + { + if(attrHandle>=handle) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); + break; + } + } + else { + handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + //Testing if attribute handle is between two Characteristic Handles + if(attrHandle>=handle && attrHandle<handle_1) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); + break; + } else continue; + } + } + + return p_char; +} + +void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { + this->handleDataWrittenEvent(params); +} + +void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { + PRINTF("Called HCIDataReadEvent\n\r"); + this->handleDataReadEvent(params); +} + +void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { + this->handleEvent(type, charHandle); +} + +void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { + this->handleDataSentEvent(count); +} + + +ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { + // <TODO> + return (ble_error_t)0; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::reset(void) +{ + PRINTF("BlueNRGGattServer::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (GattServer::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + /* Clear class members */ + memset(p_characteristics, 0, sizeof(p_characteristics)); + memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles)); + serviceCount = 0; + characteristicCount = 0; + + return BLE_ERROR_NONE; +} + + +/// compute the number of attributes needed by this service. +uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) { + uint16_t attribute_records = 1; + + for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) { + // add two attributes, one for the characteristic declaration + // and the other for the characteristic value. + attribute_records += 2; + + const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index); + const uint8_t properties = characteristic->getProperties(); + // if notify or indicate are present, two attributes are + // needed + if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) || + (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { + attribute_records += 2; + } + + // if broadcast is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) { + attribute_records += 2; + } + + // if extended properties flag is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) { + attribute_records += 2; + } + + attribute_records += characteristic->getDescriptorCount(); + } + + // for some reason, if there is just a service, this value should + // be equal to 5 + if (attribute_records == 1) { + attribute_records = 5; + } + + return attribute_records; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,421 @@ +/** + ****************************************************************************** + * @file ble_hci.c + * @author AMS/HESA Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "ble_gp_timer.h" +#include "ble_debug.h" + +#include "stm32_bluenrg_ble.h" + +#if BLE_CONFIG_DBG_ENABLE +#undef PRINTF +#endif + +#define HCI_LOG_ON 0 + +#define HCI_READ_PACKET_NUM_MAX (0x40) + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tListNode hciReadPktPool; +tListNode hciReadPktRxQueue; + +// betzw - DEBUG: +//#define POOL_CNT +#ifdef POOL_CNT +#include <stdio.h> +static unsigned int nr_hciReadPktPool; +static unsigned int lowest_nr_hciReadPktPool; +#endif // POOL_CNT + +/* pool of hci read packets */ +static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; + +static volatile uint8_t hci_timer_id; +static volatile uint8_t hci_timeout; + +void hci_timeout_callback(void) +{ + hci_timeout = 1; + return; +} + +void HCI_Init(void) +{ + uint8_t index; + +#ifdef POOL_CNT + nr_hciReadPktPool = 0; +#endif // POOL_CNT + + /* Initialize list heads of ready and free hci data packet queues */ + list_init_head (&hciReadPktPool); + list_init_head (&hciReadPktRxQueue); + + /* Initialize the queue of free hci data packets */ + for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) + { + list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif // POOL_CNT + } + +#ifdef POOL_CNT + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif // POOL_CNT +} + +#define HCI_PCK_TYPE_OFFSET 0 +#define EVENT_PARAMETER_TOT_LEN_OFFSET 2 + +/** + * Verify if HCI packet is correctly formatted. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * @return 0 if HCI packet is as expected + */ +int HCI_verify(const tHciDataPacket * hciReadPacket) +{ + const uint8_t *hci_pckt = hciReadPacket->dataBuff; + + if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) + return 1; /* Incorrect type. */ + + if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) + return 2; /* Wrong length (packet truncated or too long). */ + + return 0; +} + +void HCI_Process(void) +{ + tHciDataPacket * hciReadPacket = NULL; + +#ifdef POOL_CNT + printf("betzw(%s, %d): nr_hciReadPktPool = %u (lowest = %u)\r\n", __func__, __LINE__, + nr_hciReadPktPool, lowest_nr_hciReadPktPool); +#endif // POOL_CNT + + Disable_SPI_IRQ(); + uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); + /* process any pending events read */ + while(list_empty == FALSE) + { + list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + Enable_SPI_IRQ(); + HCI_Event_CB(hciReadPacket->dataBuff); + Disable_SPI_IRQ(); + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + list_empty = list_is_empty(&hciReadPktRxQueue); + } + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG. */ + HCI_HandleSPI(); + Enable_SPI_IRQ(); +} + +BOOL HCI_Queue_Empty(void) +{ + return list_is_empty(&hciReadPktRxQueue); +} + +/** + * When an interrupt is raised by BlueNRG, + * just signal that a new event (availability of SPI data to be read) + * needs to be processed. + */ +void HCI_Isr(void) +{ + signalEventsToProcess(); +} + +/** + * Now, SPI Data are handled in user space. + * In case it has to be called in ISR, take care to + * call Disable_SPI_IRQ/Enable_SPI_IRQ in a proper way. + * The calls Disable_SPI_IRQ/Enable_SPI_IRQ have not been removed + * from this code for backward compatibility. + */ +void HCI_HandleSPI(void) +{ + tHciDataPacket * hciReadPacket = NULL; + uint8_t data_len; + + Clear_SPI_EXTI_Flag(); + while(BlueNRG_DataPresent()){ + if (list_is_empty (&hciReadPktPool) == FALSE){ + + /* enqueueing a packet for read */ + list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool--; + if(nr_hciReadPktPool < lowest_nr_hciReadPktPool) + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif + + data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); + if(data_len > 0){ + hciReadPacket->data_len = data_len; + if(HCI_verify(hciReadPacket) == 0) { + list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); + } else { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else { + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else{ + // HCI Read Packet Pool is empty, wait for a free packet. + Clear_SPI_EXTI_Flag(); + return; + } + + Clear_SPI_EXTI_Flag(); + } +} + +void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){ +#if HCI_LOG_ON + PRINTF("HCI <- "); + for(int i=0; i < n_bytes1; i++) + PRINTF("%02X ", *((uint8_t*)data1 + i)); + for(int i=0; i < n_bytes2; i++) + PRINTF("%02X ", *((uint8_t*)data2 + i)); + PRINTF("\n"); +#endif + + Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); +} + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) +{ + hci_command_hdr hc; + + hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); + hc.plen= plen; + + uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; + header[0] = HCI_COMMAND_PKT; + Osal_MemCpy(header+1, &hc, sizeof(hc)); + + hci_write(header, param, sizeof(header), plen); +} + +static void move_list(tListNode * dest_list, tListNode * src_list) +{ + pListNode tmp_node; + + while(!list_is_empty(src_list)){ + list_remove_tail(src_list, &tmp_node); + list_insert_head(dest_list, tmp_node); + } +} + + /* It ensures that we have at least half of the free buffers in the pool. */ +static void free_event_list(void) +{ + tHciDataPacket * pckt; + + Disable_SPI_IRQ(); + + while(list_get_size(&hciReadPktPool) < HCI_READ_PACKET_NUM_MAX/2){ + list_remove_head(&hciReadPktRxQueue, (tListNode **)&pckt); + list_insert_tail(&hciReadPktPool, (tListNode *)pckt); + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG */ + HCI_HandleSPI(); + } + + Enable_SPI_IRQ(); +} + +int hci_send_req(struct hci_request *r, BOOL async) +{ + uint8_t *ptr; + uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + hci_event_pckt *event_pckt; + hci_uart_pckt *hci_hdr; + int to = DEFAULT_TIMEOUT; + struct timer t; + tHciDataPacket * hciReadPacket = NULL; + tListNode hciTempQueue; + + list_init_head(&hciTempQueue); + + free_event_list(); + + hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); + + if(async){ + return 0; + } + + /* Minimum timeout is 1. */ + if(to == 0) + to = 1; + + Timer_Set(&t, to); + + while(1) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + evt_le_meta_event *me; + int len; + + while(1){ + + Disable_SPI_IRQ(); + HCI_HandleSPI(); + Enable_SPI_IRQ(); + + if(Timer_Expired(&t)){ + goto failed; + } + if(!HCI_Queue_Empty()){ + break; + } + } + + /* Extract packet from HCI event queue. */ + Disable_SPI_IRQ(); + list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + + hci_hdr = (void *)hciReadPacket->dataBuff; + + if(hci_hdr->type == HCI_EVENT_PKT){ + + event_pckt = (void *) (hci_hdr->data); + + ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); + len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); + + switch (event_pckt->evt) { + + case EVT_CMD_STATUS: + cs = (void *) ptr; + + if (cs->opcode != opcode) + goto failed; + + if (r->event != EVT_CMD_STATUS) { + if (cs->status) { + goto failed; + } + break; + } + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_CMD_COMPLETE: + cc = (void *) ptr; + + if (cc->opcode != opcode) + goto failed; + + ptr += EVT_CMD_COMPLETE_SIZE; + len -= EVT_CMD_COMPLETE_SIZE; + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_LE_META_EVENT: + me = (void *) ptr; + + if (me->subevent != r->event) + break; + + len -= 1; + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, me->data, r->rlen); + goto done; + + case EVT_HARDWARE_ERROR: + goto failed; + + default: + break; + } + } + + /* If there are no more packets to be processed, be sure there is at list one + packet in the pool to process the expected event. + If no free packets are available, discard the processed event and insert it + into the pool. */ + if(list_is_empty(&hciReadPktPool) && list_is_empty(&hciReadPktRxQueue)){ + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); + hciReadPacket=NULL; + } + else { + /* Insert the packet in a different queue. These packets will be + inserted back in the main queue just before exiting from send_req(), so that + these events can be processed by the application. + */ + list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); + hciReadPacket = NULL; + } + + HCI_HandleSPI(); + + Enable_SPI_IRQ(); + + } + +failed: + if(hciReadPacket != NULL) { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + move_list(&hciReadPktRxQueue, &hciTempQueue); + Enable_SPI_IRQ(); + return -1; + +done: + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + move_list(&hciReadPktRxQueue, &hciTempQueue); + + Enable_SPI_IRQ(); + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,837 @@ +/** + ****************************************************************************** + * @file ble_hci_le.c + * @author AMG RF Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +int hci_reset(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_RESET; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_disconnect(uint16_t handle, uint8_t reason) +{ + struct hci_request rq; + disconnect_cp cp; + uint8_t status; + + cp.handle = handle; + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) +{ + struct hci_request rq; + read_local_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + + *hci_version = resp.hci_version; + *hci_revision = btohs(resp.hci_revision); + *lmp_pal_version = resp.lmp_pal_version; + *manufacturer_name = btohs(resp.manufacturer_name); + *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); + + return 0; +} + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) +{ + struct hci_request rq; + le_read_buffer_size_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_BUFFER_SIZE; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *pkt_len = resp.pkt_len; + *max_pkt = resp.max_pkt; + + return 0; +} + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter) +{ + struct hci_request rq; + le_set_adv_parameters_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.min_interval = min_interval; + adv_cp.max_interval = max_interval; + adv_cp.advtype = advtype; + adv_cp.own_bdaddr_type = own_bdaddr_type; + adv_cp.direct_bdaddr_type = direct_bdaddr_type; + if(direct_bdaddr != NULL) + Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); + adv_cp.chan_map = chan_map; + adv_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_PARAMETERS; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_adv_data_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.length = length; + Osal_MemCpy(adv_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_DATA; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertise_enable(uint8_t enable) +{ + struct hci_request rq; + le_set_advertise_enable_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.enable = enable?1:0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter) +{ + struct hci_request rq; + le_set_scan_parameters_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.type = type; + scan_cp.interval = interval; + scan_cp.window = window; + scan_cp.own_bdaddr_type = own_bdaddr_type; + scan_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) +{ + struct hci_request rq; + le_set_scan_enable_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.enable = enable?1:0; + scan_cp.filter_dup = filter_dup; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_ENABLE; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_rand(uint8_t random_number[8]) +{ + struct hci_request rq; + le_rand_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_RAND; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + Osal_MemCpy(random_number, resp.random, 8); + + return 0; +} + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_scan_response_data_cp scan_resp_cp; + uint8_t status; + + Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); + scan_resp_cp.length = length; + Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; + rq.cparam = &scan_resp_cp; + rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) +{ + struct hci_request rq; + le_read_adv_channel_tx_power_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *tx_power_level = resp.level; + + return 0; +} + +int hci_le_set_random_address(tBDAddr bdaddr) +{ + struct hci_request rq; + le_set_random_address_cp set_rand_addr_cp; + uint8_t status; + + Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); + Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; + rq.cparam = &set_rand_addr_cp; + rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_read_bd_addr(tBDAddr bdaddr) +{ + struct hci_request rq; + read_bd_addr_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_BD_ADDR; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_BD_ADDR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); + + return 0; +} + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) +{ + struct hci_request rq; + le_create_connection_cp create_cp; + uint8_t status; + + Osal_MemSet(&create_cp, 0, sizeof(create_cp)); + create_cp.interval = interval; + create_cp.window = window; + create_cp.initiator_filter = initiator_filter; + create_cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); + create_cp.own_bdaddr_type = own_bdaddr_type; + create_cp.min_interval=min_interval; + create_cp.max_interval=max_interval; + create_cp.latency = latency; + create_cp.supervision_timeout=supervision_timeout; + create_cp.min_ce_length=min_ce_length; + create_cp.max_ce_length=max_ce_length; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN; + rq.cparam = &create_cp; + rq.clen = LE_CREATE_CONN_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_create_connection_cancel(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN_CANCEL; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) +{ + struct hci_request rq; + le_encrypt_cp params; + le_encrypt_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemCpy(params.key, key, 16); + Osal_MemCpy(params.plaintext, plaintextData, 16); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ENCRYPT; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + le_ltk_neg_reply_cp params; + le_ltk_neg_reply_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + params.handle = 1; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_LTK_NEG_REPLY; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CLEAR_WHITE_LIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0){ + return BLE_STATUS_TIMEOUT; + } + + return status; +} + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) +{ + struct hci_request rq; + le_add_device_to_white_list_cp params; + uint8_t status; + + params.bdaddr_type = bdaddr_type; + Osal_MemCpy(params.bdaddr, bdaddr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; + rq.cparam = ¶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/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1309 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB05A1 cp; + gap_init_rp resp; + + cp.role = role; + cp.privacy_enabled = privacy_enabled; + cp.device_name_char_len = device_name_char_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} +tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB04A1 cp; + gap_init_rp resp; + + cp.role = role; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + SlaveConnIntervMin = htobs(SlaveConnIntervMin); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + SlaveConnIntervMax = htobs(SlaveConnIntervMax); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB05A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.directed_adv_type = directed_adv_type; + cp.adv_interv_min = adv_interv_min; + cp.adv_interv_max = adv_interv_max; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB04A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_io_capability(uint8_t io_capability) +{ + struct hci_request rq; + uint8_t status; + gap_set_io_capability_cp cp; + + cp.io_capability = io_capability; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_IO_CAPABILITY; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode) +{ + struct hci_request rq; + gap_set_auth_requirement_cp cp; + uint8_t status; + + cp.mitm_mode = mitm_mode; + cp.oob_enable = oob_enable; + Osal_MemCpy(cp.oob_data, oob_data, 16); + cp.min_encryption_key_size = min_encryption_key_size; + cp.max_encryption_key_size = max_encryption_key_size; + cp.use_fixed_pin = use_fixed_pin; + cp.fixed_pin = htobl(fixed_pin); + cp.bonding_mode = bonding_mode; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) +{ + struct hci_request rq; + gap_set_author_requirement_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorization_enable = authorization_enable; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) +{ + struct hci_request rq; + gap_passkey_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.passkey = htobl(passkey); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_PASSKEY_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) +{ + struct hci_request rq; + gap_authorization_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorize = authorize; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB05A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + cp.own_address_type = own_address_type; + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB04A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) +{ + struct hci_request rq; + gap_set_undirected_connectable_cp cp; + uint8_t status; + + cp.own_addr_type = own_addr_type; + cp.adv_filter_policy = adv_filter_policy; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) +{ + struct hci_request rq; + gap_slave_security_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.bonding = bonding; + cp.mitm_protection = mitm_protection; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[32]; + uint8_t indx = 0; + + if (AdvLen > (sizeof(buffer)-1)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvLen; + indx++; + + Osal_MemCpy(buffer + indx, AdvData, AdvLen); + indx += AdvLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_UPDATE_ADV_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) +{ + struct hci_request rq; + gap_delete_ad_type_cp cp; + uint8_t status; + + cp.ad_type = ad_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_DELETE_AD_TYPE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required) +{ + struct hci_request rq; + gap_get_security_level_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; + rq.rparam = &resp; + rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *mitm_protection = resp.mitm_protection; + *bonding = resp.bonding; + *oob_data = resp.oob_data; + *passkey_required = resp.passkey_required; + + return resp.status; +} + +tBleStatus aci_gap_configure_whitelist(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) +{ + struct hci_request rq; + gap_terminate_cp cp; + uint8_t status; + + cp.handle = htobs(conn_handle); + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_clear_security_database(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) +{ + struct hci_request rq; + gap_allow_rebond_cp_IDB05A1 cp; + uint8_t status; + + cp.conn_handle = conn_handle; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_allow_rebond_IDB04A1(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_limited_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_general_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_name_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = use_reconn_addr; + indx++; + + Osal_MemCpy(buffer + indx, reconn_addr, 6); + indx += 6; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB05A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB04A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.use_reconn_addr = use_reconn_addr; + Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_start_selective_conn_establish_proc_cp cp; + uint8_t status; + + if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.num_whitelist_entries = num_whitelist_entries; + + Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_create_connection_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CREATE_CONNECTION; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; + rq.cparam = &procedure_code; + rq.clen = 1; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_connection_update_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) +{ + struct hci_request rq; + gap_send_pairing_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.force_rebond = force_rebond; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + gap_resolve_private_address_rp rp; + + Osal_MemCpy(cp.address, private_address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); + + return 0; +} +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + uint8_t status; + + Osal_MemCpy(cp.address, address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_set_broadcast_mode_cp cp; + uint8_t status; + uint8_t indx = 0; + uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; + + if (variable_size > sizeof(cp.var_len_data) ) + return BLE_STATUS_INVALID_PARAMS; + + cp.adv_interv_min = htobs(adv_interv_min); + cp.adv_interv_max = htobs(adv_interv_max); + cp.adv_type = adv_type; + cp.own_addr_type = own_addr_type; + + cp.var_len_data[indx] = adv_data_length; + indx++; + Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); + indx += adv_data_length; + cp.var_len_data[indx] = num_whitelist_entries; + indx ++; + Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_BROADCAST_MODE; + rq.cparam = &cp; + rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_observation_proc_cp cp; + uint8_t status; + + cp.scan_interval = scan_interval; + cp.scan_window = scan_window; + cp.scan_type = scan_type; + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_OBSERVATION_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) +{ + struct hci_request rq; + gap_is_device_bonded_cp cp; + uint8_t status; + + cp.peer_address_type = peer_address_type; + Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_IS_DEVICE_BONDED; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) +{ + struct hci_request rq; + gap_get_bonded_devices_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_BONDED_DEVICES; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (rp.status) { + return rp.status; + } + + *num_devices = rp.num_addr; + if(device_list != NULL) + Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1505 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.c +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : File with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_gatt_init(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INIT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[19]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, service_uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = service_type; + indx++; + + buffer[indx] = max_attr_records; + indx++; + + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle) +{ + struct hci_request rq; + gatt_include_serv_rp resp; + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + service_handle = htobs(service_handle); + Osal_MemCpy(buffer, &service_handle, 2); + indx += 2; + + included_start_handle = htobs(included_start_handle); + Osal_MemCpy(buffer+indx, &included_start_handle, 2); + indx += 2; + + included_end_handle = htobs(included_end_handle); + Osal_MemCpy(buffer+indx, &included_end_handle, 2); + indx += 2; + + if(included_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } else { + uuid_len = 16; + } + + buffer[indx] = included_uuid_type; + indx++; + + Osal_MemCpy(buffer + indx, included_uuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INCLUDE_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *included_handle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[25]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + buffer[indx] = charValueLen; + indx++; + + buffer[indx] = charProperties; + indx++; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *charHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle) +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = descValueMaxLen; + indx++; + + buffer[indx] = descValueLen; + indx++; + + if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + Osal_MemCpy(buffer + indx, descValue, descValueLen); + indx += descValueLen; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = accPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR_DESC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *descHandle = btohs(resp.handle); + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = charValOffset; + indx++; + + buffer[indx] = charValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charValue, charValueLen); + indx += charValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_char_cp cp; + + cp.service_handle = htobs(servHandle); + cp.char_handle = htobs(charHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_CHAR; + rq.cparam = &cp; + rq.clen = GATT_DEL_CHAR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_service(uint16_t servHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_serv_cp cp; + + cp.service_handle = htobs(servHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_inc_serv_cp cp; + + cp.service_handle = htobs(servHandle); + cp.inc_serv_handle = htobs(includeServHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_INC_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_INC_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) +{ + struct hci_request rq; + uint8_t status; + gatt_set_evt_mask_cp cp; + + cp.evt_mask = htobs(event_mask); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_EVT_MASK; + rq.cparam = &cp; + rq.clen = GATT_SET_EVT_MASK_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_exchange_config_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_EXCHANGE_CONFIG; + rq.cparam = &cp; + rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) +{ + struct hci_request rq; + uint8_t status; + att_find_info_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_INFO_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_find_by_type_value_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + Osal_MemCpy(cp.uuid, uuid, 2); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_group_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_prepare_write_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.value_offset = htobs(value_offset); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) +{ + struct hci_request rq; + uint8_t status; + att_execute_write_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.execute = execute; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_prim_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_prim_service_by_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; + rq.cparam = &cp; + rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, + uint16_t end_service_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_find_included_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_service_handle); + cp.end_handle = htobs(end_service_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_of_serv_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_attr_handle = htobs(start_attr_handle); + cp.end_attr_handle = htobs(end_attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t charUuidType, + const uint8_t* charUuid) +{ + struct hci_request rq; + uint8_t status; + + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + start_handle = htobs(start_handle); + Osal_MemCpy(buffer + indx, &start_handle, 2); + indx += 2; + + end_handle = htobs(end_handle); + Osal_MemCpy(buffer + indx, &end_handle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == 0x01){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_descriptors_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.char_val_handle = htobs(char_val_handle); + cp.char_end_handle = htobs(char_end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_read_using_charac_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; + rq.cparam = &cp; + rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles) +{ + struct hci_request rq; + uint8_t status; + gatt_read_multiple_charac_val_cp cp; + + if(num_handles*2 > sizeof(cp.set_of_handles)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.num_handles = htobs(num_handles); + Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_long_charac_val_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; + rq.cparam = &cp; + rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_signed_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_confirm_indication_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_CONFIRM_INDICATION; + rq.cparam = &cp; + rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = write_status; + indx += 1; + + buffer[indx] = err_code; + indx += 1; + + buffer[indx] = att_val_len; + indx += 1; + + Osal_MemCpy(buffer + indx, att_val, att_val_len); + indx += att_val_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(uint16_t conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ALLOW_READ; + rq.cparam = &cp; + rq.clen = GATT_ALLOW_READ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission) +{ + struct hci_request rq; + gatt_set_security_permission_cp cp; + uint8_t status; + + cp.service_handle = htobs(service_handle); + cp.attr_handle = htobs(attr_handle); + cp.security_permission = security_permission; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; + rq.cparam = &cp; + rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + charDescHandle = htobs(charDescHandle); + Osal_MemCpy(buffer + indx, &charDescHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charDescValOffset, 2); + indx += 2; + + buffer[indx] = charDescValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); + indx += charDescValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_DESC_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_cp cp; + gatt_read_handle_val_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = btohs(rp.value_len); + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_offset_cp cp; + gatt_read_handle_val_offset_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rp.value_len; + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value) +{ + struct hci_request rq; + uint8_t status; + gatt_upd_char_val_ext_cp cp; + + if(value_length > sizeof(cp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.service_handle = htobs(service_handle); + cp.char_handle = htobs(char_handle); + cp.update_type = update_type; + cp.char_length = htobs(char_length); + cp.value_offset = htobs(value_offset); + cp.value_length = value_length; + Osal_MemCpy(cp.value, value, value_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL_EXT; + rq.cparam = &cp; + rq.clen = GATT_UPD_CHAR_VAL_EXT_CP_SIZE + value_length; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,266 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number) +{ + struct hci_request rq; + hal_get_fw_build_number_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_FW_BUILD_NUMBER; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *build_number = rp.build_number; + + return 0; +} + +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((len+2) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = offset; + indx++; + + buffer[indx] = len; + indx++; + + Osal_MemCpy(buffer + indx, val, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + hal_read_config_data_cp cp; + hal_read_config_data_rp rp; + + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_READ_CONFIG_DATA; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rq.rlen-1; + + Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) +{ + struct hci_request rq; + hal_set_tx_power_level_cp cp; + uint8_t status; + + cp.en_high_power = en_high_power; + cp.pa_level = pa_level; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets) +{ + struct hci_request rq; + hal_le_tx_test_packet_number_rp resp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_LE_TX_TEST_PACKET_NUMBER; + rq.rparam = &resp; + rq.rlen = sizeof(resp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *number_of_packets = btohl(resp.number_of_packets); + + return 0; +} + +tBleStatus aci_hal_device_standby(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_DEVICE_STANDBY; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_start(uint8_t rf_channel) +{ + struct hci_request rq; + hal_tone_start_cp cp; + uint8_t status; + + cp.rf_channel = rf_channel; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_START; + rq.cparam = &cp; + rq.clen = HAL_TONE_START_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_stop(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_STOP; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]) +{ + struct hci_request rq; + hal_get_link_status_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_LINK_STATUS; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(link_status,rp.link_status,sizeof(link_status)); + for(int i = 0; i < 8; i++) + conn_handle[i] = btohs(rp.conn_handle[i]); + + return 0; +} + +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot) +{ + struct hci_request rq; + hal_get_anchor_period_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_ANCHOR_PERIOD; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *anchor_period = btohl(rp.anchor_period); + *max_free_slot = btohl(rp.max_free_slot); + + return 0; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,117 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB05A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.min_ce_length = htobs(min_ce_length); + cp.max_ce_length = htobs(max_ce_length); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB04A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,269 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_updater_aci.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_updater_reboot(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_get_updater_version(uint8_t *version) +{ + struct hci_request rq; + get_updater_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_VERSION; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) +{ + struct hci_request rq; + get_updater_bufsize_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_BUFSIZE; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_reset_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = htobl(address); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_SECTOR; + rq.cparam = &cp; + rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_program_data_block(uint32_t address, + uint16_t len, + const uint8_t *data) +{ + struct hci_request rq; + uint8_t status; + updater_prog_data_block_cp cp; + + if( len > sizeof(cp.data)) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(len); + Osal_MemCpy(cp.data, data, len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_read_data_block(uint32_t address, + uint16_t data_len, + uint8_t *data) +{ + struct hci_request rq; + updater_read_data_block_cp cp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + + if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(data_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; + rq.rparam = buffer; + rq.rlen = data_len + 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + // First byte is status + Osal_MemCpy(data, buffer+1, data_len); + + return buffer[0]; +} + +tBleStatus aci_updater_calc_crc(uint32_t address, + uint8_t num_sectors, + uint32_t *crc) +{ + struct hci_request rq; + updater_calc_crc_cp cp; + updater_calc_crc_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + cp.address = htobl(address); + cp.num_sectors = num_sectors; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_CALC_CRC; + rq.cparam = &cp; + rq.clen = UPDATER_CALC_CRC_CP_SIZE; + rq.rparam = &resp; + rq.rlen = UPDATER_CALC_CRC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *crc = btohl(resp.crc); + + return resp.status; +} + +tBleStatus aci_updater_hw_version(uint8_t *version) +{ + struct hci_request rq; + updater_hw_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_HW_VERSION; + rq.rparam = &resp; + rq.rlen = UPDATER_HW_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,423 @@ + +#include "ble_hal.h" +#include "ble_hal_types.h" +#include "ble_status.h" +#include "bluenrg_aci.h" +#include "bluenrg_utils.h" +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "ble_osal.h" +#include "string.h" +#include "stm32_bluenrg_ble.h" + +#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 +#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 + +#define BASE_ADDRESS 0x10010000 + +#define FW_OFFSET (2*1024) // 2 KB +#define FW_OFFSET_MS 0 +#define FULL_STACK_SIZE (66*1024) // 66 KB +#define BOOTLOADER_SIZE (2*1024) // 2 kB +#define SECTOR_SIZE (2*1024) // 2 KB + +// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + +// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 +#define CRC_POLY 0x04C11DB7 // the poly without the x**32 + +#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC + +#define IFR_SIZE 192 +#define IFR_BASE_ADDRESS 0x10020000 +#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data + +#if BLUENRG_MS +#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET +#else +#define IFR_WRITE_OFFSET_BEGIN 0 +#endif + + +#define BLUE_FLAG_OFFSET 0x8C0 +#define MAX_ERASE_RETRIES 2 +#define MAX_WRITE_RETRIES 2 +#define MIN_WRITE_BLOCK_SIZE 4 +#define MAX_WRITE_BLOCK_SIZE 64 // 64 bytes +#define READ_BLOCK_SIZE 64 // 64 bytes + +#define RETRY_COMMAND(func, num_ret, error) \ +{ \ + uint8_t num_retries; \ + num_retries = 0; \ + error = 0; \ + while (num_retries++ < num_ret) { \ + if (func == BLE_STATUS_SUCCESS) \ + break; \ + if (num_retries == num_ret) \ + error = BLE_UTIL_ACI_ERROR; \ + } \ +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, + they are extended with 0xFF until sector size is reached +*/ +static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) +{ + uint32_t i, j, a1; + uint32_t crc, value; + + crc = 0; + for (i = 0; i < SECTOR_SIZE; i += 4) { + uint8_t *dataw = (uint8_t *) &value; + + dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; + dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; + dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; + dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; + + crc = crc ^ value; + for (j = 0; j < 32; j ++) { + a1 = (crc >> 31) & 0x1; + crc = (crc << 1) ^ (a1 * CRC_POLY); + } + } + + return crc; +} + +int program_device(const uint8_t *fw_image, uint32_t fw_size) +{ + uint8_t version, num_erase_retries, status, write_block_size; + uint32_t address; + uint32_t crc, crc2, crc_size; + uint32_t fw_offset = FW_OFFSET; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + if(aci_updater_hw_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version==0x31){ + // It does not contain bootloader inside first sector. It may contain code. + fw_offset = FW_OFFSET_MS; + } + + if (fw_size != FULL_STACK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + if (fw_size % MIN_WRITE_BLOCK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + + /*********************************************************************** + * Erase BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + /*********************************************************************** + * Erase and Program sectors + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE) { + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(BASE_ADDRESS + i); + for (int j=i; ((j<i+SECTOR_SIZE)&&(j<fw_size)); j += write_block_size) { + + write_block_size = MIN(fw_size-j, MAX_WRITE_BLOCK_SIZE); + + RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, write_block_size, fw_image+j), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + break; + } + if (status == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + } + + /*********************************************************************** + * Verify firmware + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE){ + address = BASE_ADDRESS + i; + if(aci_updater_calc_crc(address, 1, &crc)) + return BLE_UTIL_ACI_ERROR; + + crc_size = MIN(fw_size-i,SECTOR_SIZE); + + crc2 = updater_calc_crc(fw_image+i,crc_size); + if(crc!=crc2) + return BLE_UTIL_CRC_ERROR; + } + + /*********************************************************************** + * Write BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +int read_IFR(uint8_t *data) +{ + uint8_t version, offset; + tBleStatus ret; + + offset = 0; + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + /*********************************************************************** + * Reading last 3 IFR 64-byte blocks + ************************************************************************/ + for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(BASE_ADDRESS+i, READ_BLOCK_SIZE, (data+offset)); + offset += READ_BLOCK_SIZE; + if(ret) return BLE_UTIL_ACI_ERROR; + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; + +} + +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) +{ + IFR_config->stack_mode = data[0]; + IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); + IFR_config->master_sca = data[30]; + IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); + IFR_config->year = BCD_TO_INT(data[41]); + IFR_config->month = BCD_TO_INT(data[42]); + IFR_config->day = BCD_TO_INT(data[43]); +} + +int IFR_validate(IFR_config2_TypeDef *IFR_config) +{ +#if BLUENRG_MS + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) +#else + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) +#endif + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode + if(IFR_config->master_sca > 7) + return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->day > 31 || IFR_config->day < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + + return BLE_STATUS_SUCCESS; +} + +/* TODO: Function to generate data from given options. */ + +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) +{ + data[0] = IFR_config->stack_mode; + HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); + data[30] = IFR_config->master_sca; + HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); + data[41] = INT_TO_BCD(IFR_config->year); + data[42] = INT_TO_BCD(IFR_config->month); + data[43] = INT_TO_BCD(IFR_config->day); +} + + +int program_IFR(const IFR_config_TypeDef *ifr_image) +{ + uint8_t version, num_erase_retries; + tBleStatus ret; +#if BLUENRG_MS + const uint8_t *ifr_data = (uint8_t *)ifr_image; +#else + uint8_t ifr_data[SECTOR_SIZE]; +#endif + uint8_t hwVersion; + uint16_t fwVersion; + + if(getBlueNRGVersion(&hwVersion, &fwVersion)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + +#ifndef BLUENRG_MS + /*********************************************************************** + * READ IFR data + ************************************************************************/ + for(int i = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_data+i); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + } +#endif + + /*********************************************************************** + * Erase & Flashing IFR sectors + ************************************************************************/ +#ifndef BLUENRG_MS + Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); +#endif + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(IFR_BASE_ADDRESS); + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += MAX_WRITE_BLOCK_SIZE, j += MAX_WRITE_BLOCK_SIZE) { + RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, MAX_WRITE_BLOCK_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); + if (ret != BLE_STATUS_SUCCESS) + break; + } + if (ret == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + + /*********************************************************************** + * Verify IFR + ************************************************************************/ + { + uint8_t ifr_updated[READ_BLOCK_SIZE]; + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE, j += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ifr_data+j, READ_BLOCK_SIZE) != 0) + return BLE_UTIL_WRONG_VERIFY; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) +{ + uint8_t ifr_updated[READ_BLOCK_SIZE]; + uint8_t version, ret = BLE_STATUS_SUCCESS; + + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + for(int i = 0; i < IFR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, READ_BLOCK_SIZE) != 0) + { + ret = BLE_UTIL_WRONG_VERIFY; + break; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return ret; +} + +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) +{ + uint8_t status; + uint8_t hci_version, lmp_pal_version; + uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; + + status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, + &manufacturer_name, &lmp_pal_subversion); + + if (status == BLE_STATUS_SUCCESS) { + *hwVersion = hci_revision >> 8; + *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number + *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number + *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number + } + + return status; +} + +uint8_t getBlueNRGUpdaterVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(version)) + return BLE_UTIL_ACI_ERROR; + + if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_updater_hw_version(version)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t isHWBootloader_Patched(void) +{ + uint8_t status, version; + uint32_t crc, address = 0x10010000; + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); + if (status != BLE_STATUS_SUCCESS) + return 0; + + if (crc == BOOTLOADER_CRC_NOT_PATCHED) + return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +#include "ble_gp_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function sets a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * @param[in] t A pointer to the timer + * @param[in] interval The interval before the timer expires. + * + */ +void +Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +Timer_Expired(struct timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + tClockTime diff = (Clock_Time() - t->start) + 1; + return t->interval < diff; + +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +tClockTime +Timer_Remaining(struct timer *t) +{ + return t->start + t->interval - Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +#ifdef __DMA_LP__ + +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID) +{ + TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, + (pf_TIMER_TimerCallBack_t) timercb); + TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); + + return (BLE_STATUS_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) +{ + TIMER_Delete(timerID); + + return (BLE_STATUS_SUCCESS); +} + +#endif /* __DMA_LP__ */ +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,119 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Circular Linked List Implementation. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/****************************************************************************** + * Include Files +******************************************************************************/ +#include <ble_hal_types.h> +#include "ble_list.h" + +/****************************************************************************** + * Function Definitions +******************************************************************************/ +void list_init_head (tListNode * listHead) +{ + listHead->next = listHead; + listHead->prev = listHead; +} + +uint8_t list_is_empty (tListNode * listHead) +{ + return ((listHead->next == listHead)? TRUE:FALSE); +} + +void list_insert_head (tListNode * listHead, tListNode * node) +{ + node->next = listHead->next; + node->prev = listHead; + listHead->next = node; + (node->next)->prev = node; +} + + +void list_insert_tail (tListNode * listHead, tListNode * node) +{ + node->next = listHead; + node->prev = listHead->prev; + listHead->prev = node; + (node->prev)->next = node; +} + + +void list_remove_node (tListNode * node) +{ + (node->prev)->next = node->next; + (node->next)->prev = node->prev; +} + + +void list_remove_head (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->next; + list_remove_node (listHead->next); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_remove_tail (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->prev; + list_remove_node (listHead->prev); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_insert_node_after (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node->next; + node->prev = ref_node; + ref_node->next = node; + (node->next)->prev = node; +} + + +void list_insert_node_before (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node; + node->prev = ref_node->prev; + ref_node->prev = node; + (node->prev)->next = node; +} + + +int list_get_size (tListNode * listHead) +{ + int size = 0; + tListNode * temp = listHead->next; + while (temp != listHead) + { + size++; + temp = temp->next; + } + return (size); +} + +void list_get_next_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->next; +} + + +void list_get_prev_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->prev; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,72 @@ +/** +****************************************************************************** +* @file ble_osal.c +* @author AMS - HEA&RF BU / CL +* @version V1.0.0 +* @date 04-July-2014 +* @brief Implementation of OS abstraction layer functions used by the +* library. +****************************************************************************** +* @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> +#include <ble_osal.h> + + /** + * @brief Osal_MemCpy + * @param dest: Pointer to the destination buffer + * @param src : Pointer to the source buffer + * @param size: Number of bytes to copy from the source to the destination + * buffer + * @retval Pointer to the destination buffer + */ +void* Osal_MemCpy(void *dest, const void *src, unsigned int size) +{ + return(memcpy(dest,src,size)); +} + +/** + * @brief Osal_MemSet + * @param ptr : Pointer to block of memory to fill + * @param value: Value to assign to each byte of the memory block + * @param size : Number of bytes to be set to "value" + * @retval Pointer to the filled block of memory + */ +void* Osal_MemSet(void *ptr, int value, unsigned int size) +{ + return(memset(ptr,value,size)); +} + +/****************************************************************************** + * local Functions + *****************************************************************************/ + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ + +#include "ble_clock.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/wait_api.h" + #include "mbed-drivers/rtc_time.h" +#else + #include "wait_api.h" + #include "rtc_time.h" +#endif + +const uint32_t CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + //Not Used +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return clock(); +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,715 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file btle.cpp + * @author STMicroelectronics + * @brief Implementation BlueNRG Init and helper functions. + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + + +#include "btle.h" +#include "ble/Gap.h" +#include "ble/GapEvents.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" + +#include "bluenrg_targets.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* C File Includes ------------------------------------------------------------------*/ +#include <stdio.h> +#include <string.h> +#include "ble_hci.h" +#include "ble_hci_const.h" +#include "bluenrg_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" +#include "bluenrg_utils.h" + +#include "ble_hal_types.h" +#include "ble_hal.h" +#include "ble_gp_timer.h" +#include "ble_osal.h" +#include "ble_sm.h" +#include "ble_debug.h" + +#ifdef __cplusplus +} +#endif + +#define IDB04A1 0 +#define IDB05A1 1 + +/* See file 'bluenrg_targets.h' for details regarding the BLUENRG_STACK_MODE */ +#define STACK_MODE BLUENRG_STACK_MODE + +void HCI_Input(tHciDataPacket * hciReadPacket); + +uint16_t g_gap_service_handle = 0; +uint16_t g_appearance_char_handle = 0; +uint16_t g_device_name_char_handle = 0; +uint16_t g_preferred_connection_parameters_char_handle = 0; + +/* Private variables ---------------------------------------------------------*/ +volatile uint8_t set_connectable = 1; + +static char versionString[32]; +uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ + +/**************************************************************************/ +/*! + @brief Init the BTLE stack with the specified role + @returns void +*/ +/**************************************************************************/ +void btleInit(void) +{ + PRINTF("btleInit>>\n\r"); + + int ret; + uint8_t hwVersion; + uint16_t fwVersion; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* get the BlueNRG HW and FW versions */ + getBlueNRGVersion(&hwVersion, &fwVersion); + + /* + * Reset BlueNRG again otherwise we won't + * be able to change its MAC address. + * aci_hal_write_config_data() must be the first + * command after reset otherwise it will fail. + */ + BlueNRG_RST(); + + if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ + bnrg_expansion_board = IDB05A1; + } + + /* set BLE version string */ + setVersionString(hwVersion, fwVersion); + + if (bnrg_expansion_board == IDB05A1) { + uint8_t stackMode = STACK_MODE; + ret = aci_hal_write_config_data(CONFIG_DATA_MODE_OFFSET, + CONFIG_DATA_MODE_LEN, + &stackMode); + } + + ret = aci_gatt_init(); + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GATT_Init failed.\n"); + } + if (bnrg_expansion_board == IDB05A1) { + ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1, + 0, + 0x18, + &service_handle, + &dev_name_char_handle, + &appearance_char_handle); + } else { + // IDB04A1 is configured as peripheral by default + ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + } + + // read the default static address and inject it into the GAP object + { + Gap::Address_t BLE_address_BE = { 0 }; + uint8_t data_len_out; + aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS, BDADDR_SIZE, &data_len_out, BLE_address_BE); + // FIXME error handling of this function + BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE); + } + + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GAP_Init failed.\n"); + } + + //FIXME: Security and passkey set by default + ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, + OOB_AUTH_DATA_ABSENT, + NULL, + 7, + 16, + USE_FIXED_PIN_FOR_PAIRING, + 123456, + BONDING); + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Auth Req set failed.\n"); + } + + aci_hal_set_tx_power_level(1,4); + + g_gap_service_handle = service_handle; + g_appearance_char_handle = appearance_char_handle; + g_device_name_char_handle = dev_name_char_handle; + //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API + /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, + strlen(name), (tHalUint8 *)name);*/ + + signalEventsToProcess(); + // update the peripheral preferred conenction parameters handle + // This value is hardcoded at the moment. + g_preferred_connection_parameters_char_handle = 10; + + return; +} + +/**************************************************************************/ +/*! + @brief mbedOS + + @param[in] void + + @returns +*/ +/**************************************************************************/ +int btle_handler_pending = 0; + +void btle_handler(void) +{ + btle_handler_pending = 0; + BlueNRGGap::getInstance().Process(); + HCI_HandleSPI(); + HCI_Process(); +} + +/* set BLE Version string */ +void setVersionString(uint8_t hwVersion, uint16_t fwVersion) +{ + if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) { + snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u", + hwVersion>>4, (hwVersion&0x0F), + fwVersion>>8, (fwVersion&0x00F0)>>4); + } else { + snprintf(versionString, sizeof(versionString), "ST (unknown spec)"); + } +} + +/* get BLE Version string */ +const char* getVersionString(void) +{ + return versionString; +} + +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type) +{ + tBleStatus ret; + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + if(bnrg_expansion_board == IDB05A1) { + PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window); + PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type); + ret = aci_gap_start_observation_procedure(scan_interval, + scan_window, + scan_type, + own_address_type, + 0); // 1 to filter duplicates + } else { + ret = BLE_STATUS_INVALID_CID; + } + + return ret; + +} + +/*! + @brief Not Used + + @param[in] void + + @returns +*/ +void SPI_Poll(void) +{ + //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); + return; +} + +void Attribute_Modified_CB(evt_blue_aci *blue_evt) +{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t *att_data; + uint8_t offset; + + if (bnrg_expansion_board == IDB05A1) { + evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = evt->offset; + } else { + evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = 0; + } + + //Extract the GattCharacteristic from p_characteristics[] and find the properties mask + GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle); + if(p_char!=NULL) { + GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE; + PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]); + PRINTF("getProperties 0x%x\n\r",p_char->getProperties()); + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; + } + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; + } + PRINTF("currentHandle %d\n\r", currentHandle); + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && + currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { + + GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1; + + PRINTF("*****NOTIFICATION CASE\n\r"); + //Now Check if data written in Enable or Disable + if((uint16_t)att_data[0]==1) { + //PRINTF("Notify ENABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle); + } else { + //PRINTF("Notify DISABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle); + } + return; + } + + //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) && + currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) { + + PRINTF("*****WRITE CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = p_char->getValueAttribute().getHandle(); + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle); + //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + BlueNRGGattServer::getInstance().write( + p_char->getValueAttribute().getHandle(), + (uint8_t*)att_data, + data_length, + false + ); + } + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } else { + PRINTF("*****WRITE DESCRIPTOR CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = attr_handle; + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } + } + +} + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************************/ + /*! + @brief Handle HCI Stack Event + + @param[in] pckt + Event Packet sent by the stack to be decoded + + @returns + */ + /**************************************************************************/ + extern void HCI_Event_CB(void *pckt) { + hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; + hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; + + if(hci_pckt->type != HCI_EVENT_PKT) + return; + + switch(event_pckt->evt){ + + case EVT_DISCONN_COMPLETE: + { + PRINTF("EVT_DISCONN_COMPLETE\n"); + + evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data; + + if(BlueNRGGap::getInstance().getGapRole() == Gap::CENTRAL) { + BlueNRGGattClient::getInstance().removeGattConnectionClient(evt->handle, evt->reason); + } + + BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason); + } + break; + + case EVT_LE_META_EVENT: + { + PRINTF("EVT_LE_META_EVENT\n"); + + evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; + + switch(evt->subevent){ + + case EVT_LE_CONN_COMPLETE: + { + PRINTF("EVT_LE_CONN_COMPLETE\n"); + Gap::Address_t ownAddr; + Gap::AddressType_t ownAddrType; + BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr); + + Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + Gap::Role_t role; + + evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; + + BlueNRGGap::getInstance().setConnectionHandle(cc->handle); + BlueNRGGap::ConnectionParams_t connectionParams = { + /* minConnectionInterval = */ cc->interval, + /* maxConnectionInterval = */ cc->interval, + /* slaveLatency = */ cc->latency, + /* connectionSupervisionTimeout = */ cc->supervision_timeout + }; + + BlueNRGGap::getInstance().setConnectionInterval(cc->interval); + + switch (cc->peer_bdaddr_type) { + case PUBLIC_ADDR: + peerAddrType = BLEProtocol::AddressType::PUBLIC; + break; + case STATIC_RANDOM_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + break; + case RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE; + break; + case NON_RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE; + break; + } + //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role); + switch (cc->role) { + case 0: //master + role = Gap::CENTRAL; + BlueNRGGattClient::getInstance().createGattConnectionClient(cc->handle); + break; + case 1: + role = Gap::PERIPHERAL; + break; + default: + role = Gap::PERIPHERAL; + break; + } + + BlueNRGGap::getInstance().setGapRole(role); + + BlueNRGGap::getInstance().processConnectionEvent(cc->handle, + role, + peerAddrType, + cc->peer_bdaddr, + ownAddrType, + ownAddr, + &connectionParams); + } + break; + + case EVT_LE_ADVERTISING_REPORT: + PRINTF("EVT_LE_ADVERTISING_REPORT\n\r"); + /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */ + // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT) + // Formally the structure related to both events are identical except that for the ADV REPORT + // there is one more field (number of reports) which is not forwarded to upper layer. + // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT. + le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1); + PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + break; + } + } + break; + + case EVT_VENDOR: + { + evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; + //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode); + + switch(blue_evt->ecode){ + + case EVT_BLUE_GATT_WRITE_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_WRITE_PERMIT_REQ\r\n"); + evt_gatt_write_permit_req* write_req = (evt_gatt_write_permit_req*)blue_evt->data; + + // ask the local server if the write operation is authorized + uint8_t err_code = BlueNRGGattServer::getInstance().Write_Request_CB( + write_req->conn_handle, + write_req->attr_handle, + write_req->data_length, + write_req->data + ); + uint8_t write_status = err_code == 0 ? 0 : 1; + + // reply to the shield + aci_gatt_write_response( + write_req->conn_handle, + write_req->attr_handle, + write_status, + err_code, + write_req->data_length, + write_req->data + ); + } + break; + + case EVT_BLUE_GATT_READ_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r"); + evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle); + BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle); + } + break; + + case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: + { + PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r"); + /* this callback is invoked when a GATT attribute is modified + extract callback data and pass to suitable handler function */ + Attribute_Modified_CB(blue_evt); + } + break; + + //Any cases for Data Sent Notifications? + case EVT_BLUE_GATT_NOTIFICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_NOTIFICATION"); + break; + case EVT_BLUE_GATT_INDICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_INDICATION"); + break; + + case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r"); + evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_data_length, + pr->attribute_data_list); + } + break; + case EVT_BLUE_ATT_READ_BY_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r"); + evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle, + pr->event_data_length, + pr->handle_value_pair_length, + pr->handle_value_pair); + } + break; + case EVT_BLUE_ATT_READ_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_RESP\n\r"); + evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_value); + } + break; + case EVT_BLUE_ATT_EXEC_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle, + pr->event_data_length); + } + break; + case EVT_BLUE_ATT_PREPARE_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_handle, + pr->offset, + pr->part_attr_value); + } + break; + case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP: + { + PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r"); + evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle, + pr->event_data_length, + pr->attr_handle, + pr->attr_value); + } + break; + case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r"); + evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle, + pr->event_data_length, + pr->handles_info_list); + } + break; + case EVT_BLUE_ATT_FIND_INFORMATION_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r"); + evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle, + pr->event_data_length, + pr->format, + pr->handle_uuid_pair); + } + break; + case EVT_BLUE_GATT_PROCEDURE_COMPLETE: + { + evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code); + BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code); + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_REQ: + { + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_REQ\r\n"); + evt_l2cap_conn_upd_req *evt = (evt_l2cap_conn_upd_req*)blue_evt->data; + if(bnrg_expansion_board == IDB05A1) { + // we assume the application accepts the request from the slave + aci_l2cap_connection_parameter_update_response_IDB05A1(evt->conn_handle, + evt->interval_min, + evt->interval_max, + evt->slave_latency, + evt->timeout_mult, + CONN_L1, CONN_L2, + evt->identifier, + 0x0000); + } + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_RESP: + { + evt_l2cap_conn_upd_resp *evt = (evt_l2cap_conn_upd_resp*)blue_evt->data; + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_RESP code=0x%x, result=0x%x\r\n", evt->code, evt->result); + } + break; + + case EVT_LE_CONN_UPDATE_COMPLETE: + { + evt_le_connection_update_complete *evt = (evt_le_connection_update_complete*)blue_evt->data; + PRINTF("EVT_LE_CONN_UPDATE_COMPLETE status=0x%x\r\n", evt->status); + } + break; + + case EVT_BLUE_GAP_DEVICE_FOUND: + { + evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data; + PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + } + break; + + case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + { + evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data; + //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code); + + switch(pr->procedure_code) { + case GAP_OBSERVATION_PROC_IDB05A1: + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL); + break; + } + } + break; + } + } + break; + } + return ; + } + + +#ifdef __cplusplus +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,217 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.cpp + * @author CL + * @version V1.0.0 + * @date 15-June-2015 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRGGap.h" +#include "BlueNRGDevice.h" +#include "btle.h" + +// FIXME: find a better way to get the instance of the BlueNRG device +extern BlueNRGDevice bluenrgDeviceInstance; + + +//////////////////////////////////////// +// Start of C function wrappers +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32_bluenrg_ble.h" +#include "ble_debug.h" + + +void BlueNRG_RST(void) +{ + bluenrgDeviceInstance.reset(); +} + +uint8_t BlueNRG_DataPresent(void) +{ + return (bluenrgDeviceInstance.dataPresent()); +} + + +/** + * @brief This function is a utility to print the log time +* in the format HH:MM:SS:MSS (DK GUI time format) + * @param None + * @retval None + */ +void print_csv_time(void){ +#ifdef PRINT_CSV_FORMAT + uint32_t ms = 0;//ms_counter; + PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000); +#endif +} + +/** + * @brief Writes data to a serial interface. + * @param data1 : 1st buffer + * @param data2 : 2nd buffer + * @param n_bytes1: number of bytes in 1st buffer + * @param n_bytes2: number of bytes in 2nd buffer + * @retval None + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, + int32_t n_bytes2) +{ + struct timer t; + + Timer_Set(&t, CLOCK_SECOND/10); + +#ifdef PRINT_CSV_FORMAT + print_csv_time(); + for (int i=0; i<n_bytes1; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data1)[i]); + } + for (int i=0; i<n_bytes2; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data2)[i]); + } + PRINT_CSV("\n"); +#endif + + while(1){ + if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; + if(Timer_Expired(&t)){ + break; + } + } +} + + +/** + * @brief Activate internal bootloader using pin. + * @param None + * @retval None + */ +void BlueNRG_HW_Bootloader(void) +{ + // Reset BlueNRG SPI interface + BlueNRG_RST(); + + // Send an ACI command to reboot BlueNRG in bootloader mode + // The safest way to get in bootloader mode is keeping high + // the interrupt pin during reset, but this would require many + // changes to the current mbed driver + aci_updater_start(); +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size) +{ + int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size); + + return ret; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2); + + return ret; +} + +/** + * @brief Enable SPI IRQ. + * @param None + * @retval None + */ +void Enable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.enable_irq(); +} + +void signalEventsToProcess(void) { + if(btle_handler_pending == 0) { + btle_handler_pending = 1; + bluenrgDeviceInstance.signalEventsToProcess(BLE::DEFAULT_INSTANCE); + } +} + +/** + * @brief Disable SPI IRQ. + * @param None + * @retval None + */ +void Disable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.disable_irq(); +} + +/** + * @brief Clear Pending SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_IRQ(void) +{ +} + +/** + * @brief Clear EXTI (External Interrupt) line for SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_EXTI_Flag(void) +{ +} + + + + +#ifdef __cplusplus +} +#endif +// End of C function wrappers +//////////////////////////////////////// + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <ble_payload.h> + +Payload::Payload() { + stringLength = 0; + payloadUnitCount = 0; + payload = NULL; +} + +Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + stringLength = string_ength; + payloadUnitCount = 0; + payload = NULL; + + int index = 0; + while( index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + UnitPayload *obj = new UnitPayload[payloadUnitCount]; + int i=0; + int c=0; + int j,k; + + while(i<payloadUnitCount) + { + obj[i].length=tokenString[c]; + obj[i].id=tokenString[c+1]; + + obj[i].data = new uint8_t[obj[i].length]; + for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) + { + obj[i].data[k]=tokenString[j]; + + } + + c=c+obj[i].length+1; + i++; + + } + payload = obj; +} + +uint8_t Payload::getPayloadUnitCount() { + return payloadUnitCount; +} + +uint8_t Payload::getIDAtIndex(int index) { + return payload[index].get_id(); +} + +uint8_t Payload::getLengthAtIndex(int index) { + return payload[index].get_length(); +} + +uint8_t* Payload::getDataAtIndex(int index) { + return payload[index].get_data(); +} + +int8_t Payload::getInt8AtIndex(int index) { + uint8_t* str = payload[index].get_data(); + int8_t value = (int8_t)str[0]; + return value; +} + +uint16_t Payload::getUint16AtIndex(int index) { + uint16_t* str = (uint16_t*)payload[index].get_data(); + uint16_t value = str[0]; + return value; +} + +uint8_t* Payload::getSerializedAdDataAtIndex(int index) { + uint8_t length = payload[index].get_length(); + uint8_t* data = payload[index].get_data(); + uint8_t id = payload[index].get_id(); + uint8_t *serializedAdData = new uint8_t[length]; + + serializedAdData[0] = id; + for(int i=0; i<length-1; i++) { + serializedAdData[i+1] = data[i]; + } + return serializedAdData; +} + +Payload::~Payload() { + int i = 0; + + if(payload) { + while(i<payloadUnitCount) { + if(payload->data) { + delete[] payload->data; + payload->data = NULL; + } + } + delete[] payload; + payload = NULL; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,93 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ble_utils.h" + +/**************************************************************************/ +/*! + @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power + +*/ +/**************************************************************************/ +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(dBMLevel==-18) { + EN_HIGH_POWER = 0; + PA_LEVEL = 0; + } + else if(dBMLevel==-15) { + EN_HIGH_POWER = 0; + PA_LEVEL = 1; + } + else if(dBMLevel==-14) { + EN_HIGH_POWER = 1; + PA_LEVEL = 0; + } + else if(dBMLevel==-12) { + EN_HIGH_POWER = 0; + PA_LEVEL = 2; + } + else if(dBMLevel==-11) { + EN_HIGH_POWER = 1; + PA_LEVEL = 1; + } + else if(dBMLevel==-9) { + EN_HIGH_POWER = 0; + PA_LEVEL = 3; + } + else if(dBMLevel==-8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 2; + } + else if(dBMLevel==-6) { + EN_HIGH_POWER = 0; + PA_LEVEL = 4; + } + else if(dBMLevel==-5) { + EN_HIGH_POWER = 1; + PA_LEVEL = 3; + } + else if(dBMLevel==-2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 4; + } + else if(dBMLevel==0) { + EN_HIGH_POWER = 0; + PA_LEVEL = 6; + } + else if(dBMLevel==2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 5; + } + else if(dBMLevel==4) { + EN_HIGH_POWER = 1; + PA_LEVEL = 6; + } + else if(dBMLevel==5) { + EN_HIGH_POWER = 0; + PA_LEVEL = 7; + } + else if(dBMLevel==8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + else { + ret = ERR_INVALID_HCI_CMD_PARAMS; + } + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_BatteryLevel/source/main.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,129 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <events/mbed_events.h> +#include <mbed.h> +#include "ble/BLE.h" +#include "ble/Gap.h" +#include "ble/services/BatteryService.h" + +DigitalOut led1(LED1, 1); + +const static char DEVICE_NAME[] = "BATTERY"; +static const uint16_t uuid16_list[] = {GattService::UUID_BATTERY_SERVICE}; + +static uint8_t batteryLevel = 50; +static BatteryService* batteryServicePtr; + +static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); + +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) +{ + BLE::Instance().gap().startAdvertising(); +} + +void updateSensorValue() { + batteryLevel++; + if (batteryLevel > 100) { + batteryLevel = 20; + } + + batteryServicePtr->updateBatteryLevel(batteryLevel); +} + +void blinkCallback(void) +{ + led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ + + BLE &ble = BLE::Instance(); + if (ble.gap().getState().connected) { + eventQueue.call(updateSensorValue); + } +} + +/** + * This function is called when the ble initialization process has failled + */ +void onBleInitError(BLE &ble, ble_error_t error) +{ + /* Initialization error handling should go here */ +} + +void printMacAddress() +{ + /* Print out device MAC address to the console*/ + Gap::AddressType_t addr_type; + Gap::Address_t address; + BLE::Instance().gap().getAddress(&addr_type, address); + printf("DEVICE MAC ADDRESS: "); + for (int i = 5; i >= 1; i--){ + printf("%02x:", address[i]); + } + printf("%02x\r\n", address[0]); +} + +/** + * Callback triggered when the ble initialization process has finished + */ +void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) +{ + BLE& ble = params->ble; + ble_error_t error = params->error; + + if (error != BLE_ERROR_NONE) { + /* In case of error, forward the error handling to onBleInitError */ + onBleInitError(ble, error); + return; + } + + /* Ensure that it is the default instance of BLE */ + if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { + return; + } + + ble.gap().onDisconnection(disconnectionCallback); + + /* Setup primary service */ + batteryServicePtr = new BatteryService(ble, batteryLevel); + + /* Setup advertising */ + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *) uuid16_list, sizeof(uuid16_list)); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *) DEVICE_NAME, sizeof(DEVICE_NAME)); + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.gap().setAdvertisingInterval(1000); /* 1000ms */ + ble.gap().startAdvertising(); + + printMacAddress(); +} + +void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { + BLE &ble = BLE::Instance(); + eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); +} + +int main() +{ + eventQueue.call_every(500, blinkCallback); + + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(scheduleBleEventsProcessing); + ble.init(bleInitComplete); + + eventQueue.dispatch_forever(); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/.mbed Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +ROOT=.
Binary file mbed-os-example-ble-master/BLE_Beacon/img/beacon_details.png has changed
Binary file mbed-os-example-ble-master/BLE_Beacon/img/discovery.png has changed
Binary file mbed-os-example-ble-master/BLE_Beacon/img/start_scan.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/mbed-os.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/mbed_app.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "target_overrides": { + "K64F": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "NUCLEO_F401RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "DISCO_L475VG_IOT01A": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "ble-beacon", + "version": "0.0.1", + "description": "BLE iBeacon example, building with yotta", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "dependencies": { + "ble": "^2.0.0" + }, + "targetDependencies": {}, + "bin": "./source" +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/readme.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,52 @@ +This example creates a BLE beacon: a method of advertising a small amount of information to nearby devices. The information doesn't have to be human-readable; it can be in a format that only an application can use. + +Beacons are very easy to set up: the code for all beacons is the same, and only the information you want to advertise - the beacon payload - needs to change. + +This example advertises a UUID, a major and minor number and the transmission strength. The major and minor numbers are an example of information that is not (normally) meaningful to humans, but that an application can use to identify the beacon and display related information. For example, if the major number is a store ID and the minor number is a location in that store, then a matching application can use these numbers to query a database and display location-specific information. + +# Running the application + +## Requirements + +The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : + +- [nRF Connect for Mobile](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. + +- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Checking for success + +**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. + +1. Build the application and install it on your board as explained in the building instructions. +1. Open the BLE scanner on your phone. +1. Start a scan. + +  + + **figure 1** How to start scan using nRF Master Control Panel 4.0.5 + +1. Find your device; it should be tagged as an `iBeacon` and observe its advertisements (there is no need to connect to the beacon). + +  + + **figure 2** Scan results using nRF Master Control Panel 4.0.5 + +1. View the beacon's details; the exact steps depend on which scanner you're using. + +  + + **figure 3** Beacon details using nRF Master Control Panel 4.0.5 + + +**Tip:** If you are in an area with many BLE devices, it may be difficult to identify your beacon. The simplest solution is to turn your board off and on, initiate a new scan on your BLE scanner every time, and look for the beacon that appears only when your board is on. + +If you can see the beacon and all its information, the application worked properly. + +For more information, see the [mbed Classic version of this application](https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_iBeacon/).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/#b630517008bbe47592927cc8e5dfcd2e5b9de968
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/.gitignore Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,9 @@ +# vim temporary files +*.sw* + +# yotta files +build +yotta_modules +yotta_targets +.yotta.json +upload.tar.gz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,34 @@ +# BLE-X-NUCLEO-IDB0XA1 + +BLE_API wrapper Library for X-NUCLEO-IDB05A1 BlueNRG (Bluetooth Low Energy) Expansion Board + +## Introduction + +This firmware package implements the port of BLE_API to STMicroelectronics' [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) Bluetooth Low Energy Nucleo Expansion Board. + +### Arduino Connector Compatibility Warning + +X-NUCLEO-IDB05A1 is Arduino compatible with an exception: instead of using pin **D13** for the SPI clock, pin **D3** is used. +The default configuration for this library is having the SPI clock on pin **D3**. + +To be fully Arduino compatible, X-NUCLEO-IDB05A1 needs a small HW patch. + +For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor **R4** and instead soldering zero resistor **R6**. + +In case you patch your board, then you also have to configure this library to use pin **D13** to drive the SPI clock. To this aim you need to compile this driver with macro `BLUENRG_PIN_SPI_SCK=D13` defined. + +If you use pin **D13** for the SPI clock, please be aware that on STM32 Nucleo boards you may **not** drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin **D13**. + +Referring to the current list of tested platforms (see [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) page), the patch is required by [ST-Nucleo-F103RB](https://developer.mbed.org/platforms/ST-Nucleo-F103RB/); [ST-Nucleo-F302R8](https://developer.mbed.org/platforms/ST-Nucleo-F302R8/); [ST-Nucleo-F411RE](https://developer.mbed.org/platforms/ST-Nucleo-F411RE/); [ST-Nucleo-F446RE](https://developer.mbed.org/platforms/ST-Nucleo-F446RE/); and [FRDM-K64F](https://developer.mbed.org/platforms/FRDM-K64F/). + +### Firmware update + +For better performance and compatibility with latest mbed API, you should update firmware of X-NUCLEO-IDB05A1 component by using this simple [application](https://developer.mbed.org/teams/ST/code/BlueNRG-MS-Stack-Updater). + +### Driver configuration + +In order to use the BlueNRG-MS module together with other targets, you need to set the macros defined in file [bluenrg_targets.h](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/bluenrg/bluenrg_targets.h). Please, update the [mbed_lib.json](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/mbed_lib.json) to include the list of extra macros that configure the driver for your target. + +## Example Applications + +To run BLE example applications using X-NUCLEO-IDB05A1 Expansion Board based on mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli), please refer to section [Using ST shield on other targets](https://github.com/ARMmbed/mbed-os-example-ble#using-st-nucleo-shield-on-other-targets) in the official [mbed-os-example-ble](https://github.com/ARMmbed/mbed-os-example-ble) page.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.h + * @author STMicroelectronics + * @brief Header file for BLEDeviceInstanceBase based BlueNRGDevice + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_DEVICE_H__ +#define __BLUENRG_DEVICE_H__ + +#define BLUENRG +#define DEBUG_BLUENRG_USER + +#include "btle.h" + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "ble/BLEInstanceBase.h" +#include "ble/BLE.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" + + +class BlueNRGDevice : public BLEInstanceBase +{ + +public: + BlueNRGDevice(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, PinName irq); + virtual ~BlueNRGDevice(void); + + virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback); + virtual ble_error_t shutdown(void); + virtual const char *getVersion(void); + virtual Gap& getGap(); + virtual const Gap& getGap() const; + virtual GattServer& getGattServer(); + virtual const GattServer& getGattServer() const; + virtual void waitForEvent(void); + + virtual GattClient& getGattClient() { + return BlueNRGGattClient::getInstance(); + } + + virtual SecurityManager& getSecurityManager() { + return *sm; + } + + virtual const SecurityManager& getSecurityManager() const { + return *sm; + } + void reset(void); + virtual bool hasInitialized(void) const { + return isInitialized; + } + + uint8_t getUpdaterHardwareVersion(uint8_t *hw_version); + int updateFirmware(const uint8_t *fw_image, uint32_t fw_size); + bool dataPresent(); + int32_t spiRead(uint8_t *buffer, uint8_t buff_size); + int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2); + void disable_irq(); + void enable_irq(); + + virtual void processEvents(); + +private: + bool isInitialized; + + SPI spi_; + DigitalOut nCS_; + DigitalOut rst_; + InterruptIn irq_; + + //FIXME: TBI (by now just placeholders to let build + /*** betzw: placeholders ***/ + SecurityManager *sm; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ +#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ + +#include "ble/DiscoveredCharacteristic.h" + +class BlueNRGGattClient; /* forward declaration */ + +class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic { +public: + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + + void setLastHandle(GattAttribute::Handle_t lastHandleIn); +}; + +#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGGap.h + * @author STMicroelectronics + * @brief Header file for BlueNRG BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GAP_H__ +#define __BLUENRG_GAP_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/Gap.h" + +#define BLE_CONN_HANDLE_INVALID 0x0 +#define BDADDR_SIZE 6 + +#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020) +#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000) +#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0) + +// Scanning and Connection Params used by Central for creating connection +#define GAP_OBSERVATION_PROC (0x80) + +#define SCAN_P (0x0010) +#define SCAN_L (0x0010) +#define SUPERV_TIMEOUT (0xC80) +#define CONN_P(x) ((int)((x)/1.25f)) +#define CONN_L(x) ((int)((x)/0.625f)) +#define CONN_P1 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_P2 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_L1 (0x0008) +#define CONN_L2 (0x0008) +#define GUARD_INT 5 //msec +#define MIN_INT_CONN 0x0006 //=>7.5msec +#define MAX_INT_CONN 0x0C80 //=>4000msec +#define DEF_INT_CONN 0x0140 //=>400msec (default value for connection interval) + +/**************************************************************************/ +/*! + \brief + +*/ +/**************************************************************************/ +class BlueNRGGap : public Gap +{ +public: + static BlueNRGGap &getInstance() { + static BlueNRGGap m_instance; + return m_instance; + } + + enum Reason_t { + DEVICE_FOUND, + DISCOVERY_COMPLETE + }; + + /* Functions that must be implemented from Gap */ + virtual ble_error_t setAddress(addr_type_t type, const BLEProtocol::AddressBytes_t address); + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address); + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &); + virtual ble_error_t startAdvertising(const GapAdvertisingParams &); + virtual ble_error_t stopAdvertising(void); + virtual ble_error_t stopScan(); + virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);} + virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);} + virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);} + virtual ble_error_t disconnect(DisconnectionReason_t reason); + virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason); + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params); + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); + + virtual ble_error_t setDeviceName(const uint8_t *deviceName); + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); + virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance); + virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP); + + virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode); + virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode); + virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const; + virtual ScanningPolicyMode_t getScanningPolicyMode(void) const; + + virtual ble_error_t setTxPower(int8_t txPower); + virtual void getPermittedTxPowerValues(const int8_t **, size_t *); + + virtual ble_error_t connect(const Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams); + + virtual ble_error_t reset(void); + + void Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI); + ble_error_t createConnection(void); + + void setConnectionHandle(uint16_t con_handle); + uint16_t getConnectionHandle(void); + + bool getIsSetAddress(); + + // ADV timeout handling + Timeout& getAdvTimeout(void) { + return advTimeout; + } + uint8_t getAdvToFlag(void) { + return AdvToFlag; + } + void setAdvToFlag(void); + + // SCAN timeout handling + Timeout& getScanTimeout(void) { + return scanTimeout; + } + uint8_t getScanToFlag(void) { + return ScanToFlag; + } + void setScanToFlag(void); + + void Process(void); + + GapScanningParams* getScanningParams(void); + + virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams); + + void setConnectionInterval(uint16_t interval); + Gap::Role_t getGapRole(void); + void setGapRole(Gap::Role_t role); + +private: + uint16_t m_connectionHandle; + Role_t gapRole; + AddressType_t addr_type; + Address_t _peerAddr; + AddressType_t _peerAddrType; + uint8_t bdaddr[BDADDR_SIZE]; + bool _scanning; + bool _connecting; + bool isSetAddress; + uint8_t deviceAppearance[2]; + + // ADV timeout handling + Timeout advTimeout; + bool AdvToFlag; + + // SCAN timeout handling + Timeout scanTimeout; + bool ScanToFlag; + + static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) { + return (duration * 625) / 1000; + } + + uint16_t scanInterval; + uint16_t scanWindow; + uint16_t advInterval; + uint16_t slaveConnIntervMin; + uint16_t slaveConnIntervMax; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + void setAdvParameters(void); + void setConnectionParameters(void); + + Gap::AdvertisingPolicyMode_t advertisingPolicyMode; + Gap::ScanningPolicyMode_t scanningPolicyMode; + + Whitelist_t whitelistAddresses; + + ble_error_t updateAdvertisingData(void); + + BlueNRGGap() : AdvToFlag(false), ScanToFlag(false) { + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + addr_type = BLEProtocol::AddressType::RANDOM_STATIC; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + isSetAddress = false; + memset(deviceAppearance, 0, sizeof(deviceAppearance)); + } + + BlueNRGGap(BlueNRGGap const &); + void operator=(BlueNRGGap const &); + + GapAdvertisingData _advData; + GapAdvertisingData _scanResponse; +}; + +#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,157 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattClient.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CLIENT_H__ +#define __BLUENRG_GATT_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattConnectionClient.h" + +using namespace std; + +#define MAX_ACTIVE_CONNECTIONS 7 + +class BlueNRGGattClient : public GattClient +{ +public: + static BlueNRGGattClient &getInstance() { + static BlueNRGGattClient m_instance; + return m_instance; + } + + ble_error_t createGattConnectionClient(Gap::Handle_t connectionHandle); + ble_error_t removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason); + + /* Functions that must be implemented from GattClient */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + virtual bool isServiceDiscoveryActive(void) const; + virtual void terminateServiceDiscovery(void); + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback); + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + virtual ble_error_t write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + virtual ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + virtual ble_error_t reset(void); + + void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code); + + void primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(Gap::Handle_t connectionHandle); + + void serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length); + + +protected: + + BlueNRGGattClient(): _connectionPool() {}; + + ServiceDiscovery::TerminationCallback_t terminationCallback; + +private: + + BlueNRGGattClient(BlueNRGGattClient const &); + void operator=(BlueNRGGattClient const &); + + BlueNRGGattConnectionClient *_connectionPool[MAX_ACTIVE_CONNECTIONS]; + uint8_t _numConnections; + + BlueNRGGattConnectionClient * getGattConnectionClient(Gap::Handle_t connectionHandle); + +}; + +#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,185 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattConnectionClient.cpp + * @author STMicroelectronics + * @brief Header file for BlueNRGGattConnectionClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CONNECTION_CLIENT_H__ +#define __BLUENRG_GATT_CONNECTION_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" + +using namespace std; + +#define BLE_TOTAL_DISCOVERED_SERVICES 10 +#define BLE_TOTAL_DISCOVERED_CHARS 10 + +class BlueNRGGattConnectionClient +{ +public: + + enum { + GATT_IDLE, + GATT_SERVICE_DISCOVERY, + GATT_CHAR_DESC_DISCOVERY, + //GATT_CHARS_DISCOVERY_COMPLETE, + //GATT_DISCOVERY_TERMINATED, + GATT_READ_CHAR, + GATT_WRITE_CHAR + }; + + /* Functions that must be implemented from GattClient */ + ble_error_t launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + bool isServiceDiscoveryActive(void) const; + void terminateServiceDiscovery(void); + void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + } + ble_error_t read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + ble_error_t write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + ble_error_t reset(void); + + void gattProcedureCompleteCB(uint8_t error_code); + + void primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(void); + + void serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(uint8_t event_data_length); + +protected: + + BlueNRGGattConnectionClient(BlueNRGGattClient *gattClient, Gap::Handle_t connectionHandle): + discoveredService(), + discoveredChar(), + readCBParams(), + writeCBParams(), + _characteristic() { + + //PRINTF("BlueNRGGattConnectionClient construtor: connHandle=%d\n\r", connectionHandle); + + _gattClient = gattClient; + _connectionHandle = connectionHandle; + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + } + + ServiceDiscovery::ServiceCallback_t serviceDiscoveryCallback; + ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback; + ServiceDiscovery::TerminationCallback_t terminationCallback; + CharacteristicDescriptorDiscovery::DiscoveryCallback_t charDescDiscoveryCallback; + CharacteristicDescriptorDiscovery::TerminationCallback_t charDescTerminationCallback; + +private: + + BlueNRGGattConnectionClient(BlueNRGGattConnectionClient const &); + void operator=(BlueNRGGattConnectionClient const &); + ~BlueNRGGattConnectionClient() {}; + + BlueNRGGattClient *_gattClient; + + Gap::Handle_t _connectionHandle; + DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES]; + BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS]; + + GattReadCallbackParams readCBParams; + GattWriteCallbackParams writeCBParams; + + // The char for which the descriptor discovery has been launched + DiscoveredCharacteristic _characteristic; + + UUID _matchingServiceUUID; + UUID _matchingCharacteristicUUIDIn; + uint8_t _currentState; + uint8_t _numServices, _servIndex; + uint8_t _numChars; + uint8_t _numCharDesc; + + friend class BlueNRGGattClient; +}; + +#endif /* __BLUENRG_GATT_CONNECTION_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_SERVER_H__ +#define __BLUENRG_GATT_SERVER_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattService.h" +#include "ble/GattServer.h" +#include <vector> +#include <map> + +#define BLE_TOTAL_CHARACTERISTICS 10 + +using namespace std; + +class BlueNRGGattServer : public GattServer +{ +public: + static BlueNRGGattServer &getInstance() { + static BlueNRGGattServer m_instance; + return m_instance; + } + + enum HandleEnum_t { + CHAR_HANDLE = 0, + CHAR_VALUE_HANDLE, + CHAR_DESC_HANDLE + }; + + /* Functions that must be implemented from GattServer */ + virtual ble_error_t addService(GattService &); + virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t initializeGATTDatabase(void); + + virtual bool isOnDataReadAvailable() const { + return true; + } + + virtual ble_error_t reset(void); + + /* BlueNRG Functions */ + void eventCallback(void); + //void hwCallback(void *pckt); + ble_error_t Read_Request_CB(uint16_t attributeHandle); + uint8_t Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, + uint8_t data_length, const uint8_t* data + ); + GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle); + void HCIDataWrittenEvent(const GattWriteCallbackParams *params); + void HCIDataReadEvent(const GattReadCallbackParams *params); + void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle); + void HCIDataSentEvent(unsigned count); + +private: + + // compute the number of attribute record needed by a service + static uint16_t computeAttributesRecord(GattService& service); + + + static const int MAX_SERVICE_COUNT = 10; + uint8_t serviceCount; + uint8_t characteristicCount; + uint16_t servHandle, charHandle; + + std::map<uint16_t, uint16_t> bleCharHandleMap; // 1st argument is characteristic, 2nd argument is service + GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS]; + uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS]; + + BlueNRGGattServer() { + serviceCount = 0; + characteristicCount = 0; + }; + + BlueNRGGattServer(BlueNRGGattServer const &); + void operator=(BlueNRGGattServer const &); + + static const int CHAR_DESC_TYPE_16_BIT=0x01; + static const int CHAR_DESC_TYPE_128_BIT=0x02; + static const int CHAR_DESC_SECURITY_PERMISSION=0x00; + static const int CHAR_DESC_ACCESS_PERMISSION=0x03; + static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_CLOCK_H__ +#define __BLE_CLOCK_H__ + +#include <ble_hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __BLE_CLOCK_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file ble_debug.h + * @author CL + * @version V1.0.0 + * @date 04-July-2014 + * @brief This file defines print functions for debug purposes. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLE_DEBUG_H +#define __BLE_DEBUG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> + +/* Exported macro ------------------------------------------------------------*/ +//#define DEBUG +#ifdef DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Print the data travelling over the SPI in the .csv format for the GUI*/ +//#define PRINT_CSV_FORMAT +#ifdef PRINT_CSV_FORMAT +#include <stdio.h> +#define PRINT_CSV(...) printf(__VA_ARGS__) +#else +#define PRINT_CSV(...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __BLE_DEBUG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_gp_timer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : General purpose timer library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_GP_TIMER_H__ +#define __BLE_GP_TIMER_H__ + +#include "ble_clock.h" +#include "ble_status.h" +#ifdef __DMA_LP__ +#include "stm32xx_timerserver.h" +#endif /* __DMA_LP__ */ + +/** + * timer + * + * A structure that represents a timer. Use Timer_Set() to set the timer. + * + */ +struct timer { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + tClockTime start; + tClockTime interval; + +#endif +}; + +typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); + +/** + * Timer_Set + * + * @param[in] t Pointer to a timer structure + * @param[in] interval timeout value + * + * This function sets the timeout value of a timer. + * + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * Timer_Reset + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the time it previously expired. + * + */ +void Timer_Reset(struct timer *t); + +/** + * Timer_Restart + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the current time. + * + */ +void Timer_Restart(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns TRUE if timer is expired, FALSE otherwise. + * + */ +int Timer_Expired(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns the time needed for expiration. + * + * @return Time before timer's expiration. + */ +tClockTime Timer_Remaining(struct timer *t); + +#ifdef __DMA_LP__ +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID); + +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); +#endif /* __DMA_LP__ */ + +#endif /* __BLE_GP_TIMER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,108 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_H__ +#define __BLE_HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void signalEventsToProcess(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __BLE_HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_TYPES_H__ +#define __BLE_HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __BLE_HAL_TYPES_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,126 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.0, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_H_ +#define __BLE_HCI_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ble_hal_types.h" +#include "ble_link_layer.h" +#include <ble_list.h> + +#define HCI_READ_PACKET_SIZE 128 //71 + +/** + * Maximum payload of HCI commands that can be sent. Change this value if needed. + * This value can be up to 255. + */ +#define HCI_MAX_PAYLOAD_SIZE 128 + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_READ_PACKET_SIZE]; + uint8_t data_len; +} tHciDataPacket; + +struct hci_request { + uint16_t ogf; + uint16_t ocf; + int event; + void *cparam; + int clen; + void *rparam; + int rlen; +}; + +typedef enum +{ + BUSY, + AVAILABLE +} HCI_CMD_STATUS_t; + + +/** + * This function must be used to pass the packet received from the HCI + * interface to the BLE Stack HCI state machine. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * + */ +void HCI_Input(tHciDataPacket *hciReadPacket); + +/** + * Initialization function. Must be done before any data can be received from + * BLE controller. + */ +void HCI_Init(void); + +/** + * Callback used to pass events to application. + * + * @param[in] pckt The event. + * + */ +extern void HCI_Event_CB(void *pckt); + +/** + * Processing function that must be called after an event is received from + * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if + * necessary. +*/ +void HCI_Process(void); + +/** + * @brief Check if queue of HCI event is empty or not. + * @note This funtion can be used to check if the event queue from BlueNRG is empty. This + * is useful when checking if it is safe to go to sleep. + * @return TRUE if event queue is empty. FALSE otherwhise. + */ +BOOL HCI_Queue_Empty(void); +/** + * Iterrupt service routine that must be called when the BlueNRG + * reports a packet received or an event to the host through the + * BlueNRG interrupt line. + */ +#ifdef __DMA_LP__ +void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); +void HCI_Process_Notification_Request(void); +void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); +void HCI_Wait_For_Response(void); +#else +void HCI_Isr(void); +void HCI_HandleSPI(void); + +int hci_send_req(struct hci_request *r, BOOL async); +#endif /* __DMA_LP__ */ + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#ifdef __cplusplus +} +#endif + + +#endif /* __BLE_HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,548 @@ +/****************************************************************************** +* +* File Description +* --------------------- +* This file defines constants and functions for HCI layer. +* See Bluetooth Core v 4.0, Vol. 2, Part E. +* +*******************************************************************************/ + +#ifndef __HCI_INTERNAL_H_ +#define __HCI_INTERNAL_H_ + +#include "ble_compiler.h" +#include "ble_hal_types.h" +#include "ble_clock.h" +#include "ble_link_layer.h" +#include "ble_hci.h" + +#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) + + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +typedef __packed struct _hci_uart_pckt{ + uint8_t type; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef __packed struct _hci_command_hdr{ + uint16_t opcode; /* OCF & OGF */ + uint8_t plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef __packed struct _hci_event_pckt{ + uint8_t evt; + uint8_t plen; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef __packed struct _hci_acl_hdr{ + uint16_t handle; /* Handle & Flags(PB, BC) */ + uint16_t dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef __packed struct _disconnect_cp{ + uint16_t handle; + uint8_t reason; +} PACKED disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 + +#define OCF_SET_EVENT_MASK 0x0001 +#define OCF_RESET 0x0003 + +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D +typedef __packed struct _read_transmit_power_level_cp{ + uint16_t handle; + uint8_t type; +} PACKED read_transmit_power_level_cp; +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 +typedef __packed struct _read_transmit_power_level_rp{ + uint8_t status; + uint16_t handle; + int8_t level; +} PACKED read_transmit_power_level_rp; +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 + +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 +#define OCF_HOST_BUFFER_SIZE 0x0033 +#define OCF_HOST_NUM_COMP_PKTS 0x0035 + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef __packed struct _read_local_version_rp{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t manufacturer_name; + uint16_t lmp_pal_subversion; +} PACKED read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_COMMANDS 0x0002 +#define OCF_READ_LOCAL_FEATURES 0x0003 + +#define OCF_READ_BD_ADDR 0x0009 +typedef __packed struct _read_bd_addr_rp{ + uint8_t status; + tBDAddr bdaddr; +} PACKED read_bd_addr_rp; +#define READ_BD_ADDR_RP_SIZE 7 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +#define OCF_READ_RSSI 0x0005 +typedef __packed struct _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef __packed struct _read_rssi_rp{ + uint8_t status; + uint16_t handle; + int8_t rssi; +} PACKED read_rssi_rp; +#define READ_RSSI_RP_SIZE 4 + + +/* LE commands */ +#define OGF_LE_CTL 0x08 + +#define OCF_LE_SET_EVENT_MASK 0x0001 +typedef __packed struct _le_set_event_mask_cp{ + uint8_t mask[8]; +} PACKED le_set_event_mask_cp; +#define LE_SET_EVENT_MASK_CP_SIZE 8 + +#define OCF_LE_READ_BUFFER_SIZE 0x0002 +typedef __packed struct _le_read_buffer_size_rp{ + uint8_t status; + uint16_t pkt_len; + uint8_t max_pkt; +} PACKED le_read_buffer_size_rp; +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 + +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 +typedef __packed struct _le_read_local_supported_features_rp{ + uint8_t status; + uint8_t features[8]; +} PACKED le_read_local_supported_features_rp; +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 + +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 +typedef __packed struct _le_set_random_address_cp{ + tBDAddr bdaddr; +} PACKED le_set_random_address_cp; +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 + +#define OCF_LE_SET_ADV_PARAMETERS 0x0006 +typedef __packed struct _le_set_adv_parameters_cp{ + uint16_t min_interval; + uint16_t max_interval; + uint8_t advtype; + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint8_t chan_map; + uint8_t filter; +} PACKED le_set_adv_parameters_cp; +#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 + +#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 +typedef __packed struct _le_read_adv_channel_tx_power_rp{ + uint8_t status; + int8_t level; +} PACKED le_read_adv_channel_tx_power_rp; +#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 + +#define OCF_LE_SET_ADV_DATA 0x0008 +typedef __packed struct _le_set_adv_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_adv_data_cp; +#define LE_SET_ADV_DATA_CP_SIZE 32 + +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 +typedef __packed struct _le_set_scan_response_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_scan_response_data_cp; +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 + +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A +typedef __packed struct _le_set_advertise_enable_cp{ + uint8_t enable; +} PACKED le_set_advertise_enable_cp; +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 + +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B +typedef __packed struct _le_set_scan_parameters_cp{ + uint8_t type; + uint16_t interval; + uint16_t window; + uint8_t own_bdaddr_type; + uint8_t filter; +} PACKED le_set_scan_parameters_cp; +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 + +#define OCF_LE_SET_SCAN_ENABLE 0x000C +typedef __packed struct _le_set_scan_enable_cp{ + uint8_t enable; + uint8_t filter_dup; +} PACKED le_set_scan_enable_cp; +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 + +#define OCF_LE_CREATE_CONN 0x000D +typedef __packed struct _le_create_connection_cp{ + uint16_t interval; + uint16_t window; + uint8_t initiator_filter; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_create_connection_cp; +#define LE_CREATE_CONN_CP_SIZE 25 + +#define OCF_LE_CREATE_CONN_CANCEL 0x000E + +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F +typedef __packed struct _le_read_white_list_size_rp{ + uint8_t status; + uint8_t size; +} PACKED le_read_white_list_size_rp; +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 + +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 +typedef __packed struct _le_add_device_to_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_add_device_to_white_list_cp; +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 +typedef __packed struct _le_remove_device_from_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_remove_device_from_white_list_cp; +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_CONN_UPDATE 0x0013 +typedef __packed struct _le_connection_update_cp{ + uint16_t handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_connection_update_cp; +#define LE_CONN_UPDATE_CP_SIZE 14 + +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 +typedef __packed struct _le_set_host_channel_classification_cp{ + uint8_t map[5]; +} PACKED le_set_host_channel_classification_cp; +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 + +#define OCF_LE_READ_CHANNEL_MAP 0x0015 +typedef __packed struct _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef __packed struct _le_read_channel_map_rp{ + uint8_t status; + uint16_t handle; + uint8_t map[5]; +} PACKED le_read_channel_map_rp; +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 + +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 +typedef __packed struct _le_read_remote_used_features_cp{ + uint16_t handle; +} PACKED le_read_remote_used_features_cp; +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 + +#define OCF_LE_ENCRYPT 0x0017 +typedef __packed struct _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef __packed struct _le_encrypt_rp{ + uint8_t status; + uint8_t encdata[16]; +} PACKED le_encrypt_rp; +#define LE_ENCRYPT_RP_SIZE 17 + +#define OCF_LE_RAND 0x0018 +typedef __packed struct _le_rand_rp{ + uint8_t status; + uint8_t random[8]; +} PACKED le_rand_rp; +#define LE_RAND_RP_SIZE 9 + +#define OCF_LE_START_ENCRYPTION 0x0019 +typedef __packed struct _le_start_encryption_cp{ + uint16_t handle; + uint8_t random[8]; + uint16_t diversifier; + uint8_t key[16]; +} PACKED le_start_encryption_cp; +#define LE_START_ENCRYPTION_CP_SIZE 28 + +#define OCF_LE_LTK_REPLY 0x001A +typedef __packed struct _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef __packed struct _le_ltk_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_reply_rp; +#define LE_LTK_REPLY_RP_SIZE 3 + +#define OCF_LE_LTK_NEG_REPLY 0x001B +typedef __packed struct _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef __packed struct _le_ltk_neg_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_neg_reply_rp; +#define LE_LTK_NEG_REPLY_RP_SIZE 3 + +#define OCF_LE_READ_SUPPORTED_STATES 0x001C +typedef __packed struct _le_read_supported_states_rp{ + uint8_t status; + uint8_t states[8]; +} PACKED le_read_supported_states_rp; +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 + +#define OCF_LE_RECEIVER_TEST 0x001D +typedef __packed struct _le_receiver_test_cp{ + uint8_t frequency; +} PACKED le_receiver_test_cp; +#define LE_RECEIVER_TEST_CP_SIZE 1 + +#define OCF_LE_TRANSMITTER_TEST 0x001E +typedef __packed struct _le_transmitter_test_cp{ + uint8_t frequency; + uint8_t length; + uint8_t payload; +} PACKED le_transmitter_test_cp; +#define LE_TRANSMITTER_TEST_CP_SIZE 3 + +#define OCF_LE_TEST_END 0x001F +typedef __packed struct _le_test_end_rp{ + uint8_t status; + uint16_t num_pkts; +} PACKED le_test_end_rp; +#define LE_TEST_END_RP_SIZE 3 + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3f + + +/*------------- Events -------------*/ +#define EVT_CONN_COMPLETE 0x03 +typedef __packed struct _evt_conn_complete{ + uint8_t status; + uint16_t handle; + tBDAddr bdaddr; + uint8_t link_type; + uint8_t encr_mode; +} PACKED evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef __packed struct _evt_disconn_complete{ + uint8_t status; + uint16_t handle; + uint8_t reason; +} PACKED evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef __packed struct _evt_encrypt_change{ + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} PACKED evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C + +#define EVT_CMD_COMPLETE 0x0E +typedef __packed struct _evt_cmd_complete{ + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef __packed struct _evt_cmd_status{ + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef __packed struct _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef __packed struct _evt_num_comp_pkts{ + uint8_t num_hndl; + /* variable length part */ +} PACKED evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +/* variable length part of evt_num_comp_pkts. */ +typedef __packed struct _evt_num_comp_pkts_param{ + uint16_t hndl; + uint16_t num_comp_pkts; +} PACKED evt_num_comp_pkts_param; +#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 + +#define EVT_DATA_BUFFER_OVERFLOW 0x1A +typedef __packed struct _evt_data_buffer_overflow{ + uint8_t link_type; +} PACKED evt_data_buffer_overflow; +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 + +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef __packed struct _evt_encryption_key_refresh_complete{ + uint8_t status; + uint16_t handle; +} PACKED evt_encryption_key_refresh_complete; +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 + +#define EVT_LE_META_EVENT 0x3E +typedef __packed struct _evt_le_meta_event{ + uint8_t subevent; + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef __packed struct _evt_le_connection_complete{ + uint8_t status; + uint16_t handle; + uint8_t role; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; +} PACKED evt_le_connection_complete; +#define EVT_LE_CONN_COMPLETE_SIZE 18 + +#define EVT_LE_ADVERTISING_REPORT 0x02 +typedef __packed struct _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t data_length; + uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef __packed struct _evt_le_connection_update_complete{ + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; +} PACKED evt_le_connection_update_complete; +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 + +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +typedef __packed struct _evt_le_read_remote_used_features_complete{ + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} PACKED evt_le_read_remote_used_features_complete; +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 + +#define EVT_LE_LTK_REQUEST 0x05 +typedef __packed struct _evt_le_long_term_key_request{ + uint16_t handle; + uint8_t random[8]; + uint16_t ediv; +} PACKED evt_le_long_term_key_request; +#define EVT_LE_LTK_REQUEST_SIZE 12 + +/** +* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, +* application can use @ref evt_blue_aci structure to parse the packet. +*/ +#define EVT_VENDOR 0xFF + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + + + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); + +typedef enum { + WAITING_TYPE, + WAITING_OPCODE1, + WAITING_OPCODE2, + WAITING_EVENT_CODE, + WAITING_HANDLE, + WAITING_HANDLE_FLAG, + WAITING_PARAM_LEN, + WAITING_DATA_LEN1, + WAITING_DATA_LEN2, + WAITING_PAYLOAD +}hci_state; + +typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); + +/* HCI library functions. */ + +int hci_send_req(struct hci_request *r, BOOL async); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,170 @@ +/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +* File Name : ble_hci_le.h +* Author : AMG RF FW team +* Version : V1.1.0 +* Date : 18-July-2016 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.1, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_LE_H_ +#define __BLE_HCI_LE_H_ + +#include "ble_hal_types.h" +#include "ble_link_layer.h" + +/** + * @defgroup HCI_Error_codes HCI Error codes + * @{ + */ +#define HCI_UNKNOWN_COMMAND 0x01 +#define HCI_NO_CONNECTION 0x02 +#define HCI_HARDWARE_FAILURE 0x03 +#define HCI_PAGE_TIMEOUT 0x04 +#define HCI_AUTHENTICATION_FAILURE 0x05 +#define HCI_PIN_OR_KEY_MISSING 0x06 +#define HCI_MEMORY_FULL 0x07 +#define HCI_CONNECTION_TIMEOUT 0x08 +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a +#define HCI_ACL_CONNECTION_EXISTS 0x0b +#define HCI_COMMAND_DISALLOWED 0x0c +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d +#define HCI_REJECTED_SECURITY 0x0e +#define HCI_REJECTED_PERSONAL 0x0f +#define HCI_HOST_TIMEOUT 0x10 +#define HCI_UNSUPPORTED_FEATURE 0x11 +#define HCI_INVALID_PARAMETERS 0x12 +#define HCI_OE_USER_ENDED_CONNECTION 0x13 +#define HCI_OE_LOW_RESOURCES 0x14 +#define HCI_OE_POWER_OFF 0x15 +#define HCI_CONNECTION_TERMINATED 0x16 +#define HCI_REPEATED_ATTEMPTS 0x17 +#define HCI_PAIRING_NOT_ALLOWED 0x18 +#define HCI_UNKNOWN_LMP_PDU 0x19 +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a +#define HCI_SCO_OFFSET_REJECTED 0x1b +#define HCI_SCO_INTERVAL_REJECTED 0x1c +#define HCI_AIR_MODE_REJECTED 0x1d +#define HCI_INVALID_LMP_PARAMETERS 0x1e +#define HCI_UNSPECIFIED_ERROR 0x1f +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 +#define HCI_UNIT_LINK_KEY_USED 0x26 +#define HCI_QOS_NOT_SUPPORTED 0x27 +#define HCI_INSTANT_PASSED 0x28 +#define HCI_PAIRING_NOT_SUPPORTED 0x29 +#define HCI_TRANSACTION_COLLISION 0x2a +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c +#define HCI_QOS_REJECTED 0x2d +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e +#define HCI_INSUFFICIENT_SECURITY 0x2f +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 +#define HCI_ROLE_SWITCH_PENDING 0x32 +#define HCI_SLOT_VIOLATION 0x34 +#define HCI_ROLE_SWITCH_FAILED 0x35 +#define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 +#define HCI_CONN_REJ_NO_CH_FOUND 0x39 +#define HCI_CONTROLLER_BUSY 0x3A +#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B +#define HCI_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_CONN_TERM_MIC_FAIL 0x3D +#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E +#define HCI_MAC_CONN_FAILED 0x3F +/** + * @} + */ + + +/* + * HCI library functions. + * Each function returns 0 in case of success, otherwise one of the error codes. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(uint8_t enable); + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter); + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter); + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); + +int hci_le_rand(uint8_t random_number[8]); + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); + +int hci_acl_data(const uint8_t * data, uint16_t len); + +int hci_le_set_random_address(tBDAddr bdaddr); + +int hci_read_bd_addr(tBDAddr bdaddr); + +int hci_le_read_white_list_size(uint8_t *size); + +int hci_le_clear_white_list(); + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); + +int hci_le_ltk_request_reply(uint8_t key[16]); + +int hci_le_ltk_request_neg_reply(); + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); + +int hci_le_create_connection_cancel(void); + +int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level); + +int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi); + +int hci_le_read_local_supported_features(uint8_t *features); + +int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); + +int hci_le_read_supported_states(uint8_t states[8]); + +int hci_le_receiver_test(uint8_t frequency); + +int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); + +int hci_le_test_end(uint16_t *num_pkts); + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion); + + + +#endif /* __BLE_HCI_LE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,161 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_link_layer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's link layer. It contains +* definition of functions for link layer, most of which are +* mapped to HCI commands. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef _BLE_LINK_LAYER_H +#define _BLE_LINK_LAYER_H + +#include <ble_status.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + *@name Advertising filter + *Advertising policy for filtering (white list related) + *@{ + */ +#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ +#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ +/** + * @} + */ + + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef uint8_t tBDAddr[6]; + + +/** + *@name Bluetooth address types + * Bluetooth address types + *@{ + */ +#define PUBLIC_ADDR (0) +#define RANDOM_ADDR (1) +#define STATIC_RANDOM_ADDR (1) +#define RESOLVABLE_PRIVATE_ADDR (2) +#define NON_RESOLVABLE_PRIVATE_ADDR (3) +/** + * @} + */ + +/** + *@name Directed advertising types + * Type of advertising during directed advertising + *@{ + */ +#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) +#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) +/** + * @} + */ + +/** + * @name Advertising type + * @{ + */ + +/** + * undirected scannable and connectable + */ +#define ADV_IND (0x00) + +/** + * directed non scannable + */ +#define ADV_DIRECT_IND (0x01) + +/** + * scannable non connectable + */ +#define ADV_SCAN_IND (0x02) + +/** + * non-connectable and no scan response + */ +#define ADV_NONCONN_IND (0x03) + +/** + * scan response + */ +#define SCAN_RSP (0x04) + +/** + * @} + */ + +/* 0X05-0XFF RESERVED */ + +/** + * @name Advertising ranges + * @{ + */ + +/** + * lowest allowed interval value for connectable types(20ms)..multiple of 625us + */ +#define ADV_INTERVAL_LOWEST_CONN (0X0020) + +/** + * highest allowed interval value (10.24s)..multiple of 625us. + */ +#define ADV_INTERVAL_HIGHEST (0X4000) + +/** + * lowest allowed interval value for non connectable types + * (100ms)..multiple of 625us. + */ +#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) + +/** + * @} + */ + +/** + * @name Advertising channels + * @{ + */ +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 +/** + * @} + */ + +/** + * @name Scan_types Scan types + * @{ + */ +#define PASSIVE_SCAN 0 +#define ACTIVE_SCAN 1 +/** + * @} + */ + +/** + * @} + */ + + +#endif /* _BLE_LINK_LAYER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,47 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for linked list library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef _BLE_LIST_H_ +#define _BLE_LIST_H_ + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +uint8_t list_is_empty (tListNode * listHead); + +void list_insert_head (tListNode * listHead, tListNode * node); + +void list_insert_tail (tListNode * listHead, tListNode * node); + +void list_remove_node (tListNode * node); + +void list_remove_head (tListNode * listHead, tListNode ** node ); + +void list_remove_tail (tListNode * listHead, tListNode ** node ); + +void list_insert_node_after (tListNode * node, tListNode * ref_node); + +void list_insert_node_before (tListNode * node, tListNode * ref_node); + +int list_get_size (tListNode * listHead); + +void list_get_next_node (tListNode * ref_node, tListNode ** node); + +void list_get_prev_node (tListNode * ref_node, tListNode ** node); + +#endif /* _BLE_LIST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_OSAL_H__ +#define __BLE_OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __BLE_OSAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,158 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_sm.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's security manager. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_SM_H__ +#define __BLE_SM_H__ + +/****************************************************************************** +* Macros +*****************************************************************************/ + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/* IO capabilities */ +/** + * @anchor IO_capabilities + * @name IO capabilities + * @{ + */ +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define IO_CAP_KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) +/** + * @} + */ + +/** + * @anchor Auth_req + * @name Authentication requirements + * @{ + */ +#define BONDING (0x01) +#define NO_BONDING (0x00) +/** + * @} + */ + +/** + * @anchor MITM_req + * @name MITM protection requirements + * @{ + */ +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor OOB_Data + * @name Out-Of-Band data + * @{ + */ +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) +/** + * @} + */ + +/** + * @anchor Author_req + * @name Authorization requirements + * @{ + */ +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor Conn_authorization + * @name Connection authorization + * @{ + */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) +/** + * @} + */ + +/** + * @anchor Use_fixed_pin + * @name Use fixed pin + * @{ + */ +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +/** + * @} + */ + +/** + * @anchor link_security_status + * @name Link security status + * @{ + */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) +/** + * @} + */ + +/** + * @anchor SMP_pairing_failed_codes + * @name SMP pairing failed reason codes + * @{ + */ +#define PASSKEY_ENTRY_FAILED (0x01) +#define OOB_NOT_AVAILABLE (0x02) +#define AUTH_REQ_CANNOT_BE_MET (0x03) +#define CONFIRM_VALUE_FAILED (0x04) +#define PAIRING_NOT_SUPPORTED (0x05) +#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) +#define CMD_NOT_SUPPORTED (0x07) +#define UNSPECIFIED_REASON (0x08) +#define VERY_EARLY_NEXT_ATTEMPT (0x09) +#define SM_INVALID_PARAMS (0x0A) +/** + * @} + */ + +/** + * @anchor pairing_failed_codes + * @name Pairing failed error codes + * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event + * @{ + */ +#define SM_PAIRING_SUCCESS (0x00) +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,188 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_status.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file with BLE Stack status codes. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_STATUS_H__ +#define __BLE_STATUS_H__ + +#include <ble_hal_types.h> + +/** @addtogroup Middlewares + * @{ + */ + +/** @defgroup ST + * @{ + */ + +/** @defgroup SimpleBlueNRG_HCI + * @{ + */ + +/** @defgroup ble_status Bluetooth Status/Error Codes + * @{ + */ + +typedef uint8_t tBleStatus; + +/* Error Codes as specified by the specification + * according to the spec the error codes range + * from 0x00 to 0x3F + */ +/** + * @name Standard error codes + * @brief Standard error codes. See Core v 4.1, Vol. 2, part D. + * @{ + */ +#define ERR_CMD_SUCCESS (0x00) +#define BLE_STATUS_SUCCESS (0x00) +#define ERR_UNKNOWN_HCI_COMMAND (0x01) +#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) + +#define ERR_AUTH_FAILURE (0x05) +#define ERR_PIN_OR_KEY_MISSING (0x06) +#define ERR_MEM_CAPACITY_EXCEEDED (0x07) +#define ERR_CONNECTION_TIMEOUT (0x08) + +#define ERR_COMMAND_DISALLOWED (0x0C) + +#define ERR_UNSUPPORTED_FEATURE (0x11) +#define ERR_INVALID_HCI_CMD_PARAMS (0x12) +#define ERR_RMT_USR_TERM_CONN (0x13) +#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) +#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) +#define ERR_LOCAL_HOST_TERM_CONN (0x16) + +#define ERR_UNSUPP_RMT_FEATURE (0x1A) + +#define ERR_INVALID_LMP_PARAM (0x1E) +#define ERR_UNSPECIFIED_ERROR (0x1F) + +#define ERR_LL_RESP_TIMEOUT (0x22) +#define ERR_LMP_PDU_NOT_ALLOWED (0x24) + +#define ERR_INSTANT_PASSED (0x28) + +#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) +#define ERR_CONTROLLER_BUSY (0x3A) + +#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) + +#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) + +#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) + + +/** + * @} + */ +/** + * @name Vendor-specific error codes + * @brief Error codes defined by ST related to BlueNRG stack + * @{ + */ +/** + * The command cannot be executed due to the current state of the device. + */ +#define BLE_STATUS_FAILED (0x41) +/** + * Some parameters are invalid. + */ +#define BLE_STATUS_INVALID_PARAMS (0x42) +/** + * It is not allowed to start the procedure (e.g. another the procedure is ongoing + * or cannot be started on the given handle). + */ +#define BLE_STATUS_NOT_ALLOWED (0x46) +/** + * Unexpected error. + */ +#define BLE_STATUS_ERROR (0x47) +#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) + +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +#define BLE_STATUS_INVALID_CID (0x50) + +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) +#define BLE_STATUS_IRK_NOT_FOUND (0x5B) +#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) +#define BLE_STATUS_SEC_DB_FULL (0x5D) +#define BLE_STATUS_DEV_NOT_BONDED (0x5E) +#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) + +#define BLE_STATUS_INVALID_HANDLE (0x60) +#define BLE_STATUS_INVALID_PARAMETER (0x61) +#define BLE_STATUS_OUT_OF_HANDLE (0x62) +#define BLE_STATUS_INVALID_OPERATION (0x63) +#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) +#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) +#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) + +/** + * Returned when no valid slots are available (e.g. when there are no available state machines). + */ +#define BLE_STATUS_NO_VALID_SLOT (0x82) + +/** + * Returned when a scan window shorter than minimum allowed value has been requested (i.e. 2ms) + */ + +#define BLE_STATUS_SCAN_WINDOW_SHORT (0x83) +/** + * Returned when the maximum requested interval to be allocated is shorter then the current + * anchor period and a there is no submultiple for the current anchor period that is between + * the minimum and the maximum requested intervals. + */ + +#define BLE_STATUS_NEW_INTERVAL_FAILED (0x84) +/** + * Returned when the maximum requested interval to be allocated is greater than the current anchor + * period and there is no multiple of the anchor period that is between the minimum and the maximum + * requested intervals. + */ + +#define BLE_STATUS_INTERVAL_TOO_LARGE (0x85) +/** + * Returned when the current anchor period or a new one can be found that is compatible to the + * interval range requested by the new slot but the maximum available length that can be allocated is + * less than the minimum requested slot length. + */ + +#define BLE_STATUS_LENGTH_FAILED (0x86) +/** + * @} + */ + +/** + * @name Library Error Codes + * @brief Error codes defined by ST related to MCU library. + * @{ + */ +#define BLE_STATUS_TIMEOUT (0xFF) +#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) +#define BLE_STATUS_NULL_PARAM (0xF1) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,813 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci_const.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with ACI definitions for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_CONST_H_ +#define __BLUENRG_ACI_CONST_H_ + +#include "ble_compiler.h" +#include "ble_link_layer.h" +#include "ble_hci_const.h" +#include "bluenrg_gatt_server.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define OCF_HAL_GET_FW_BUILD_NUMBER 0x0000 +typedef __packed struct _hal_get_fw_build_number_rp{ + uint8_t status; + uint16_t build_number; +} PACKED hal_get_fw_build_number_rp; +#define HAL_GET_FW_BUILD_NUMBER_RP_SIZE 3 +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +#define OCF_HAL_READ_CONFIG_DATA 0x000D +typedef __packed struct _hal_read_config_data_cp{ + uint8_t offset; +} PACKED hal_read_config_data_cp; +#define HAL_READ_CONFIG_DATA_RP_SIZE 1 +typedef __packed struct _hal_read_config_data_rp{ + uint8_t status; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE]; +} PACKED hal_read_config_data_rp; + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef __packed struct _hal_set_tx_power_level_cp{ + uint8_t en_high_power; + uint8_t pa_level; +} PACKED hal_set_tx_power_level_cp; +#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 + +#define OCF_HAL_DEVICE_STANDBY 0x0013 + +#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014 +typedef __packed struct _hal_le_tx_test_packet_number_rp{ + uint8_t status; + uint32_t number_of_packets; +} PACKED hal_le_tx_test_packet_number_rp; + +#define OCF_HAL_TONE_START 0x0015 +typedef __packed struct _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_HAL_TONE_STOP 0x0016 +#define OCF_HAL_GET_LINK_STATUS 0x0017 +typedef __packed struct _hal_get_link_status_rp{ + uint8_t status; + uint8_t link_status[8]; + uint16_t conn_handle[8]; +} PACKED hal_get_link_status_rp; + +#define OCF_HAL_GET_ANCHOR_PERIOD 0x0019 +typedef __packed struct _hal_get_anchor_period_rp{ + uint8_t status; + uint32_t anchor_period; + uint32_t max_free_slot; +} PACKED hal_get_anchor_period_rp; + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef __packed struct _get_updater_version_rp{ + uint8_t status; + uint8_t version; +} PACKED get_updater_version_rp; +#define GET_UPDATER_VERSION_RP_SIZE 2 + +#define OCF_GET_UPDATER_BUFSIZE 0x0023 +typedef __packed struct _get_updater_bufsize_rp{ + uint8_t status; + uint8_t buffer_size; +} PACKED get_updater_bufsize_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 + +#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 + +#define OCF_UPDATER_ERASE_SECTOR 0x0026 +typedef __packed struct _updater_erase_sector_cp{ + uint32_t address; +} PACKED updater_erase_sector_cp; +#define UPDATER_ERASE_SECTOR_CP_SIZE 4 + +#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 +#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_prog_data_block_cp{ + uint32_t address; + uint16_t data_len; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; +} PACKED updater_prog_data_block_cp; + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef __packed struct _updater_read_data_block_cp{ + uint32_t address; + uint16_t data_len; +} PACKED updater_read_data_block_cp; +#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[VARIABLE_SIZE]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef __packed struct _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef __packed struct _updater_calc_crc_rp{ + uint8_t status; + uint32_t crc; +} PACKED updater_calc_crc_rp; +#define UPDATER_CALC_CRC_RP_SIZE 5 + +#define OCF_UPDATER_HW_VERSION 0x002A +typedef __packed struct _updater_hw_version_rp{ + uint8_t status; + uint8_t version; +} PACKED updater_hw_version_rp; +#define UPDATER_HW_VERSION_RP_SIZE 2 + +#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 + +#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 + +#define OCF_GAP_SET_DISCOVERABLE 0x0083 + +#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 +typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ + uint8_t own_bdaddr_type; + uint8_t directed_adv_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint16_t adv_interv_min; + uint16_t adv_interv_max; +} PACKED gap_set_direct_conectable_cp_IDB05A1; + +typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB04A1; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef __packed struct _gap_set_io_capability_cp{ + uint8_t io_capability; +} PACKED gap_set_io_capability_cp; +#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 + +#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 +typedef __packed struct _gap_set_auth_requirement_cp{ + uint8_t mitm_mode; + uint8_t oob_enable; + uint8_t oob_data[16]; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t bonding_mode; +} PACKED gap_set_auth_requirement_cp; +#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 + +#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 +typedef __packed struct _gap_set_author_requirement_cp{ + uint16_t conn_handle; + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef __packed struct _gap_passkey_response_cp{ + uint16_t conn_handle; + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef __packed struct _gap_authorization_response_cp{ + uint16_t conn_handle; + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 + +#define OCF_GAP_INIT 0x008A +typedef __packed struct _gap_init_cp_IDB05A1{ + uint8_t role; + uint8_t privacy_enabled; + uint8_t device_name_char_len; +} PACKED gap_init_cp_IDB05A1; +#define GAP_INIT_CP_SIZE_IDB05A1 3 + +typedef __packed struct _gap_init_cp_IDB04A1{ + uint8_t role; +} PACKED gap_init_cp_IDB04A1; +#define GAP_INIT_CP_SIZE_IDB04A1 1 +typedef __packed struct _gap_init_rp{ + uint8_t status; + uint16_t service_handle; + uint16_t dev_name_char_handle; + uint16_t appearance_char_handle; +} PACKED gap_init_rp; +#define GAP_INIT_RP_SIZE 7 + +#define OCF_GAP_SET_NON_CONNECTABLE 0x008B +typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ + uint8_t advertising_event_type; + uint8_t own_address_type; +#endif +} PACKED gap_set_non_connectable_cp_IDB05A1; + +typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp_IDB04A1; + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef __packed struct _gap_set_undirected_connectable_cp{ + uint8_t adv_filter_policy; + uint8_t own_addr_type; +} PACKED gap_set_undirected_connectable_cp; +#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 + +#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D +typedef __packed struct _gap_slave_security_request_cp{ + uint16_t conn_handle; + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef __packed struct _gap_delete_ad_type_cp{ + uint8_t ad_type; +} PACKED gap_delete_ad_type_cp; +#define GAP_DELETE_AD_TYPE_CP_SIZE 1 + +#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 +typedef __packed struct _gap_get_security_level_rp{ + uint8_t status; + uint8_t mitm_protection; + uint8_t bonding; + uint8_t oob_data; + uint8_t passkey_required; +} PACKED gap_get_security_level_rp; +#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 + +#define OCF_GAP_SET_EVT_MASK 0x0091 +typedef __packed struct _gap_set_evt_mask_cp{ + uint16_t evt_mask; +} PACKED gap_set_evt_mask_cp; +#define GAP_SET_EVT_MASK_CP_SIZE 2 + +#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 + +#define OCF_GAP_TERMINATE 0x0093 +typedef __packed struct _gap_terminate_cp{ + uint16_t handle; + uint8_t reason; +} PACKED gap_terminate_cp; +#define GAP_TERMINATE_CP_SIZE 3 + +#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 + +#define OCF_GAP_ALLOW_REBOND_DB 0x0095 + +typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ + uint16_t conn_handle; +} PACKED gap_allow_rebond_cp_IDB05A1; + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef __packed struct _gap_start_limited_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_limited_discovery_proc_cp; +#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 +typedef __packed struct _gap_start_general_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_general_discovery_proc_cp; +#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 +typedef __packed struct _gap_start_name_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_name_discovery_proc_cp; +#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 + +#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 + +#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; + +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t use_reconn_addr; + tBDAddr reconn_addr; +} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; + +#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B +#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 +typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t num_whitelist_entries; + uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; +} PACKED gap_start_selective_conn_establish_proc_cp; + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef __packed struct _gap_create_connection_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_create_connection_cp; +#define GAP_CREATE_CONNECTION_CP_SIZE 24 + +#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D + +#define OCF_GAP_START_CONNECTION_UPDATE 0x009E +typedef __packed struct _gap_start_connection_update_cp{ + uint16_t conn_handle; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_connection_update_cp; +#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 + +#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F +typedef __packed struct _gap_send_pairing_request_cp{ + uint16_t conn_handle; + uint8_t force_rebond; +} PACKED gap_send_pairing_request_cp; +#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 + +#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 +typedef __packed struct _gap_resolve_private_address_cp{ + tBDAddr address; +} PACKED gap_resolve_private_address_cp; +#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 +typedef __packed struct _gap_resolve_private_address_rp{ + uint8_t status; + tBDAddr address; +} PACKED gap_resolve_private_address_rp; + +#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 +#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 +typedef __packed struct _gap_set_broadcast_mode_cp{ + uint16_t adv_interv_min; + uint16_t adv_interv_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; +} PACKED gap_set_broadcast_mode_cp; + +#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 +typedef __packed struct _gap_start_observation_proc_cp{ + uint16_t scan_interval; + uint16_t scan_window; + uint8_t scan_type; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_observation_proc_cp; + +#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 +typedef __packed struct _gap_get_bonded_devices_rp{ + uint8_t status; + uint8_t num_addr; + uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; +} PACKED gap_get_bonded_devices_rp; + +#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 +typedef __packed struct _gap_is_device_bonded_cp{ + uint8_t peer_address_type; + tBDAddr peer_address; +} PACKED gap_is_device_bonded_cp; + + +#define OCF_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef __packed struct _gatt_add_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_serv_rp; +#define GATT_ADD_SERV_RP_SIZE 3 + +#define OCF_GATT_INCLUDE_SERV 0x0103 +typedef __packed struct _gatt_include_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_include_serv_rp; +#define GATT_INCLUDE_SERV_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR 0x0104 +typedef __packed struct _gatt_add_char_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_rp; +#define GATT_ADD_CHAR_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR_DESC 0x0105 +typedef __packed struct _gatt_add_char_desc_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_desc_rp; +#define GATT_ADD_CHAR_DESC_RP_SIZE 3 + +#define OCF_GATT_UPD_CHAR_VAL 0x0106 + +#define OCF_GATT_DEL_CHAR 0x0107 +typedef __packed struct _gatt_del_char_cp{ + uint16_t service_handle; + uint16_t char_handle; +} PACKED gatt_del_char_cp; +#define GATT_DEL_CHAR_CP_SIZE 4 + +#define OCF_GATT_DEL_SERV 0x0108 +typedef __packed struct _gatt_del_serv_cp{ + uint16_t service_handle; +} PACKED gatt_del_serv_cp; +#define GATT_DEL_SERV_CP_SIZE 2 + +#define OCF_GATT_DEL_INC_SERV 0x0109 +typedef __packed struct _gatt_del_inc_serv_cp{ + uint16_t service_handle; + uint16_t inc_serv_handle; +} PACKED gatt_del_inc_serv_cp; +#define GATT_DEL_INC_SERV_CP_SIZE 4 + +#define OCF_GATT_SET_EVT_MASK 0x010A +typedef __packed struct _gatt_set_evt_mask_cp{ + uint32_t evt_mask; +} PACKED gatt_set_evt_mask_cp; +#define GATT_SET_EVT_MASK_CP_SIZE 4 + +#define OCF_GATT_EXCHANGE_CONFIG 0x010B +typedef __packed struct _gatt_exchange_config_cp{ + uint16_t conn_handle; +} PACKED gatt_exchange_config_cp; +#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 + +#define OCF_ATT_FIND_INFO_REQ 0x010C +typedef __packed struct _att_find_info_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED att_find_info_req_cp; +#define ATT_FIND_INFO_REQ_CP_SIZE 6 + +#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D +#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 +typedef __packed struct _att_find_by_type_value_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[2]; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU - 7]; +} PACKED att_find_by_type_value_req_cp; + +#define OCF_ATT_READ_BY_TYPE_REQ 0x010E +#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_type_req_cp; + +#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F +#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_group_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_group_type_req_cp; + +#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 +#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val +typedef __packed struct _att_prepare_write_req_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t value_offset; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU-5]; +} PACKED att_prepare_write_req_cp; + +#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 +typedef __packed struct _att_execute_write_req_cp{ + uint16_t conn_handle; + uint8_t execute; +} PACKED att_execute_write_req_cp; +#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 + +#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 +typedef __packed struct _gatt_disc_all_prim_serivces_cp{ + uint16_t conn_handle; +} PACKED gatt_disc_all_prim_services_cp; +#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 + +#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 +typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ + uint16_t conn_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_disc_prim_service_by_uuid_cp; +#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid + +#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 +typedef __packed struct _gatt_disc_find_included_services_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED gatt_find_included_services_cp; +#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 + +#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 +typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ + uint16_t conn_handle; + uint16_t start_attr_handle; + uint16_t end_attr_handle; +} PACKED gatt_disc_all_charac_of_serv_cp; +#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 + +#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 + +#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ + uint16_t conn_handle; + uint16_t char_val_handle; + uint16_t char_end_handle; +} PACKED gatt_disc_all_charac_descriptors_cp; +#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 + +#define OCF_GATT_READ_CHARAC_VAL 0x0118 +typedef __packed struct _gatt_read_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_val_cp; +#define GATT_READ_CHARAC_VAL_CP_SIZE 4 + +#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 +typedef __packed struct _gatt_read_using_charac_uuid_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_read_using_charac_uuid_cp; +#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID + +#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A +typedef __packed struct _gatt_read_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_val_cp; +#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 + +#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B +#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles +typedef __packed struct _gatt_read_multiple_charac_val_cp{ + uint16_t conn_handle; + uint8_t num_handles; + uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_read_multiple_charac_val_cp; + +#define OCF_GATT_WRITE_CHAR_VALUE 0x011C + +#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D +#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_write_long_charac_val_cp; + +#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E +#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_charac_reliable_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; +} PACKED gatt_write_charac_reliable_cp; + +#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F +#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; +} PACKED gatt_write_long_charac_desc_cp; + +#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 +typedef __packed struct _gatt_read_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_desc_cp; +#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 + +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 +typedef __packed struct _gatt_read_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_desc_cp; +#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 +#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 3]; +} PACKED gatt_write_without_resp_cp; + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 +#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_signed_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 13]; +} PACKED gatt_signed_write_without_resp_cp; + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 +typedef __packed struct _gatt_confirm_indication_cp{ + uint16_t conn_handle; +} PACKED gatt_confirm_indication_cp; +#define GATT_CONFIRM_INDICATION_CP_SIZE 2 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef __packed struct _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 +typedef __packed struct _gatt_set_security_permission_cp{ + uint16_t service_handle; + uint16_t attr_handle; + uint8_t security_permission; +} PACKED gatt_set_security_permission_cp; +#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_GATT_READ_HANDLE_VALUE 0x012A +typedef __packed struct _gatt_read_handle_val_cp{ + uint16_t attr_handle; +} PACKED gatt_read_handle_val_cp; +#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 +typedef __packed struct _gatt_read_handle_val_rp{ + uint8_t status; + uint16_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; +} PACKED gatt_read_handle_val_rp; + +#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B +typedef __packed struct _gatt_read_handle_val_offset_cp{ + uint16_t attr_handle; + uint8_t offset; +} PACKED gatt_read_handle_val_offset_cp; +#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 +typedef __packed struct _gatt_read_handle_val_offset_rp{ + uint8_t status; + uint8_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; +} PACKED gatt_read_handle_val_offset_rp; + +#define OCF_GATT_UPD_CHAR_VAL_EXT 0x012C +#define GATT_UPD_CHAR_VAL_EXT_CP_SIZE 10 // without value +typedef __packed struct _gatt_upd_char_val_ext_cp{ + uint16_t service_handle; + uint16_t char_handle; + uint8_t update_type; + uint16_t char_length; + uint16_t value_offset; + uint8_t value_length; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_UPD_CHAR_VAL_EXT_CP_SIZE]; +} PACKED gatt_upd_char_val_ext_cp; + +#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 +typedef __packed struct _l2cap_conn_param_update_req_cp{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_update_req_cp; +#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 + +#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint16_t min_ce_length; + uint16_t max_ce_length; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; + +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; + +/** + * @defgroup BlueNRG_Events BlueNRG events (vendor specific) + * @{ + */ + +/** + * Vendor specific event for BlueNRG. + */ +typedef __packed struct _evt_blue_aci{ + uint16_t ecode; /**< One of the BlueNRG event codes. */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_blue_aci; + + +/** + * @} + */ + +#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gap.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GAP layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BNRG_GAP_H__ +#define __BNRG_GAP_H__ + +#include <ble_link_layer.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + * @name GAP UUIDs + * @{ + */ +#define GAP_SERVICE_UUID (0x1800) +#define DEVICE_NAME_UUID (0x2A00) +#define APPEARANCE_UUID (0x2A01) +#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) +#define RECONNECTION_ADDR_UUID (0x2A03) +#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) +/** + * @} + */ + +/** + * @name Characteristic value lengths + * @{ + */ +#define DEVICE_NAME_CHARACTERISTIC_LEN (8) +#define APPEARANCE_CHARACTERISTIC_LEN (2) +#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) +#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) +#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) +/** + * @} + */ + +/*------------- AD types for adv data and scan response data ----------------*/ + +/** + * @defgroup AD_Types AD Types + * @brief AD Types + * @{ + */ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +/** + * @anchor Flags_AD_Type_bits + * @name Flags AD Type bits + * @brief Bits in Flags AD Type + * @{ + */ +#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) +#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) +#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) +#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) +#define FLAG_BIT_LE_BR_EDR_HOST (0x10) +/** + * @} + */ + +/** + * @name Service UUID AD types + * @{ + */ +#define AD_TYPE_16_BIT_SERV_UUID (0x02) +#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) +#define AD_TYPE_32_BIT_SERV_UUID (0x04) +#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) +#define AD_TYPE_128_BIT_SERV_UUID (0x06) +#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) +/** + * @} + */ + +/* LOCAL NAME AD types */ +/** + * @name Local name AD types + * @{ + */ +#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) +#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) +/** + * @} + */ + +/* TX power level AD type*/ +#define AD_TYPE_TX_POWER_LEVEL (0x0A) + +/* Class of device */ +#define AD_TYPE_CLASS_OF_DEVICE (0x0D) + +/* security manager TK value AD type */ +#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) + +/* security manager OOB flags */ +#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) + +/* slave connection interval AD type */ +#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) + +/* service solicitation UUID list Ad types*/ +/** + * @name Service solicitation UUID list AD types + * @{ + */ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) +#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) +/** + * @} + */ + +/* service data AD type */ +#define AD_TYPE_SERVICE_DATA (0x16) + +/* manufaturer specific data AD type */ +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/* appearance AD type */ +#define AD_TYPE_APPEARANCE (0x19) + +/* advertising interval AD type */ +#define AD_TYPE_ADVERTISING_INTERVAL (0x1A) + +/** + * @} + */ + +#define MAX_ADV_DATA_LEN (31) + +#define DEVICE_NAME_LEN (7) +#define BD_ADDR_SIZE (6) + +/** + * @name Privacy flag values + * @{ + */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) +/** + * @} + */ + +/** + * @name Intervals + * Intervals in terms of 625 micro sec + * @{ + */ +#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ +#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ +#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ +#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ +#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ +#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ +#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ +#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ +/** + * @} + */ + +/** + * @name Timeout values + * @{ + */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ +/** + * @} + */ + +/** + * @anchor gap_roles + * @name GAP Roles + * @{ +*/ +#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) +#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) + +#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) +#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) +/** + * @} + */ + +/** + * @anchor gap_procedure_codes + * @name GAP procedure codes + * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event + * and aci_gap_terminate_gap_procedure() command. + * @{ + */ +#define GAP_LIMITED_DISCOVERY_PROC (0x01) +#define GAP_GENERAL_DISCOVERY_PROC (0x02) +#define GAP_NAME_DISCOVERY_PROC (0x04) +#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) +#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) +#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) +#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) +#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1231 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gap_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GAP_ACI_H__ +#define __BLUENRG_GAP_ACI_H__ + +/** + *@addtogroup GAP GAP + *@brief GAP layer. + *@{ + */ + +/** + *@defgroup GAP_Functions GAP functions + *@brief API for GAP layer. + *@{ + */ + +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". + * @param privacy_enabled Enable (1) or disable (0) privacy. + * @param device_name_char_len Length of the device name characteristic + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, + uint8_t device_name_char_len, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Privacy Flag (peripheral role only) + * @li Reconnection Address (peripheral role only) + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB04A1(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); + +/** + * @brief Set the Device in non-discoverable mode. + * @note This command will disable the LL advertising. + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_discoverable(void); + +/** + * @brief Put the device in limited discoverable mode + * (as defined in GAP specification volume 3, section 9.2.3). + * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. + * The advertising can be disabled at any time by issuing + * aci_gap_set_non_discoverable() command. + * The AdvIntervMin and AdvIntervMax parameters are optional. If both + * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). + * Host can set the Local Name, a Service UUID list and the Slave Connection + * Minimum and Maximum. If provided, these data will be inserted into the + * advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() + * separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following + * standard AD types: + * @li AD Flags + * @li TX Power Level + * + * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates + * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. + * + * Example: + * @code + * + * #define ADV_INTERVAL_MIN_MS 100 + * #define ADV_INTERVAL_MAX_MS 200 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, + * (ADV_INTERVAL_MAX_MS*1000)/0.625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * sizeof(serviceUUIDList), serviceUUIDList, + * 0, 0); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 250 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 500 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg NO_WHITE_LIST_USE + * @arg WHITE_LIST_FOR_ONLY_SCAN + * @arg WHITE_LIST_FOR_ONLY_CONN + * @arg WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +/** + * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4). + * @note The device will be discoverable until the Host issue Aci_Gap_Set_Non_Discoverable command. + * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses + * the default values for advertising intervals (1.28 s and 2.56 s respectively for IDB04A1). + * When using connectable undirected advertising events:\n + * @li Adv_Interval_Min = 30 ms + * @li Adv_Interval_Max = 60 ms + * \nWhen using non-connectable advertising events or scannable undirected advertising events:\n + * @li Adv_Interval_Min = 100 ms + * @li Adv_Interval_Max = 150 ms + * Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided, + * these data will be inserted into the advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following standard AD types: + * @li AD Flags + * @li TX Power Level + * + * Usage example: + * + * @code + * + * #define ADV_INTERVAL_MIN_MS 800 + * #define ADV_INTERVAL_MAX_MS 900 + * #define CONN_INTERVAL_MIN_MS 100 + * #define CONN_INTERVAL_MAX_MS 300 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625, + * (ADV_INTERVAL_MAX_MS*1000)/625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * 0, NULL, + * (CONN_INTERVAL_MIN_MS*1000)/1250, + * (CONN_INTERVAL_MAX_MS*1000)/1250); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 1.28 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 2.56 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ONLY_SCAN + * @arg @ref WHITE_LIST_FOR_ONLY_CONN + * @arg @ref WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); + +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @param adv_interv_min Minimum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @param adv_interv_max Maximum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max); +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); + +/** + * @brief Set the IO capabilities of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param io_capability One of the allowed codes for IO Capability: + * @arg @ref IO_CAP_DISPLAY_ONLY + * @arg @ref IO_CAP_DISPLAY_YES_NO + * @arg @ref IO_CAP_KEYBOARD_ONLY + * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT + * @arg @ref IO_CAP_KEYBOARD_DISPLAY + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_io_capability(uint8_t io_capability); + +/** + * @brief Set the authentication requirements for the device. + * @note If the oob_enable is set to 0, oob_data will be ignored. + * This command has to be given only when the device is not in a connected state. + * @param mitm_mode MITM mode: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @param oob_enable If OOB data are present or not: + * @arg @ref OOB_AUTH_DATA_ABSENT + * @arg @ref OOB_AUTH_DATA_PRESENT + * @param oob_data Out-Of-Band data + * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process + * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process + * @param use_fixed_pin If application wants to use a fixed pin or not: + * @arg @ref USE_FIXED_PIN_FOR_PAIRING + * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING + * If a fixed pin is not used, it has to be provided by the application with + * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will + * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is + * accepted. + * @param bonding_mode One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode); + /** + * @brief Set the authorization requirements of the device. + * @note This command has to be given when connected to a device if authorization is required to access services + * which require authorization. + * @param conn_handle Handle of the connection. + * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required + * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables + * the authorization requirement in the device and when a remote device + * tries to read/write a characeristic with authorization requirements, the stack will + * send back an error response with "Insufficient authorization" error code. + * After pairing is complete a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event + * will be sent to the Host. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); + +/** + * @brief Provide the pass key that will be used during pairing. + * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param conn_handle Connection handle + * @param passkey Pass key that will be used during the pairing process. Must be a number between + * 0 and 999999. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); + +/** + * @brief Authorize a device to access attributes. + * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. + * + * @param conn_handle Connection handle + * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) + * @arg @ref CONNECTION_REJECTED : Reject (reject connection) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); + +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @param own_address_type If Privacy is disabled, then the peripheral address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the peripheral address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); + +/** + * @brief Put the device into undirected connectable mode. + * @note If privacy is enabled in the device, a resolvable private address is generated and used + * as the advertiser's address. If not, the address of the type specified in own_addr_type + * is used for advertising. + * @param own_addr_type Type of our address used during advertising: + * if BLUENRG (IDB04A1) + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * else if BLUENRG_MS (IDB05A1) + * If Privacy is disabled: + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled: + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_filter_policy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ALL + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); + +/** + * @brief Send a slave security request to the master. + * @note This command has to be issued to notify the master of the security requirements of the slave. + * The master may encrypt the link, initiate the pairing procedure, or reject the request. + * @param conn_handle Connection handle + * @param bonding One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @param mitm_protection If MITM protection is required or not: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); + +/** + * @brief Update advertising data. + * @note This command can be used to update the advertising data for a particular AD type. + * If the AD type specified does not exist, then it is added to the advertising data. + * If the overall advertising data length is more than 31 octets after the update, then + * the command is rejected and the old data is retained. + * @param AdvLen Length of AdvData array + * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification + * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. + * Example + * @code + * tBleStatus ret; + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; + * + * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * 8, local_name, 3, serviceUUIDList, 0, 0); + * ret = aci_gap_update_adv_data(5, manuf_data); + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); + +/** + * @brief Delete an AD Type + * @note This command can be used to delete the specified AD type from the advertisement data if + * present. + * @param ad_type One of the allowed AD types (see @ref AD_Types) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); + +/** + * @brief Get the current security settings + * @note This command can be used to get the current security settings of the device. + * @param mitm_protection @arg 0: Not required + * @arg 1: Required + * @param bonding @arg 0: No bonding mode + * @arg 1: Bonding mode + * @param oob_data @arg 0: Data absent + * @arg 1: Data present + * @param passkey_required @arg 0: Not required + * @arg 1: Fixed pin is present which is being used + * @arg 2: Passkey required for pairing. An event will be generated + * when required. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required); + +/** + * @brief Add addresses of bonded devices into the controller's whitelist. + * @note The command will return an error if there are no devices in the database or if it was unable + * to add the device into the whitelist. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_configure_whitelist(void); + +/** + * @brief Terminate a connection. + * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. + * @param conn_handle Connection handle + * @param reason Reason for requesting disconnection. The error code can be any of ones as specified + * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); + +/** + * @brief Clear the security database. + * @note All the devices in the security database will be removed. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_clear_security_database(void); + +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @param conn_handle + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB04A1(void); + +/** + * @brief Start the limited discovery procedure. + * @note The controller is commanded to start active scanning. When this procedure is started, + * only the devices in limited discoverable mode are returned to the upper layers. + * The procedure is terminated when either the upper layers issue a command to terminate the + * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code + * set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated + * due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC. + * The device found when the procedure is ongoing is returned to the upper layers through the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the general discovery procedure. + * @note The controller is commanded to start active scanning. The procedure is terminated when + * either the upper layers issue a command to terminate the procedure by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC + * or a timeout happens. When the procedure is terminated due to any of the above reasons, + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to + * @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to + * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the name discovery procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. Once a connection is established, GATT procedure is started to read the + * device name characteristic. When the read is completed (successfully or unsuccessfully), + * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also + * contains the name of the device if the device name was read successfully. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Start the auto connection establishment procedure. + * @note The devices specified are added to the white list of the controller and a LE_Create_Connection + * call will be made to the controller by GAP with the initiator filter policy set to + * use whitelist to determine which advertiser to connect to. When a command is issued to + * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the + * controller by GAP. + * The procedure is terminated when either a connection is successfully established with one of + * the specified devices in the white list or the procedure is explicitly terminated by issuing + * the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start a general connection establishment procedure. + * @note The host enables scanning in the controller with the scanner filter policy set + * to accept all advertising packets and from the scanning results all the devices + * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * The upper layer then has to select one of the devices to which it wants to connect + * by issuing the command aci_gap_create_connection(). The procedure is terminated + * when a connection is established or the upper layer terminates the procedure by + * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates); +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); + +/** + * @brief Start a selective connection establishment procedure. + * @note The GAP adds the specified device addresses into white list and enables scanning in + * the controller with the scanner filter policy set to accept packets only from + * devices in whitelist. All the devices found are sent to the upper layer by the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the + * devices to which it wants to connect by issuing the command aci_gap_create_connection(). + * On completion of the procedure a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated + * with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * The procedure is terminated when a connection is established or the upper layer terminates + * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure + * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start the direct connection establishment procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. The procedure can be terminated explicitly by the upper layer by issuing + * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the + * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller + * by GAP. + * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can + * be explicitly terminated by the upper layer by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is + * returned with the procedure code set to the corresponding procedure. + * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes"). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); + +/** + * @brief Start the connection parameter update procedure. + * @note Allowed by the Central to update the connection parameter of the specified connection. + * A Link Layer Connection Update procedure is started on the controller. + * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to + * the upper layer. + * @param conn_handle Handle of the connection for which the update procedure has to be started. + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Send a pairing request. + * @note Send the SM pairing request to start a pairing process from a Central. The authentication + * requirements and IO capabilities should be set before issuing this command using + * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). + * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. + * @param conn_handle Handle of the connection for which the pairing request has to be sent. + * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded + * @arg 0x01: Pairing request will be sent even if the device was previously bonded + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param[in] address Address to be resolved. + * @param[out] actual_address The public or static random address of the peer device, distributed during pairing phase. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); + +/** + * @brief This command gets the list of bonded devices. + * @note It returns the number of addresses and the corresponding address types and values. + * Example: + * @code + * tBleStatus ret; + * uint8_t num_devices = 0; + * uint8_t device_list[12*7]; + * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); + * for(int i = 0; i < num_devices; i+=7){ + * uint8_t addr_type = device_list[i]; + * uint8_t addr = device_list[i+1]; + * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); + * } + * @endcode + * + * @param[out] num_devices The number of bonded devices. + * @param[out] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address + * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. + * @param device_list_size Maximum size of the device_list buffer used to return the device list. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); + +/** + * @brief Puts the device into broadcast mode + * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address + * as specified in the own_addr_type parameter of the command. + * @param adv_interv_min Minimum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_interv_max Maximum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param own_addr_type If Privacy is disabled, the broadcaster address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the broadcaster address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_data_length Length of the advertising data in the advertising packet + * @param adv_data Advertising data used by the device while advertising + * @param num_whitelist_entries Number of devices to be added to whitelist + * @param addr_array It will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Starts an observation procedure, when the device is in Observer role. + * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer + * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth + * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. + * The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. + * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param own_address_type If Privacy is disabled, then the scanner address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the scanner address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates); + +/** + * @brief The command finds whether a device is bonded. + * @note If the device is using a resolvable private address and it has been bonded, then the command will return + * BLE_STATUS_SUCCESS. + * @param peer_address_type The address type of the peer device + * @arg @ref PUBLIC_ADDR. + * @arg @ref RANDOM_ADDR. + * @param peer_address Address used by the peer device while advertising. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address); + + +/** + * @} + */ + +/** + * @defgroup GAP_Events GAP events + * @{ + */ + +/** + * This event is generated by the controller when the limited discoverable + * mode ends due to timeout (180 seconds). No parameters in the event. + */ +#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) + + +/** + * This event is generated when the pairing process has completed successfully + * or a pairing procedure timeout has occurred or the pairing has failed. + * This is to notify the application that we have paired with a remote device + * so that it can take further actions or to notify that a timeout has occurred + * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. + */ +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +typedef __packed struct _evt_gap_pairing_cmplt{ + uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ + /** + * 0x00: Pairing Success. Pairing with a remote device was successful\n + * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n + * 0x02: Pairing Failed. The pairing failed with the remote device. + */ + uint8_t status; +} PACKED evt_gap_pairing_cmplt; + + +/** + * This event is generated by the Security manager to the application when a pass key is required for pairing. + * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. + * See @ref _evt_gap_pass_key_req. + */ +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +typedef __packed struct _evt_gap_pass_key_req{ + uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ +} PACKED evt_gap_pass_key_req; + + +/** + * This event is generated by the Security manager to the application when the application + * has set that authorization is required for reading/writing of attributes. This event will + * be generated as soon as the pairing is complete. When this event is received, + * aci_gap_authorization_response() command should be used by the application. + * See @ref _evt_gap_author_req. + */ +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +typedef __packed struct _evt_gap_author_req{ + uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ +} PACKED evt_gap_author_req; + +/** + * This event is generated when the slave security request is successfully sent to the master. + * No parameters for this event. + */ +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) + +/** + * This event is generated on the slave when a aci_gap_slave_security_request() is called to reestablish the bond + * with a master but the master has lost the bond. When this event is received, the upper layer has to issue the + * command aci_gap_allow_rebond() in order to allow the slave to continue the pairing process with the master. + * On the master this event is raised when aci_gap_send_pairing_request() is called to reestablish a bond with a slave + * but the slave has lost the bond. In order to create a new bond the master has to launch aci_gap_send_pairing_request() + * with force_rebond set to 1. + * No parameters for this event + */ +#define EVT_BLUE_GAP_BOND_LOST (0X0405) + +/** + * The event is given by the GAP layer to the upper layers when a device is discovered during scanning + * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. + */ +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef __packed struct _evt_gap_device_found{ + uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ + uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ + tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ + uint8_t data_length; /**< Length of advertising or scan response data. */ + uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ +} PACKED evt_gap_device_found; + +/** + * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated + * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. + */ +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef __packed struct _evt_gap_procedure_complete{ + uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ + /** + * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed + * due to authentication requirements). + */ + uint8_t status; + /** + * Procedure specific data.\n + * @li For Name Discovery Procedure:\n + * the name of the peer device if the procedure completed successfully. + * @li For General Connection Establishment Procedure:\n + * The reconnection address written to the peripheral device if the peripheral is privacy enabled + */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_gap_procedure_complete; + +/** + * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral + * is not able to resolve the private address of the peer device after connecting to it. + */ +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) +typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ + uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ +} PACKED evt_gap_addr_not_resolved_IDB05A1; +/** + * This event is raised when the reconnection address is generated during the general connection + * establishment procedure. The same address is set into the peer device also as a part of the general + * connection establishment procedure. In order to make use of the reconnection address the next time + * while connecting to the bonded peripheral, the application needs to use this reconnection address + * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() + * and aci_gap_start_auto_conn_establish_proc(). + */ +#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) +typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ + uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ +} PACKED evt_gap_reconnection_addr_IDB04A1; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1128 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GATT_ACI_H__ +#define __BLUENRG_GATT_ACI_H__ + +#include "bluenrg_gatt_server.h" + +/** + *@addtogroup GATT GATT + *@brief GATT layer. + *@{ + */ + +/** + *@defgroup GATT_Functions GATT functions + *@brief API for GATT layer. + *@{ + */ + +/** + * @brief Initialize the GATT layer for server and client roles. + * @note It adds also the GATT service with Service Changed Characteristic. + * Until this command is issued the GATT channel will not process any commands + * even if the connection is opened. This command has to be given + * before using any of the GAP features. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_init(void); + +/** + * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs + * to reserve the handle ranges for this service using max_attr_records parameter. This + * parameter specifies the maximum number of attribute records that can be added to this + * service (including the service attribute, include attribute, characteristic attribute, + * characteristic value attribute and characteristic descriptor attribute). Handle of the + * created service is returned. + * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors + * are allocated from the attribute pool. + * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field + * @param service_type Primary or secondary service. See @ref Service_type "Service Type". + * @param max_attr_records Maximum number of attribute records that can be added to this service + * (including the service declaration itself) + * @param[out] serviceHandle Handle of the Service. When this service is added to the service, + * a handle is allocated by the server to this service. Server also + * allocates a range of handles for this service from serviceHandle to + * <serviceHandle + max_attr_records>. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, + const uint8_t* service_uuid, + uint8_t service_type, + uint8_t max_attr_records, + uint16_t *serviceHandle); + +/** + * @brief Include a service given by included_start_handle and included_end_handle to another service + * given by service_handle. Attribute server creates an INCLUDE definition attribute and return + * the handle of this attribute in included_handle. + * @param service_handle Handle of the service to which another service has to be included + * @param included_start_handle Start Handle of the service which has to be included in service + * @param included_end_handle End Handle of the service which has to be included in service + * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". + * @param[in] included_uuid 16-bit or 128-bit UUID. + * @param[out] included_handle Handle of the include declaration. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle); + +/** + * @brief Add a characteristic to a service. + * @param serviceHandle Handle of the service to which the characteristic has to be added. + * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param charUuid 16-bit or 128-bit UUID. + * @param charValueLen Maximum length of the characteristic value. + * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, + * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". + * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @arg GATT_DONT_NOTIFY_EVENTS + * @arg GATT_NOTIFY_ATTRIBUTE_WRITE + * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP + * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. + * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client + * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE + * properties. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle); + +/** + * Add a characteristic descriptor to a service. + * @param serviceHandle Handle of the service to which the characteristic belongs + * @param charHandle Handle of the characteristic to which description has to be added. + * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG + * (Well_known_UUIDs) or a user-defined one. + * @param descValueMaxLen The maximum length of the descriptor value + * @param descValueLen Current Length of the characteristic descriptor value + * @param[in] descValue Value of the characteristic description + * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". + * @arg ATTR_NO_ACCESS + * @arg ATTR_ACCESS_READ_ONLY + * @arg ATTR_ACCESS_WRITE_REQ_ONLY + * @arg ATTR_ACCESS_READ_WRITE + * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE + * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param[out] descHandle Handle of the Characteristic Descriptor. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle); + +/** + * @brief Update a characteristic value in a service. + * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. The command is queued into the + * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, + * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or + * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate + * than what is allowed by the link. Throughput on BLE link depends on connection interval and + * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() + * for more info on how to suggest new connection parameters from a slave). If the application does not + * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function + * returns @ref BLE_STATUS_SUCCESS or any other error code.\n + * Example:\n + * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some + * notifications will be lost. + * @code + * tBleStatus Free_Fall_Notify(void) + * { + * uint8_t val; + * tBleStatus ret; + * + * val = 0x01; + * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); + * + * if (ret != BLE_STATUS_SUCCESS){ + * PRINTF("Error while updating FFall characteristic.\n") ; + * return BLE_STATUS_ERROR ; + * } + * return BLE_STATUS_SUCCESS; + * } + * @endcode + * Here if BlueNRG buffer become full, the application try again to send the notification. + * @code + * struct timer t; + * Timer_Set(&t, CLOCK_SECOND*10); + * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ + * // Radio is busy (buffer full). + * if(Timer_Expired(&t)) + * break; + * } + * @endcode + * + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic + * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, + * and the attribute value is of variable length, then the length of the attribute will + * be set to the charValueLen. If the charValOffset is set to a value greater than 0, + * then the length of the attribute will be set to the maximum length as specified for + * the attribute while adding the characteristic. + * @param charValueLen Length of the characteristic value in octets + * @param[in] charValue Characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue); +/** + * @brief Delete the specified characteristic from the service. + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); + +/** + * @brief Delete the specified service from the GATT server database. + * @param servHandle Handle of the service to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_service(uint16_t servHandle); + +/** + * @brief Delete the Include definition from the service. + * @param servHandle Handle of the service to which Include definition belongs + * @param includeServHandle Handle of the Included definition to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); + +/** + * @brief Perform an ATT MTU exchange procedure. + * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP + * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated + * to indicate the end of the procedure. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); + +/** + * @brief Send a @a Find @a Information @a Request. + * @note This command is used to obtain the mapping of attribute handles with their associated + * types. The responses of the procedure are given through the + * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by + * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range of attributes to be discovered on the server + * @param end_handle Ending handle of the range of attributes to be discovered on the server + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send a @a Find @a By @a Type @a Value @a Request + * @note The Find By Type Value Request is used to obtain the handles of attributes that + * have a given 16-bit UUID attribute type and a given attribute value. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid 2 octet UUID to find (little-endian) + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). + * @param attr_val Attribute value to find + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send a @a Read @a By @a Type @a Request + * @note The Read By Type Request is used to obtain the values of attributes where the attribute type + * is known but the handle is not known. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Read @a By @a Group @a Type @a Request + * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute + * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping + * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Prepare @a Write @a Request + * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param attr_handle The handle of the attribute to be written + * @param value_offset The offset of the first octet to be written + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). + * @param attr_val The value of the attribute to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send an @a Execute @a Write @a Request + * @note The Execute Write Request is used to request the server to write or cancel the write of all the + * prepared values currently held in the prepare queue from this client. + * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param execute @arg 0x00 Cancel all prepared writes + * @arg 0x01 Immediately write all pending prepared values. + * @return Value indicating success or error code. + */ +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); + +/** + * @brief This command will start the GATT client procedure to discover all primary services on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +/** + * @brief Start the procedure to discover the primary services of the specified UUID on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to find all included services. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle Start handle of the service + * @param end_handle End handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Start the procedure to discover all the characteristics of a given service. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_attr_handle Start attribute handle of the service + * @param end_attr_handle End attribute handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +/** + * @brief Start the procedure to discover all the characteristics specified by a UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Start attribute handle of the service + * @param end_handle End attribute handle of the service + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); + +/** + * @brief Start the procedure to discover all characteristic descriptors on the server. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. + * @param conn_handle Connection handle for which the command is given. + * @param char_val_handle Starting handle of the characteristic + * @param char_end_handle End handle of the characteristic + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +/** + * @brief Start the procedure to read the attribute value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to read all the characteristics specified by the UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range to be searched + * @param end_handle End handle of the range to be searched + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start a procedure to read multiple characteristic values from a server. + * @note This sub-procedure is used to read multiple Characteristic Values from a server when the + * client knows the Characteristic Value Handles. + * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param num_handles The number of handles for which the value has to be read + * @param set_of_handles The handles for which the attribute value has to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles); + +/** + * @brief Start the procedure to write a characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to write a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start the procedure to write a characteristic reliably. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to write a long characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP + * event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic descriptor + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start the procedure to write a characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to read the descriptor specified. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the descriptor to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to write a characteristic value without waiting for any response from the server. + * @note No events are generated after this command is executed. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 3) + * @param[in] attr_val Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start a signed write without response from the server. + * @note The procedure i used to write a characteristic value with an authentication signature without waiting + * for any response from the server. It cannot be used when the link is encrypted. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 13). + * @param attr_val Value to be written + * @return Value indicating success or error code + */ +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Confirm an indication + * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); + +/** + * @brief Allow or reject a write request from a client. + * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, + * then the status has to be set to 1 and the error code has to be set to the error code that has to be + * passed to the client. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n + * 0x01: The value cannot be written to the attribute specified by the attr_handle. + * @param err_code The error code that has to be passed to the client in case the write has to be rejected. + * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val); + +/** + * @brief Allow the GATT server to send a response to a read request from a client. + * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ + * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response + * can be sent to the client. So if the application wishes to update any of the attributes before + * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value + * and then give this command. The application should perform the required operations within 30 seconds, + * otherwise the GATT procedure will go to timeout. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_allow_read(uint16_t conn_handle); + +/** + * @brief Set the security permission for the attribute handle specified. + * @note Currently the setting of security permission is allowed only for client configuration descriptor. + * @param service_handle Handle of the service which contains the attribute whose security + * permission has to be modified. + * @param attr_handle Handle of the attribute whose security permission has to be modified. + * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission); + +/** + * @brief This command sets the value of the descriptor specified by charDescHandle. + * @param servHandle Handle of the service which contains the descriptor. + * @param charHandle Handle of the characteristic which contains the descriptor. + * @param charDescHandle Handle of the descriptor whose value has to be set. + * @param charDescValOffset Offset from which the descriptor value has to be updated. + * @param charDescValueLen Length of the descriptor value + * @param[in] charDescValue descriptor value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue); + +/** + * @brief Reads the value of the attribute handle specified from the local GATT database. + * @param attr_handle Handle of the attribute to read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + + /** + * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. + * @param attr_handle Handle of the attribute to read + * @param offset Offset from which the value needs to be read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); +/** + * @brief Update the value of a characteristic and sends notifications or indications. + * @note This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute + * up to 512 bytes and indicate selectively the generation of indications and notifications. + * @param service_handle Handle of the service to which the characteristic belongs. + * @param char_handle Handle of the characteristic + * @param update_type Bitmask that controls generation of notifications and indications. It can be a combination + * @arg @ref NOTIFICATION (0x01): send notification, if enabled. + * @arg @ref INDICATION (0x02): send indication, if enabled. + * If set to 0 no notifications or indications are sent. + * @param char_length Total length of the characteristic value. In case of a variable size characteristic, + * this field specifies the new length of the characteristic value after the update; + * in case of fixed length characteristic this field is ignored. + * @param value_offset The offset from which the attribute value has to be updated + * @param value_length Length of the value to be updated + * @param[out] value Updated characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value); + +/** + * @} + */ + + +/** + * @defgroup GATT_Events GATT events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** + * This event (if enabled, see @ref Gatt_Event_Mask "Gatt Event Mask") is raised to the application + * by the GATT server when a client modifies any attribute on the server, as consequence of one of + * the following GATT procedures: + * @li write without response + * @li signed write without response + * @li write characteristic value + * @li write long characteristic value + * @li reliable write. + * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. + */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint16_t offset; /**< Offset from which the write has been performed by the peer device */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB05A1; + +typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB04A1; + +/** + * This event is generated by the client/server to the application on a GATT timeout (30 seconds). + * See @ref _evt_gatt_procedure_timeout. + */ +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +typedef __packed struct _evt_gatt_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ +} PACKED evt_gatt_procedure_timeout; + +/** + * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). + * See @ref _evt_att_exchange_mtu_resp. + */ +#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) +typedef __packed struct _evt_att_exchange_mtu_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data (always 1). */ + uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ +} PACKED evt_att_exchange_mtu_resp; + +/** + * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and + * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. + */ +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef __packed struct _evt_att_find_information_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ + /** + * A sequence of handle-uuid pairs.\n + * @li if format=1, each pair is:\n + * [2 octets for handle, 2 octets for UUIDs] \n + * @li if format=2, each pair is:\n + * [2 octets for handle, 16 octets for UUIDs] + */ + uint8_t handle_uuid_pair[VARIABLE_SIZE]; +} PACKED evt_att_find_information_resp; + +/** + * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See + * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. + */ +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +typedef __packed struct _evt_att_find_by_type_val_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + /** + * Handles Information List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] + */ + uint8_t handles_info_list[VARIABLE_SIZE]; +} PACKED evt_att_find_by_type_val_resp; + +/** + * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and + * aci_gatt_disc_all_charac_of_serv(). + * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. + */ +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef __packed struct _evt_att_read_by_type_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ + /** + * Attribute Data List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] + */ + uint8_t handle_value_pair[VARIABLE_SIZE]; +} PACKED evt_att_read_by_type_resp; + +/** + * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). + * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. + */ +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +typedef __packed struct _evt_att_read_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ +} PACKED evt_att_read_resp; + +/** + * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). + * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. + */ +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +typedef __packed struct _evt_att_read_blob_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ +} PACKED evt_att_read_blob_resp; + +/** + * This event is generated in response to a @a Read @a Multiple @a Request. + * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. + */ +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +typedef __packed struct _evt_att_read_mult_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ +} PACKED evt_att_read_mult_resp; + +/** + * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). + * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. + */ +#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) +typedef __packed struct _evt_att_read_by_group_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_data_length; /**< The size of each Attribute Data. */ + /** + * A list of Attribute Data where the attribute data is composed by: + * @li 2 octets for Attribute Handle + * @li 2 octets for End Group Handle + * @li (attribute_data_length - 4) octets for Attribute Value + */ + uint8_t attribute_data_list[VARIABLE_SIZE]; +} PACKED evt_att_read_by_group_resp; + +/** + * This event is generated in response to a @a Prepare @a Write @a Request. + * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. + */ +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +typedef __packed struct _evt_att_prepare_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attribute_handle; /**< The handle of the attribute to be written. */ + uint16_t offset; /**< The offset of the first octet to be written. */ + uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ +} PACKED evt_att_prepare_write_resp; + +/** + * This event is generated in response to an @a Execute @a Write @a Request. + * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. + */ +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +typedef __packed struct _evt_att_exec_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Always 0. */ +} PACKED evt_att_exec_write_resp; + +/** + * This event is generated when an indication is received from the server. + * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. + */ +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +typedef __packed struct _evt_gatt_indication{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_indication; + +/** + * This event is generated when a notification is received from the server. + * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. + */ +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef __packed struct _evt_gatt_notification{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_attr_notification; + +/** + * This event is generated when a GATT client procedure completes either with error or successfully. + * See @ref _evt_gatt_procedure_complete. + */ +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef __packed struct _evt_gatt_procedure_complete{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ + uint8_t data_length; /**< Length of error_code field (always 1). */ + /** + * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). + */ + uint8_t error_code; +} PACKED evt_gatt_procedure_complete; + +/** + * This event is generated when an Error Response is received from the server. The error response can be given + * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended + * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. + */ +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +typedef __packed struct _evt_gatt_error_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t req_opcode; /**< The request that generated this error response. */ + uint16_t attr_handle; /**< The attribute handle that generated this error response. */ + uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ +} PACKED evt_gatt_error_resp; + +/** + * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using + * Characteristic UUID" procedure. + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. + */ +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + /** + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. + */ + uint8_t attr_value[VARIABLE_SIZE]; +} PACKED evt_gatt_disc_read_char_by_uuid_resp; + +/** + * This event is given to the application when a write request, write command or signed write command + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * If the write is rejected by the application, then the value of the attribute will not be modified. + * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. + * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef __packed struct _evt_gatt_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_write_permit_req; + +/** + * This event is given to the application when a read request or read blob request is received by the server + * from the client. This event will be given to the application only if the event bit for this event generation + * is set when the characteristic was added. + * On receiving this event, the application can update the value of the handle if it desires and when done + * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef __packed struct _evt_gatt_read_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ + uint8_t data_length; /**< Length of offset field. */ + uint16_t offset; /**< Contains the offset from which the read has been requested */ +} PACKED evt_gatt_read_permit_req; + +/** + * This event is given to the application when a read multiple request or read by type request is received + * by the server from the client. This event will be given to the application only if the event bit for this + * event generation is set when the characteristic was added. + * On receiving this event, the application can update the values of the handles if it desires and when done + * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_multi_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) +typedef __packed struct _evt_gatt_read_multi_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ +} PACKED evt_gatt_read_multi_permit_req; + +/** + * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2). + * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES. + * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value(). + * See @ref evt_gatt_tx_pool_vailable. + * + */ +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE (0x0C16) +typedef __packed struct _evt_gatt_tx_pool_available{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t available_buffers; /**< Length of data field. */ +} PACKED evt_gatt_tx_pool_available; + +/** + * This event is raised on the server when the client confirms the reception of an indication. + */ +#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT (0x0C17) +typedef __packed struct _evt_gatt_server_confirmation{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ +} PACKED evt_gatt_server_confirmation; +/** + * This event is given to the application when a prepare write request + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * Based on the response from the application, the attribute value will be modified by the stack. + * If the write is rejected by the application, then the value of the attribute will not be modified + * and an error response will be sent to the client, with the error code as specified by the application. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ (0x0C18) +typedef __packed struct _evt_gatt_prepare_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint16_t offset; /**< The offset from which the prepare write has been requested */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_prepare_write_permit_req; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,229 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gatt_server.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GATT server layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BNRG_GATT_SERVER_H__ +#define __BNRG_GATT_SERVER_H__ + +#include "ble_compiler.h" +#include "ble_status.h" + +/** + *@addtogroup GATT GATT + *@{ + */ + +/** + * @anchor Well-Known_UUIDs + * @name Well-Known UUIDs + * @{ + */ +#define PRIMARY_SERVICE_UUID (0x2800) +#define SECONDARY_SERVICE_UUID (0x2801) +#define INCLUDE_SERVICE_UUID (0x2802) +#define CHARACTERISTIC_UUID (0x2803) +#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) +#define CHAR_USER_DESC_UUID (0x2901) +#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) +#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) +#define CHAR_FORMAT_DESC_UUID (0x2904) +#define CHAR_AGGR_FMT_DESC_UUID (0x2905) +#define GATT_SERVICE_UUID (0x1801) +#define GAP_SERVICE_UUID (0x1800) +#define SERVICE_CHANGED_UUID (0x2A05) +/** + * @} + */ + +/** + * @anchor Access_permissions + * @name Access permissions + * Access permissions for an attribute + * @{ + */ +#define ATTR_NO_ACCESS (0x00) +#define ATTR_ACCESS_READ_ONLY (0x01) +#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) +#define ATTR_ACCESS_READ_WRITE (0x03) +#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) +#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) +/** + * Allows all write procedures + */ +#define ATTR_ACCESS_WRITE_ANY (0x0E) +/** + * @} + */ + +/** + * @anchor Char_properties + * @name Characteristic properties. + * @{ + */ +#define CHAR_PROP_BROADCAST (0x01) +#define CHAR_PROP_READ (0x02) +#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) +#define CHAR_PROP_WRITE (0x08) +#define CHAR_PROP_NOTIFY (0x10) +#define CHAR_PROP_INDICATE (0x20) +#define CHAR_PROP_SIGNED_WRITE (0x40) +#define CHAR_PROP_EXT (0x80) +/** + * @} + */ + + +/** + * @anchor Security_permissions + * @name Security permissions for an attribute. + * @{ + */ +#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ +#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ +#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ +#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ +/** + * @} + */ + +/** + * @anchor UUID_Types + * @name Type of UUID (16 bit or 128 bit). + * @{ + */ +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) +/** + * @} + */ + +/** + * @anchor Service_type + * @name Type of service (primary or secondary) + * @{ + */ +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) +/** + * @} + */ + +/** + * @anchor Gatt_Event_Mask + * @name Gatt Event Mask + * Type of event generated by GATT server + * @{ + */ +#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ +#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. + An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ +#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd + or a signed write cmd are received by the server for this attribute. + An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ +#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is + received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ +/** + * @} + */ + +/** + * @name Type of characteristic length + * See aci_gatt_add_char() + * @{ + */ +#define CHAR_VALUE_LEN_CONSTANT (0x00) +#define CHAR_VALUE_LEN_VARIABLE (0x01) +/** + * @} + */ + + +/** + * @name Encryption key size + * @{ + */ +/** + * Minimum encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Maximum encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) +/** + * @} + */ + +/** + * @name Characteristic Presentation Format + * @{ + */ +typedef __packed struct _charactFormat { + uint8_t format; + int8_t exp; + uint16_t unit; + uint8_t name_space; + uint16_t desc; +} PACKED charactFormat; + +/** + * @} + */ + +/** + * @name Format + * @{ + */ +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F +/** + * @} + */ + +/** + * @name Unit + * @{ + */ +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 +/** + * @} + */ + + +/** + * ATT MTU size + */ +#define ATT_MTU (23) + +/** + * @} + */ + + /** + * @name Update type of aci_gatt_upd_char_val_ext(). + * @{ + */ + +#define NOTIFICATION 1 +#define INDICATION 2 + +#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,385 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hal_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with HCI commands for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_HAL_ACI_H__ +#define __BLUENRG_HAL_ACI_H__ + +/** + *@addtogroup HAL HAL + *@brief Hardware Abstraction Layer. + *@{ + */ + +/** + * @defgroup HAL_Functions HAL functions + * @brief API for BlueNRG HAL layer. + * @{ + */ + +/** + * @brief This command retrieves the buid number of the firmware. + * @param[out] build_number Build number identifying the firmware release. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number); + +/** + * @brief This command writes a value to a low level configure data structure. + * @note It is useful to setup directly some low level parameters for the system at runtime. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * + * @param len Length of data to be written + * @param[out] val Data to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val); + +/** + * @brief This command requests the value in the low level configure data structure. + * The number of read bytes changes for different Offset. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * @param data_len Length of the data buffer + * @param[out] data_len_out_p length of the data returned by the read. + * @param[out] data Read data + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data); + +/** + * @brief This command sets the TX power level of the BlueNRG. + * @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines + * the output power level (dBm). + * When the system starts up or reboots, the default TX power level will be used, which is + * the maximum value of 8dBm. Once this command is given, the output power will be changed + * instantly, regardless if there is Bluetooth communication going on or not. For example, + * for debugging purpose, the BlueNRG can be set to advertise all the time and use this + * command to observe the signal strength changing. The system will keep the last received + * TX power level from the command, i.e. the 2nd command overwrites the previous TX power + * level. The new TX power level remains until another Set TX Power command, or the system + * reboots.\n + * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the + * right value, depending on the selected hardware configuration for the RF network: + * normal mode or high power mode. + * @param pa_level Can be from 0 to 7. Set the PA level value. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +/** + * @brief This command returns the number of packets sent in Direct Test Mode. + * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets + * have been transmitted. This command can be used to check how many packets have been sent + * during the Direct TX test.\n + * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again. + * The counter is not cleared until the next Direct TX test starts. + * @param[out] number_of_packets Number of packets sent during the last Direct TX test. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets); + +/** + * @brief Put the device in standby mode. + * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the + * device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode, + * the device can still wake up itself with the internal timer. But in standby mode, this timer is + * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command + * sent via SPI bus. + * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code + * ERR_COMMAND_DISALLOWED will be returned. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_device_standby(void); + +/** + * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. + * @note The frequency sine wave at the specific channel may be used for test purpose only. + * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. + * This command shouldn't be used when normal Bluetooth activities are ongoing. + * The tone should be stopped by aci_hal_tone_stop() command. + * + * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the + * channel central frequency minus 250 kHz. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +/** + * This command is used to stop the previously started aci_hal_tone_start() command. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_stop(void); + +/** + * @brief This command returns the status of all the connections. + * @note This command returns the status of the 8 Bluetooth low energy links managed by the device. + * @param[out] link_status Array of link status (8 links). See @ref Link_Status. + * @param[out] conn_handle Array of connection handles for each link. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]); + +/** + * @brief This command returns the anchor period and the largest available slot. + * @note This command returns information about the anchor period to help application in selecting + * slot timings when operating in multi-link scenarios. + * @param anchor_period Current anchor period (multiple of 0.625 ms). + * @param max_free_slot Maximum available time (multiple of 0.625 ms) that can be allocated for a new slot. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot); + +/** + * @} + */ + +/** + * @defgroup HAL_Events HAL events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_HAL_INITIALIZED (0x0001) +typedef __packed struct _evt_hal_initialized{ + uint8_t reason_code; /**< Reset reason. See @ref Reset_Reasons */ +} PACKED evt_hal_initialized; + +/** + * This event is generated when an overflow occurs in the event queue read by the external microcontroller. + * This is normally caused when the external microcontroller does not read pending events. + * The returned bitmap indicates which event has been lost. Please note that one bit set to 1 indicates one or + * more occurrences of the particular events. The event EVT_BLUE_HAL_EVENTS_LOST cannot be lost and it will + * be inserted in the event queue as soon as a position is freed in the event queue. This event should not + * happen under normal operating condition where external microcontroller promptly reads events signaled by + * IRQ pin. It is provided to detected unexpected behavior of the external microcontroller or to allow + * application to recover situations where critical events are lost. + */ +#define EVT_BLUE_HAL_EVENTS_LOST_IDB05A1 (0x0002) +typedef __packed struct _evt_hal_events_lost{ + uint8_t lost_events[8]; /**< Bitmap of lost events. Each bit indicates one or more occurrences of the specific event. See @ref Lost_Events */ +} PACKED evt_hal_events_lost_IDB05A1; + + +/** + * This event is given to the application after the @ref ACI_BLUE_INITIALIZED_EVENT + * when a system crash is detected. This events returns system crash information for debugging purposes. + * Information reported are useful to understand the root cause of the crash. + */ +#define EVT_BLUE_HAL_CRASH_INFO_IDB05A1 (0x0003) +typedef __packed struct _evt_hal_crash_info{ + uint8_t crash_type; /**< Type of crash: Assert failed (0), NMI Fault (1), Hard Fault (2) */ + uint32_t sp; /**< SP register */ + uint32_t r0; /**< R0 register */ + uint32_t r1; /**< R1 register */ + uint32_t r2; /**< R2 register */ + uint32_t r3; /**< R3 register */ + uint32_t r12; /**< R12 register */ + uint32_t lr; /**< LR register */ + uint32_t pc; /**< PC register */ + uint32_t xpsr; /**< xPSR register */ + uint8_t debug_data_len; /**< length of debug_data field */ + uint8_t debug_data[VARIABLE_SIZE]; /**< Debug data */ +} PACKED evt_hal_crash_info_IDB05A1; + + +/** + * @} + */ + + +/** + * @anchor Reset_Reasons + * @name Reset Reasons + * See @ref EVT_BLUE_HAL_INITIALIZED. + * @{ + */ +#define RESET_NORMAL 1 /**< Normal startup. */ +#define RESET_UPDATER_ACI 2 /**< Updater mode entered with ACI command */ +#define RESET_UPDATER_BAD_FLAG 3 /**< Updater mode entered due to a bad BLUE flag */ +#define RESET_UPDATER_PIN 4 /**< Updater mode entered with IRQ pin */ +#define RESET_WATCHDOG 5 /**< Reset caused by watchdog */ +#define RESET_LOCKUP 6 /**< Reset due to lockup */ +#define RESET_BROWNOUT 7 /**< Brownout reset */ +#define RESET_CRASH 8 /**< Reset caused by a crash (NMI or Hard Fault) */ +#define RESET_ECC_ERR 9 /**< Reset caused by an ECC error */ +/** + * @} + */ + + +/** + * @defgroup Config_vals Offsets and lengths for configuration values. + * @brief Offsets and lengths for configuration values. + * See aci_hal_write_config_data(). + * @{ + */ + +/** + * @name Configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ +#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ +#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ +#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ +#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. + It can be written only if aci_hal_write_config_data() is the first command after reset. */ +#define CONFIG_DATA_RANDOM_ADDRESS (0x80) /**< Stored static random address. Read-only. */ + +/** + * Select the BlueNRG mode configurations.\n + * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) + * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) + * @li Mode 3: master/slave, 8 connections, RAM1 and RAM2. + * @li Mode 4: master/slave, 4 connections, RAM1 and RAM2 simultaneous scanning and advertising. + */ +#define CONFIG_DATA_MODE_OFFSET (0x2D) + +#define CONFIG_DATA_WATCHDOG_DISABLE (0x2F) /**< Set to 1 to disable watchdog. It is enabled by default. */ +/** + * @} + */ + +/** + * @name Length for configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_LEN (6) +#define CONFIG_DATA_DIV_LEN (2) +#define CONFIG_DATA_ER_LEN (16) +#define CONFIG_DATA_IR_LEN (16) +#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) +#define CONFIG_DATA_MODE_LEN (1) +#define CONFIG_DATA_WATCHDOG_DISABLE_LEN (1) +/** + * @} + */ + +/** + * @anchor Link_Status + * @name Status of the link + * See @ref aci_hal_get_link_status(). + * @{ + */ +#define STATUS_IDLE 0 +#define STATUS_ADVERTISING 1 +#define STATUS_CONNECTED_AS_SLAVE 2 +#define STATUS_SCANNING 3 +#define STATUS_CONNECTED_AS_MASTER 5 +#define STATUS_TX_TEST 6 +#define STATUS_RX_TEST 7 +/** + * @} + */ + +/** + * @} + */ + + /** + * @anchor Lost_Events + * @name Lost events bitmap + * See @ref EVT_BLUE_HAL_EVENTS_LOST. + * @{ + */ +#define EVT_DISCONN_COMPLETE_BIT 0 +#define EVT_ENCRYPT_CHANGE_BIT 1 +#define EVT_READ_REMOTE_VERSION_COMPLETE_BIT 2 +#define EVT_CMD_COMPLETE_BIT 3 +#define EVT_CMD_STATUS_BIT 4 +#define EVT_HARDWARE_ERROR_BIT 5 +#define EVT_NUM_COMP_PKTS_BIT 6 +#define EVT_ENCRYPTION_KEY_REFRESH_BIT 7 +#define EVT_BLUE_HAL_INITIALIZED_BIT 8 +#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE_BIT 9 +#define EVT_BLUE_GAP_PAIRING_CMPLT_BIT 10 +#define EVT_BLUE_GAP_PASS_KEY_REQUEST_BIT 11 +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST_BIT 12 +#define EVT_BLUE_GAP_SECURITY_REQ_INITIATED_BIT 13 +#define EVT_BLUE_GAP_BOND_LOST_BIT 14 +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE_BIT 15 +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_BIT 16 +#define EVT_BLUE_L2CAP_CONN_UPDATE_RESP_BIT 17 +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT_BIT 18 +#define EVT_BLUE_L2CAP_CONN_UPDATE_REQ_BIT 19 +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_BIT 20 +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT_BIT 21 +#define EVT_BLUE_EXCHANGE_MTU_RESP_BIT 22 +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP_BIT 23 +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP_BIT 24 +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP_BIT 25 +#define EVT_BLUE_ATT_READ_RESP_BIT 26 +#define EVT_BLUE_ATT_READ_BLOB_RESP_BIT 27 +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP_BIT 28 +#define EVT_BLUE_ATT_READ_BY_GROUP_RESP_BIT 29 +#define EVT_BLUE_ATT_WRITE_RESP_BIT 30 +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP_BIT 31 +#define EVT_BLUE_ATT_EXEC_WRITE_RESP_BIT 32 +#define EVT_BLUE_GATT_INDICATION_BIT 33 +#define EVT_BLUE_GATT_NOTIFICATION_BIT 34 +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE_BIT 35 +#define EVT_BLUE_GATT_ERROR_RESP_BIT 36 +#define EVT_BLUE_GATT_DISC_READ_CHARAC_BY_UUID_RESP_BIT 37 +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ_BIT 38 +#define EVT_BLUE_GATT_READ_PERMIT_REQ_BIT 39 +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ_BIT 40 +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_BIT 41 +#define EVT_BLUE_GATT_SERVER_RX_CONFIRMATION_BIT 42 +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ_BIT 43 +#define EVT_LL_CONNECTION_COMPLETE_BIT 44 +#define EVT_LL_ADVERTISING_REPORT_BIT 45 +#define EVT_LL_CONNECTION_UPDATE_COMPLETE_BIT 46 +#define EVT_LL_READ_REMOTE_USED_FEATURES_BIT 47 +#define EVT_LL_LTK_REQUEST_BIT 48 +/** + * @} + */ + +/** + * @name Hardware error event codes + * See @ref EVT_HARDWARE_ERROR. + * @{ + */ +/** + * Error on the SPI bus has been detected, most likely caused by incorrect SPI configuration on the external micro-controller. + */ +#define SPI_FRAMING_ERROR 0 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define RADIO_STATE_ERROR 1 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define TIMER_OVERRUN_ERROR 2 + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,166 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_l2cap_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with L2CAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_L2CAP_ACI_H__ +#define __BLUENRG_L2CAP_ACI_H__ + +/** + *@addtogroup L2CAP L2CAP + *@brief L2CAP layer. + *@{ + */ + +/** + *@defgroup L2CAP_Functions L2CAP functions + *@brief API for L2CAP layer. + *@{ + */ + +/** + * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. + * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request + * (accepts or rejects). + * @param conn_handle Connection handle on which the connection parameter update request has to be sent. + * @param interval_min Defines minimum value for the connection event interval in the following manner: + * connIntervalMin = interval_min x 1.25ms + * @param interval_max Defines maximum value for the connection event interval in the following manner: + * connIntervalMax = interval_max x 1.25ms + * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). + * @param timeout_multiplier Defines connection timeout parameter in the following manner: + * timeout_multiplier x 10ms. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier); +/** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param min_ce_length Minimum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_ce_length Maximum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept); + /** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept); + +/** + * @} + */ + +/** + * @defgroup L2CAP_Events L2CAP events + * @{ + */ + +/** + * This event is generated when the master responds to the L2CAP connection update request packet. + * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. + */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef __packed struct _evt_l2cap_conn_upd_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ +/** + * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. + * @li 0x01 in case of Command Reject. + */ + uint8_t code; + uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ + uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ +/** + * Result code (parameters accepted or rejected) in case of Connection Parameter Update + * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). + */ + uint16_t result; +} PACKED evt_l2cap_conn_upd_resp; + +/** + * This event is generated when the master does not respond to the connection update request + * within 30 seconds. + */ +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) +typedef __packed struct _evt_l2cap_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */ +} PACKED evt_l2cap_procedure_timeout; + +/** + * The event is given by the L2CAP layer when a connection update request is received from the slave. + * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). + */ +#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) +typedef __packed struct _evt_l2cap_conn_upd_req{ +/** + * Handle of the connection for which the connection update request has been received. + * The same handle has to be returned while responding to the event with the command + * aci_l2cap_connection_parameter_update_response(). + */ + uint16_t conn_handle; + uint8_t event_data_length; /**< Length of following data. */ +/** + * This is the identifier which associates the request to the + * response. The same identifier has to be returned by the upper + * layer in the command aci_l2cap_connection_parameter_update_response(). + */ + uint8_t identifier; + uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ + uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ +} PACKED evt_l2cap_conn_upd_req; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_updater_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with updater commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_UPDATER_ACI_H__ +#define __BLUENRG_UPDATER_ACI_H__ + +#include <ble_compiler.h> + +/** + * @defgroup Updater Updater + * @brief Updater. + * @{ + */ + +/** + * @defgroup Updater_Functions Updater functions + * @brief API for BlueNRG Updater. + * @{ + */ + +tBleStatus aci_updater_start(void); + +tBleStatus aci_updater_reboot(void); + +tBleStatus aci_get_updater_version(uint8_t *version); + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); + +tBleStatus aci_erase_blue_flag(void); + +tBleStatus aci_reset_blue_flag(void); + +tBleStatus aci_updater_erase_sector(uint32_t address); + +tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); + +tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); + +tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); + +tBleStatus aci_updater_hw_version(uint8_t *version); + +/** + * @} + */ + +/** + * @defgroup Updater_Events Updater events + * @{ + */ +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_INITIALIZED (0x0001) +typedef __packed struct _evt_blue_initialized{ + uint8_t reason_code; +} PACKED evt_blue_initialized; +/** + * @} + */ + +/** + * @} + */ + + + +#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,204 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_utils.h +* Author : AMS - VMA, RF Application Team +* Version : V1.0.1 +* Date : 03-October-2014 +* Description : Header file for BlueNRG utility functions +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + * @file bluenrg_utils.h + * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description + * + * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> +**/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLUENRG_UTILS_H +#define __BLUENRG_UTILS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ble_hal_types.h" +#include "ble_compiler.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct{ + uint8_t stack_mode; + uint8_t day; + uint8_t month; + uint8_t year; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint16_t hs_startup_time; /* In system time units*/ +} IFR_config2_TypeDef; + +/** + * Structure inside IFR for configuration options. + */ +typedef __packed struct{ + uint8_t cold_ana_act_config_table[64]; + uint8_t hot_ana_config_table[64]; + uint8_t stack_mode; + uint8_t gpio_config; + uint8_t rsrvd1[2]; + uint32_t rsrvd2[3]; + uint32_t max_conn_event_time; + uint32_t ls_crystal_period; + uint32_t ls_crystal_freq; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint8_t rsrvd3; + uint16_t hs_startup_time; /* In system time units*/ + uint8_t rsrvd4[2]; + uint32_t uid; + uint8_t rsrvd5; + uint8_t year; + uint8_t month; + uint8_t day; + uint32_t unused[5]; +} PACKED IFR_config_TypeDef; + +/* Exported constants --------------------------------------------------------*/ +extern const IFR_config_TypeDef IFR_config; + +/* Exported macros -----------------------------------------------------------*/ +#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)+1) +#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) + +/* Convert 2 digit BCD number to an integer */ +#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) + +/* Convert 2 digit number to a BCD number */ +#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) + +/** + * Return values + */ +#define BLE_UTIL_SUCCESS 0 +#define BLE_UTIL_UNSUPPORTED_VERSION 1 +#define BLE_UTIL_WRONG_IMAGE_SIZE 2 +#define BLE_UTIL_ACI_ERROR 3 +#define BLE_UTIL_CRC_ERROR 4 +#define BLE_UTIL_PARSE_ERROR 5 +#define BLE_UTIL_WRONG_VERIFY 6 + +/* Exported functions ------------------------------------------------------- */ +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int program_device(const uint8_t *fw_image, uint32_t fw_size); + +/** + * @brief Read raw data from IFR (3 64-bytes blocks). + * @param data Pointer to the buffer that will contain the read data. + * Its size must be 192 bytes. This data can be parsed by + * parse_IFR_data_config(). + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION) + */ +int read_IFR(uint8_t data[192]); + +/** + * @brief Verify raw data from IFR (3 64-bytes blocks). + * @param ifr_data Pointer to the buffer that will contain the data to verify. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) + */ +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); + +/** + * @brief Program raw data to IFR (3 64-bytes blocks). + * @param ifr_image Pointer to the buffer that will contain the data to program. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful + */ +int program_IFR(const IFR_config_TypeDef *ifr_image); + +/** + * @brief Parse IFR raw data. + * @param data Pointer to the raw data: last 64 bytes read from IFR sector. + * @param IFR_config Data structure that will be filled with parsed data. + * @retval None + */ +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); + +/** + * @brief Check for the correctness of parsed data. + * @param IFR_config Data structure filled with parsed data. + * @retval int It returns 0 if successful, or PARSE_ERROR in case data is + * not correct. + */ +int IFR_validate(IFR_config2_TypeDef *IFR_config); + +/** + * @brief Modify IFR data. (Last 64-bytes block). + * @param IFR_config Structure that contains the new parameters inside the + * IFR configuration data. + * @note It is highly recommended to parse the IFR configuration from + * a working IFR block (this should be done with parse_IFR_data_config()). + * Then it is possible to write the new parameters inside the IFR_config + * structure. + * @param data Pointer to the buffer that contains the original data. It + * will be modified according to the new data in the IFR_config + * structure. Then this data must be written in the last + * 64-byte block in the IFR. + * Its size must be 64 bytes. + * @retval None + */ +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); + +/** + * @brief Get BlueNRG hardware and firmware version + * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). + * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN + * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. + * @retval Status of the call + */ +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); + +/** + * @brief Get BlueNRG updater version + * @param version This parameter returns the updater version. If the updadter version is 0x03 + * the chip has the updater old, needs to update the bootloader. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterVersion(uint8_t *version); + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version); + +/** + * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on + * the HW bootloader related to the 32 MHz external crystal oscillator. + * @retval TRUE if the HW bootloader is already patched, FALSE otherwise + */ +uint8_t isHWBootloader_Patched(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__BLUENRG_UTILS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file bluenrg_targets.h + * @author AST / EST + * @version V0.0.1 + * @date 24-July-2015 + * @brief This header file is intended to manage the differences between + * the different supported base-boards which might mount the + * X_NUCLEO_IDB0XA1 BlueNRG BLE Expansion Board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent from recursive inclusion --------------------------------*/ +#ifndef _BLUENRG_TARGETS_H_ +#define _BLUENRG_TARGETS_H_ + +#if !defined(BLUENRG_PIN_SPI_MOSI) +#define BLUENRG_PIN_SPI_MOSI (D11) +#endif +#if !defined(BLUENRG_PIN_SPI_MISO) +#define BLUENRG_PIN_SPI_MISO (D12) +#endif +#if !defined(BLUENRG_PIN_SPI_nCS) +#define BLUENRG_PIN_SPI_nCS (A1) +#endif +#if !defined(BLUENRG_PIN_SPI_RESET) +#define BLUENRG_PIN_SPI_RESET (D7) +#endif +#if !defined(BLUENRG_PIN_SPI_IRQ) +#define BLUENRG_PIN_SPI_IRQ (A0) +#endif + +/* NOTE: Refer to README for further details regarding BLUENRG_PIN_SPI_SCK */ +#if !defined(BLUENRG_PIN_SPI_SCK) +#define BLUENRG_PIN_SPI_SCK (D3) +#endif + +/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv) + * Mode 0x01: slave or master, 1 connection + * Mode 0x02: slave or master, 1 connection + * Mode 0x03: master/slave, 8 connections + * Mode 0x04: master/slave, 4 connections (simultaneous scanning and advertising) + * Check Table 285 of + * BlueNRG-MS Bluetooth LE stack application command interface (ACI) User Manual (UM1865) at st.com + */ +#if !defined(BLUENRG_STACK_MODE) +#define BLUENRG_STACK_MODE (0x04) +#endif + +#endif // _BLUENRG_TARGTES_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef _BTLE_H_ +#define _BTLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "bluenrg_aci.h" +#include "ble_hci_const.h" +#include "bluenrg_hal_aci.h" +#include "stm32_bluenrg_ble.h" +#include "bluenrg_gap.h" +#include "bluenrg_gatt_server.h" + +extern uint16_t g_gap_service_handle; +extern uint16_t g_appearance_char_handle; +extern uint16_t g_device_name_char_handle; +extern uint16_t g_preferred_connection_parameters_char_handle; + +void btleInit(void); +void SPI_Poll(void); +void User_Process(void); +void setConnectable(void); +void setVersionString(uint8_t hwVersion, uint16_t fwVersion); +const char* getVersionString(void); +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type); + + +extern int btle_handler_pending; +extern void btle_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.h + * @author CL + * @version V1.0.1 + * @date 15-June-2014 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_BLUENRG_BLE_H +#define __STM32_BLUENRG_BLE_H + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdint.h> +#include "ble_gp_timer.h" +#include "ble_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup X-NUCLEO-IDB04A1 + * @{ + */ + +/** @addtogroup STM32_BLUENRG_BLE + * @{ + */ + +/** @defgroup STM32_BLUENRG_BLE_Exported_Functions + * @{ + */ + +// FIXME: add prototypes for BlueNRG here +void BlueNRG_RST(void); +uint8_t BlueNRG_DataPresent(void); +void BlueNRG_HW_Bootloader(void); +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size); +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, + uint8_t Nb_bytes1, + uint8_t Nb_bytes2); +void Clear_SPI_EXTI_Flag(void); + +void print_csv_time(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_BLUENRG_BLE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_debug.h" + +#ifndef __PAYLOAD_H__ +#define __PAYLOAD_H__ + +class UnitPayload +{ +public: + uint8_t length; + uint8_t id; + uint8_t *data; + uint8_t *idptr; + + + + void set_length(uint8_t l) { + length=l; + } + + void set_id(uint8_t i) { + id=i; + } + + void set_data(uint8_t* data1) { + for(int j=0;j<length;j++) + { + data[j]=data1[j]; + } + } + + uint8_t get_length() { + return length; + } + + uint8_t get_id() { + return id; + } + + uint8_t* get_data() { + return data; + } + +}; + +class Payload { + UnitPayload *payload; + int stringLength; + int payloadUnitCount; + +public: + Payload(const uint8_t *tokenString, uint8_t string_ength); + Payload(); + ~Payload(); + uint8_t getPayloadUnitCount(); + + uint8_t getIDAtIndex(int index); + uint8_t getLengthAtIndex(int index); + uint8_t* getDataAtIndex(int index); + int8_t getInt8AtIndex(int index); + uint16_t getUint16AtIndex(int index); + uint8_t* getSerializedAdDataAtIndex(int index); +}; + + +class PayloadUnit { +private: + uint8_t* lenPtr; + uint8_t* adTypePtr; + uint8_t* dataPtr; + +public: + PayloadUnit() { + lenPtr = NULL; + adTypePtr = NULL; + dataPtr = NULL; + } + + PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { + lenPtr = len; + adTypePtr = adType; + dataPtr = data; + } + + void setLenPtr(uint8_t *len) { + lenPtr = len; + } + + void setAdTypePtr(uint8_t *adType) { + adTypePtr = adType; + } + + void setDataPtr(uint8_t *data) { + dataPtr = data; + } + + uint8_t* getLenPtr() { + return lenPtr; + } + + uint8_t* getAdTypePtr() { + return adTypePtr; + } + + uint8_t* getDataPtr() { + return dataPtr; + } + + void printDataAsHex() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("0x%x ", dataPtr[i]); + } + PRINTF("\n"); + } + + void printDataAsString() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("%c", dataPtr[i]); + } + PRINTF("\n"); + } + +}; + +class PayloadPtr { +private: + PayloadUnit *unit; + int payloadUnitCount; +public: + PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + int stringLength = string_ength; + payloadUnitCount = 0; + + int index = 0; + while(index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + // allocate memory to unit + unit = new PayloadUnit[payloadUnitCount]; + int i = 0; + int nextUnitOffset = 0; + + while(i<payloadUnitCount) { + unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); + unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); + unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); + + nextUnitOffset += *unit[i].getLenPtr()+1; + i++; + + } + } + + PayloadUnit getUnitAtIndex(int index) { + return unit[index]; + } + + int getPayloadUnitCount() { return payloadUnitCount; } + + ~PayloadPtr() { + if(unit) delete[] unit; + + unit = NULL; + } +}; + +#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include "ble_status.h" +#include "ble_hal_types.h" + +#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do {\ + uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ + }while(0) + + +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); + +#endif // __UTIL_H__ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/mbed_lib.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "bluenrg", + "target_overrides": { + "K64F": { + "target.macros_add": ["BLUENRG_PIN_SPI_SCK=D13"] + }, + "DISCO_L475VG_IOT01A": { + "target.macros_add": ["BLUENRG_PIN_SPI_MOSI=PC_12", + "BLUENRG_PIN_SPI_MISO=PC_11", + "BLUENRG_PIN_SPI_nCS=PD_13", + "BLUENRG_PIN_SPI_RESET=PA_8", + "BLUENRG_PIN_SPI_IRQ=PE_6", + "BLUENRG_PIN_SPI_SCK=PC_10"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,37 @@ +{ + "name": "x-nucleo-idb0xa1", + "version": "2.2.0", + "description": "ST driver for the mbed BLE API.", + "keywords": [ + "expansion", + "board", + "x-nucleo", + "nucleo", + "ST", + "STM", + "Bluetooth", + "BLE" + ], + "author": "Andrea Palmieri", + "repository": { + "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git", + "type": "git" + }, + "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "extraIncludes": [ + "x-nucleo-idb0xa1", + "x-nucleo-idb0xa1/utils", + "x-nucleo-idb0xa1/platform", + "x-nucleo-idb0xa1/bluenrg-hci" + ], + "dependencies": { + "mbed-drivers": ">=0.11.3", + "ble": "^2.7.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,474 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.cpp + * @author STMicroelectronics + * @brief Implementation of BLEDeviceInstanceBase + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGDevice + * @brief BlueNRG BLE_API Device Adaptation + * @{ + */ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGDevice.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" + +#include "btle.h" +#include "ble_utils.h" +#include "ble_osal.h" + +#include "ble_debug.h" +#include "stm32_bluenrg_ble.h" + +extern "C" { + #include "ble_hci.h" + #include "bluenrg_utils.h" +} + +#define HEADER_SIZE 5 +#define MAX_BUFFER_SIZE 255 + +/** + * The singleton which represents the BlueNRG transport for the BLEDevice. + * + * See file 'bluenrg_targets.h' for details regarding the peripheral pins used! + */ +#include "bluenrg_targets.h" + +BlueNRGDevice bluenrgDeviceInstance(BLUENRG_PIN_SPI_MOSI, + BLUENRG_PIN_SPI_MISO, + BLUENRG_PIN_SPI_SCK, + BLUENRG_PIN_SPI_nCS, + BLUENRG_PIN_SPI_RESET, + BLUENRG_PIN_SPI_IRQ); + +/** +* BLE-API requires an implementation of the following function in order to +* obtain its transport handle. +*/ +BLEInstanceBase * +createBLEInstance(void) +{ + return (&bluenrgDeviceInstance); +} + +/**************************************************************************/ +/** + @brief Constructor + * @param mosi mbed pin to use for MOSI line of SPI interface + * @param miso mbed pin to use for MISO line of SPI interface + * @param sck mbed pin to use for SCK line of SPI interface + * @param cs mbed pin to use for not chip select line of SPI interface + * @param rst mbed pin to use for BlueNRG reset + * @param irq mbed pin for BlueNRG IRQ +*/ +/**************************************************************************/ +BlueNRGDevice::BlueNRGDevice(PinName mosi, + PinName miso, + PinName sck, + PinName cs, + PinName rst, + PinName irq) : + isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq) +{ + // Setup the spi for 8 bit data, low clock polarity, + // 1-edge phase, with an 8MHz clock rate + spi_.format(8, 0); + spi_.frequency(8000000); + + // Deselect the BlueNRG chip by keeping its nCS signal high + nCS_ = 1; + + wait_us(500); + + // Prepare communication between the host and the BlueNRG SPI interface + HCI_Init(); + + // Set the interrupt handler for the device + irq_.mode(PullDown); // set irq mode + irq_.rise(&HCI_Isr); +} + +/**************************************************************************/ +/** + @brief Destructor +*/ +/**************************************************************************/ +BlueNRGDevice::~BlueNRGDevice(void) +{ +} + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param hw_version The HW version is written to this parameter + * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise + */ +uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version) +{ + uint8_t status; + + status = getBlueNRGUpdaterHWVersion(hw_version); + + return (status); +} + +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns BLE_STATUS_SUCCESS on success, or a number + * not equal to 0 in case of error + * (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size) +{ + int status = program_device(fw_image, fw_size); + + return (status); +} + + +/** + * @brief Initialises anything required to start using BLE + * @param[in] instanceID + * The ID of the instance to initialize. + * @param[in] callback + * A callback for when initialization completes for a BLE + * instance. This is an optional parameter set to NULL when not + * supplied. + * + * @return BLE_ERROR_NONE if the initialization procedure was started + * successfully. + */ +ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback) +{ + if (isInitialized) { + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_ALREADY_INITIALIZED + }; + callback.call(&context); + return BLE_ERROR_ALREADY_INITIALIZED; + } + + // Init the BlueNRG/BlueNRG-MS stack + btleInit(); + + isInitialized = true; + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_NONE + }; + callback.call(&context); + + return BLE_ERROR_NONE; +} + + +/** + @brief Resets the BLE HW, removing any existing services and + characteristics + @param[in] void + @returns void +*/ +void BlueNRGDevice::reset(void) +{ + /* Reset BlueNRG SPI interface. Hold reset line to 0 for 1500us */ + rst_ = 0; + wait_us(1500); + rst_ = 1; + + /* Wait for the radio to come back up */ + wait_us(5000); +} + +/*! + @brief Wait for any BLE Event like BLE Connection, Read Request etc. + @param[in] void + @returns char * +*/ +void BlueNRGDevice::waitForEvent(void) +{ + bool must_return = false; + + do { + bluenrgDeviceInstance.processEvents(); + + if(must_return) return; + + __WFE(); /* it is recommended that SEVONPEND in the + System Control Register is NOT set */ + must_return = true; /* after returning from WFE we must guarantee + that conrol is given back to main loop before next WFE */ + } while(true); + +} + +/*! + @brief get GAP version + @brief Get the BLE stack version information + @param[in] void + @returns char * + @returns char * +*/ +const char *BlueNRGDevice::getVersion(void) +{ + return getVersionString(); +} + +/**************************************************************************/ +/*! + @brief get reference to GAP object + @param[in] void + @returns Gap& +*/ +/**************************************************************************/ +Gap &BlueNRGDevice::getGap() +{ + return BlueNRGGap::getInstance(); +} + +const Gap &BlueNRGDevice::getGap() const +{ + return BlueNRGGap::getInstance(); +} + +/**************************************************************************/ +/*! + @brief get reference to GATT server object + @param[in] void + @returns GattServer& +*/ +/**************************************************************************/ +GattServer &BlueNRGDevice::getGattServer() +{ + return BlueNRGGattServer::getInstance(); +} + +const GattServer &BlueNRGDevice::getGattServer() const +{ + return BlueNRGGattServer::getInstance(); +} + +/**************************************************************************/ +/*! + @brief shut down the BLE device + @param[out] error if any +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::shutdown(void) { + PRINTF("BlueNRGDevice::reset\n"); + + if (!isInitialized) { + return BLE_ERROR_INITIALIZATION_INCOMPLETE; + } + + /* Reset the BlueNRG device first */ + reset(); + + /* Shutdown the BLE API and BlueNRG glue code */ + ble_error_t error; + + /* GattServer instance */ + error = BlueNRGGattServer::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* GattClient instance */ + error = BlueNRGGattClient::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* Gap instance */ + error = BlueNRGGap::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + isInitialized = false; + + PRINTF("BlueNRGDevice::reset complete\n"); + return BLE_ERROR_NONE; + +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size) +{ + uint16_t byte_count; + uint8_t len = 0; + uint8_t char_ff = 0xff; + volatile uint8_t read_char; + + uint8_t i = 0; + volatile uint8_t tmpreg; + + uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00}; + uint8_t header_slave[HEADER_SIZE]; + + /* Select the chip */ + nCS_ = 0; + + /* Read the header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = (uint8_t)(tmpreg); + } + + if (header_slave[0] == 0x02) { + /* device is ready */ + byte_count = (header_slave[4]<<8)|header_slave[3]; + + if (byte_count > 0) { + + /* avoid to read more data that size of the buffer */ + if (byte_count > buff_size){ + byte_count = buff_size; + } + + for (len = 0; len < byte_count; len++){ + read_char = spi_.write(char_ff); + buffer[len] = read_char; + } + } + } + /* Release CS line to deselect the chip */ + nCS_ = 1; + + // Add a small delay to give time to the BlueNRG to set the IRQ pin low + // to avoid a useless SPI read at the end of the transaction + for(volatile int i = 0; i < 2; i++)__NOP(); + +#ifdef PRINT_CSV_FORMAT + if (len > 0) { + print_csv_time(); + for (int i=0; i<len; i++) { + PRINT_CSV(" %02x", buffer[i]); + } + PRINT_CSV("\n"); + } +#endif + + return len; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRGDevice::spiWrite(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t result = 0; + uint32_t i; + volatile uint8_t tmpreg; + + unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00}; + + disable_irq(); + + /* CS reset */ + nCS_ = 0; + + /* Exchange header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = tmpreg; + } + + if (header_slave[0] == 0x02) { + /* SPI is ready */ + if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { + + /* Buffer is big enough */ + for (i = 0; i < Nb_bytes1; i++) { + spi_.write(*(data1 + i)); + } + for (i = 0; i < Nb_bytes2; i++) { + spi_.write(*(data2 + i)); + } + } else { + /* Buffer is too small */ + result = -2; + } + } else { + /* SPI is not ready */ + result = -1; + } + + /* Release CS line */ + //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); + nCS_ = 1; + + enable_irq(); + + return result; +} + +bool BlueNRGDevice::dataPresent() +{ + return (irq_ == 1); +} + +void BlueNRGDevice::disable_irq() +{ + irq_.disable_irq(); +} + +void BlueNRGDevice::enable_irq() +{ + irq_.enable_irq(); +} + +void BlueNRGDevice::processEvents() { + btle_handler(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,68 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattClient.h" + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + uuid = uuidIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + + void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) { + lastHandle = lastHandleIn; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1477 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file BlueNRGGap.cpp + * @author STMicroelectronics + * @brief Implementation of BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGap + * @brief BlueNRG BLE_API GAP Adaptation + * @{ + */ + +#include "BlueNRGDevice.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_payload.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/* + * Utility to process GAP specific events (e.g., Advertising timeout) + */ +void BlueNRGGap::Process(void) +{ + if(AdvToFlag) { + AdvToFlag = false; + stopAdvertising(); + } + + if(ScanToFlag) { + ScanToFlag = false; + stopScan(); + } +} + +/**************************************************************************/ +/*! + @brief Sets the advertising parameters and payload for the device. + Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API + + @params[in] advData + The primary advertising data payload + @params[in] scanResponse + The optional Scan Response payload if the advertising + type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED + in \ref GapAdveritinngParams + + @returns \ref ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @retval BLE_ERROR_BUFFER_OVERFLOW + The proposed action would cause a buffer overflow. All + advertising payloads must be <= 31 bytes, for example. + + @retval BLE_ERROR_NOT_IMPLEMENTED + A feature was requested that is not yet supported in the + nRF51 firmware or hardware. + + @retval BLE_ERROR_PARAM_OUT_OF_RANGE + One of the proposed values is outside the valid range. + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) +{ + PRINTF("BlueNRGGap::setAdvertisingData\n\r"); + /* Make sure we don't exceed the advertising payload length */ + if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + PRINTF("Exceeded the advertising payload length\n\r"); + return BLE_ERROR_BUFFER_OVERFLOW; + } + + /* Make sure we have a payload! */ + if (advData.getPayloadLen() != 0) { + PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); + + /* Align the GAP Service Appearance Char value coherently + This setting is duplicate (see below GapAdvertisingData::APPEARANCE) + since BLE API has an overloaded function for appearance + */ + STORE_LE_16(deviceAppearance, advData.getAppearance()); + setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0])); + + + for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { + loadPtr.getUnitAtIndex(index); + + PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); + PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); + + switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { + /**< TX Power Level (in dBm) */ + case GapAdvertisingData::TX_POWER_LEVEL: + { + PRINTF("Advertising type: TX_POWER_LEVEL\n\r"); + int8_t enHighPower = 0; + int8_t paLevel = 0; + + int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); + tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); +#ifdef DEBUG + PRINTF("dbm=%d, ret=%d\n\r", dbm, ret); + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); +#endif + if(ret == BLE_STATUS_SUCCESS) { + aci_hal_set_tx_power_level(enHighPower, paLevel); + } + break; + } + /**< Appearance */ + case GapAdvertisingData::APPEARANCE: + { + PRINTF("Advertising type: APPEARANCE\n\r"); + + GapAdvertisingData::Appearance appearanceP; + memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2); + + PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]); + /* Align the GAP Service Appearance Char value coherently */ + setAppearance(appearanceP); + break; + } + + } // end switch + + } //end for + + } + + // update the advertising data in the shield if advertising is running + if (state.advertising == 1) { + tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS != ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload()); + if (ret) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + } + + _advData = advData; + _scanResponse = scanResponse; + + return BLE_ERROR_NONE; +} + +/* + * Utility to set ADV timeout flag + */ +void BlueNRGGap::setAdvToFlag(void) { + AdvToFlag = true; + signalEventsToProcess(); +} + +/* + * ADV timeout callback + */ +#ifdef AST_FOR_MBED_OS +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().stopAdvertising(); +} +#else +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().setAdvToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getAdvTimeout(); + t.detach(); /* disable the callback from the timeout */ +} +#endif /* AST_FOR_MBED_OS */ + +/* + * Utility to set SCAN timeout flag + */ +void BlueNRGGap::setScanToFlag(void) { + ScanToFlag = true; + signalEventsToProcess(); +} + +static void scanTimeoutCB(void) +{ + BlueNRGGap::getInstance().setScanToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getScanTimeout(); + t.detach(); /* disable the callback from the timeout */ +} + +/**************************************************************************/ +/*! + @brief Starts the BLE HW, initialising any services that were + added before this function was called. + + @param[in] params + Basic advertising details, including the advertising + delay, timeout and how the device should be advertised + + @note All services must be added before calling this function! + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ + +ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) +{ + tBleStatus ret; + int err; + + /* Make sure we support the advertising type */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { + /* ToDo: This requires a proper security implementation, etc. */ + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /* Check interval range */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { + /* Min delay is slightly longer for unconnectable devices */ + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } else { + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } + + /* Check timeout is zero for Connectable Directed */ + if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { + /* Timeout must be 0 with this type, although we'll never get here */ + /* since this isn't implemented yet anyway */ + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* Check timeout for other advertising types */ + if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && + (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* + * Advertising filter policy setting + * FIXME: the Security Manager should be implemented + */ + AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode(); + if(mode != ADV_POLICY_IGNORE_WHITELIST) { + ret = aci_gap_configure_whitelist(); + if(ret != BLE_STATUS_SUCCESS) { + PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret); + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } + + uint8_t advFilterPolicy = NO_WHITE_LIST_USE; + switch(mode) { + case ADV_POLICY_FILTER_SCAN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN; + break; + case ADV_POLICY_FILTER_CONN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN; + break; + case ADV_POLICY_FILTER_ALL_REQS: + advFilterPolicy = WHITE_LIST_FOR_ALL; + break; + default: + advFilterPolicy = NO_WHITE_LIST_USE; + break; + } + + /* Check the ADV type before setting scan response data */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED || + params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) { + + /* set scan response data */ + PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen()); + ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS!=ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + } else { + hci_le_set_scan_resp_data(0, NULL); + } + + setAdvParameters(); + PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType()); + + err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload()); + + if (err) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + + tBDAddr dummy_addr = { 0 }; + uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval; + uint16_t advIntervalMax = advIntervalMin + 1; + + err = hci_le_set_advertising_parameters( + advIntervalMin, + advIntervalMax, + params.getAdvertisingType(), + addr_type, + 0x00, + dummy_addr, + /* all channels */ 7, + advFilterPolicy + ); + + if (err) { + PRINTF("impossible to set advertising parameters\n\r"); + PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1); + PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy); + return BLE_ERROR_INVALID_PARAM; + } + + err = hci_le_set_advertise_enable(0x01); + if (err) { + PRINTF("impossible to start advertising\n\r"); + return BLE_ERROR_UNSPECIFIED; + } + + if(params.getTimeout() != 0) { + PRINTF("!!! attaching adv to!!!\n"); +#ifdef AST_FOR_MBED_OS + minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000)); +#else + advTimeout.attach(advTimeoutCB, params.getTimeout()); +#endif + } + + return BLE_ERROR_NONE; + +} + + +/**************************************************************************/ +/*! + @brief Stops the BLE HW and disconnects from any devices + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::stopAdvertising(void) +{ + if(state.advertising == 1) { + + int err = hci_le_set_advertise_enable(0); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + PRINTF("Advertisement stopped!!\n\r") ; + //Set GapState_t::advertising state + state.advertising = 0; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason) +{ + tBleStatus ret; + + ret = aci_gap_terminate(connectionHandle, reason); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_COMMAND_DISALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason) +{ + return disconnect(m_connectionHandle, reason); +} + +/**************************************************************************/ +/*! + @brief Sets the 16-bit connection handle + + @param[in] conn_handle + Connection Handle which is set in the Gap Instance + + @returns void +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionHandle(uint16_t conn_handle) +{ + m_connectionHandle = conn_handle; +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit connection handle + + @param[in] void + + @returns uint16_t + Connection Handle of the Gap Instance +*/ +/**************************************************************************/ +uint16_t BlueNRGGap::getConnectionHandle(void) +{ + return m_connectionHandle; +} + +/**************************************************************************/ +/*! + @brief Sets the BLE device address. SetAddress will reset the BLE + device and re-initialize BTLE. Will not start advertising. + + @param[in] type + Type of Address + + @param[in] address[6] + Value of the Address to be set + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address) +{ + if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if(type == BLEProtocol::AddressType::PUBLIC){ + tBleStatus ret = aci_hal_write_config_data( + CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + address + ); + if(ret != BLE_STATUS_SUCCESS) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } else if (type == BLEProtocol::AddressType::RANDOM_STATIC) { + // ensure that the random static address is well formed + if ((address[5] & 0xC0) != 0xC0) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // thanks to const correctness of the API ... + tBDAddr random_address = { 0 }; + memcpy(random_address, address, sizeof(random_address)); + int err = hci_le_set_random_address(random_address); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // It is not possible to get the bluetooth address when it is set + // store it locally in class data member + memcpy(bdaddr, address, sizeof(bdaddr)); + } else { + // FIXME random addresses are not supported yet + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + // if we're here then the address was correctly set + // commit it inside the addr_type + addr_type = type; + isSetAddress = true; + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Returns boolean if the address of the device has been set + or not + + @returns bool + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +bool BlueNRGGap::getIsSetAddress() +{ + return isSetAddress; +} + +/**************************************************************************/ +/*! + @brief Returns the address of the device if set + + @returns Pointer to the address if Address is set else NULL + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) +{ + uint8_t bdaddr[BDADDR_SIZE]; + uint8_t data_len_out; + + // precondition, check that pointers in input are valid + if (typeP == NULL || address == NULL) { + return BLE_ERROR_INVALID_PARAM; + } + + if (addr_type == BLEProtocol::AddressType::PUBLIC) { + tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr); + if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) { + return BLE_ERROR_UNSPECIFIED; + } + } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) { + // FIXME hci_read_bd_addr and + // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1 + // does not work, use the address stored in class data member + memcpy(bdaddr, this->bdaddr, sizeof(bdaddr)); + } else { + // FIXME: should be implemented with privacy features + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + *typeP = addr_type; + memcpy(address, bdaddr, BDADDR_SIZE); + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief obtains preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + + if (!g_preferred_connection_parameters_char_handle) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // Peripheral preferred connection parameters are an array of 4 uint16_t + uint8_t parameters_packed[parameter_size * 4]; + uint16_t bytes_read = 0; + + tBleStatus err = aci_gatt_read_handle_value( + g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE, + sizeof(parameters_packed), + &bytes_read, + parameters_packed + ); + + PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read); + + // check that the read succeed and the result have the expected length + if (err || bytes_read != sizeof(parameters_packed)) { + return BLE_ERROR_UNSPECIFIED; + } + + // memcpy field by field + memcpy(¶ms->minConnectionInterval, parameters_packed, parameter_size); + memcpy(¶ms->maxConnectionInterval, ¶meters_packed[parameter_size], parameter_size); + memcpy(¶ms->slaveLatency, ¶meters_packed[2 * parameter_size], parameter_size); + memcpy(¶ms->connectionSupervisionTimeout, ¶meters_packed[3 * parameter_size], parameter_size); + + return BLE_ERROR_NONE; +} + + +/**************************************************************************/ +/*! + @brief sets preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + uint8_t parameters_packed[parameter_size * 4]; + + // ensure that parameters are correct + // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC + if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) && + params->minConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) && + params->maxConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (params->slaveLatency > 0x01F3) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) && + params->connectionSupervisionTimeout != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // copy the parameters inside the byte array + memcpy(parameters_packed, ¶ms->minConnectionInterval, parameter_size); + memcpy(¶meters_packed[parameter_size], ¶ms->maxConnectionInterval, parameter_size); + memcpy(¶meters_packed[2 * parameter_size], ¶ms->slaveLatency, parameter_size); + memcpy(¶meters_packed[3 * parameter_size], ¶ms->connectionSupervisionTimeout, parameter_size); + + tBleStatus err = aci_gatt_update_char_value( + g_gap_service_handle, + g_preferred_connection_parameters_char_handle, + /* offset */ 0, + sizeof(parameters_packed), + parameters_packed + ); + + if (err) { + PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ; + switch (err) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief updates preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) +{ + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(gapRole == Gap::CENTRAL) { + ret = aci_gap_start_connection_update(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout, + CONN_L1, CONN_L2); + } else { + ret = aci_l2cap_connection_parameter_update_request(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout); + } + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case ERR_COMMAND_DISALLOWED: + case BLE_STATUS_NOT_ALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sets the Device Name Characteristic + + @param[in] deviceName + pointer to device name to be set + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) +{ + tBleStatus ret; + uint8_t nameLen = 0; + + nameLen = strlen((const char*)deviceName); + PRINTF("DeviceName Size=%d\n\r", nameLen); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_device_name_char_handle, + 0, + nameLen, + deviceName); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Gets the Device Name Characteristic + + @param[in] deviceName + pointer to device name + + @param[in] lengthP + pointer to device name length + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) +{ + tBleStatus ret; + + ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + *lengthP, + (uint16_t *)lengthP, + deviceName); + PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } +} + +/**************************************************************************/ +/*! + @brief Sets the Device Appearance Characteristic + + @param[in] appearance + device appearance + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance) +{ + tBleStatus ret; + uint8_t deviceAppearance[2]; + + STORE_LE_16(deviceAppearance, appearance); + PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_appearance_char_handle, + 0, 2, (uint8_t *)deviceAppearance); + if (BLE_STATUS_SUCCESS == ret){ + return BLE_ERROR_NONE; + } + + PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Gets the Device Appearance Characteristic + + @param[in] appearance + pointer to device appearance value + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) +{ + tBleStatus ret; + uint16_t lengthP = 2; + + ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + lengthP, + &lengthP, + (uint8_t*)appearanceP); + PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + +} + +GapScanningParams* BlueNRGGap::getScanningParams(void) +{ + return &_scanningParams; +} + +static void makeConnection(void) +{ + BlueNRGGap::getInstance().createConnection(); +} + +void BlueNRGGap::Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI) +{ + switch (reason) { + case DEVICE_FOUND: + { + GapAdvertisingParams::AdvertisingType_t type; + bool isScanResponse = false; + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * Private Random Address + * => scan_results = FALSE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type); + if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV || + (addr_type == RESOLVABLE_PRIVATE_ADDR || + addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) { + return; + } + + switch(adv_type) { + case ADV_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + break; + case ADV_DIRECT_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED; + break; + case ADV_SCAN_IND: + case SCAN_RSP: + type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED; + isScanResponse = true; + break; + case ADV_NONCONN_IND: + type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED; + break; + default: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + } + + PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n", + *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + if(!_connecting) { + processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data); + } + PRINTF("!!!After processAdvertisementReport\n\r"); + } + break; + + case DISCOVERY_COMPLETE: + // The discovery is complete. If this is due to a stop scanning (i.e., the device + // we are interested in has been found) and a connection has been requested + // then we start the device connection. + PRINTF("DISCOVERY_COMPLETE\n\r"); + _scanning = false; + + // Since the DISCOVERY_COMPLETE event can be received during the scanning interval, + // we need to delay the starting of connection + uint16_t delay = (_scanningParams.getInterval()*0.625); + +#ifdef AST_FOR_MBED_OS + if(_connecting) { + minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay)); + } +#else + Clock_Wait(delay); + if(_connecting) { + makeConnection(); + } +#endif /* AST_FOR_MBED_OS */ + + break; + } +} + +ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) +{ + + tBleStatus ret = BLE_STATUS_SUCCESS; + + // Stop ADV before scanning + /* + if (state.advertising == 1) { + stopAdvertising(); + } + */ + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * White List is empty + * => scan operation = FAILURE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + uint8_t whiteListSize = whitelistAddresses.size; + if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + ret = btleStartRadioScan(scanningParams.getActiveScanning(), + scanningParams.getInterval(), + scanningParams.getWindow(), + addr_type); + + PRINTF("Scanning...\n\r"); + PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000); + PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000); + //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval()); + //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1); + //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2); + if (BLE_STATUS_SUCCESS == ret){ + PRINTF("Observation Procedure Started\n"); + _scanning = true; + + if(scanningParams.getTimeout() != 0) { + PRINTF("!!! attaching scan to!!!\n"); + scanTimeout.attach(scanTimeoutCB, scanningParams.getTimeout()); + } + + return BLE_ERROR_NONE; + } + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + switch (ret) { + case BLE_STATUS_INVALID_CID: + PRINTF("Observation Procedure not implemented!!!\n\r"); + return BLE_ERROR_NOT_IMPLEMENTED; + default: + PRINTF("Observation Procedure failed (0x%02X)\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } + +} + +ble_error_t BlueNRGGap::stopScan() { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(_scanning) { + ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC); + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Discovery Procedure Terminated\n"); + return BLE_ERROR_NONE; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief set Tx power level + @param[in] txPower Transmission Power level + @returns ble_error_t +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setTxPower(int8_t txPower) +{ + tBleStatus ret; + + int8_t enHighPower = 0; + int8_t paLevel = 0; + + ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + ret = aci_hal_set_tx_power_level(enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief get permitted Tx power values + @param[in] values pointer to pointer to permitted power values + @param[in] num number of values +*/ +/**************************************************************************/ +void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { + static const int8_t permittedTxValues[] = { + -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8 + }; + + *valueArrayPP = permittedTxValues; + *countP = sizeof(permittedTxValues) / sizeof(int8_t); +} + +/**************************************************************************/ +/*! + @brief Set advertising parameters according to the current state + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setAdvParameters(void) +{ + uint32_t advIntMS; + + if(state.connected == 1) { + advIntMS = (conn_min_interval*1.25)-GUARD_INT; + advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS); + + PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval); + } else { + advInterval = _advParams.getIntervalInADVUnits(); + } +} + +/**************************************************************************/ +/*! + @brief Set connection parameters according to the current state (ADV and/or SCAN) + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionParameters(void) +{ + if (state.connected == 1) { + + PRINTF("state.connected=1\r\n"); + scanInterval = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(conn_min_interval*1.25); + scanWindow = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(((conn_min_interval*1.25)/100)*60); // scanWin ~= 60%(scanInt) + + } else if (state.advertising == 1) { + + if (_scanningParams.getInterval() < advInterval) { + PRINTF("state.adv=1 scanInterval<advInterval\r\n"); + scanInterval = advInterval; + scanWindow = advInterval; + } else { + PRINTF("state.adv=1 scanInterval>=advInterval\r\n"); + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + } + + if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms + conn_min_interval = MAX_INT_CONN; + conn_max_interval = MAX_INT_CONN; + } else { + conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + } + + } else { + + PRINTF("state.adv = 0\r\n"); + + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) || + SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms + conn_min_interval = DEF_INT_CONN; + conn_max_interval = DEF_INT_CONN; + } else { + conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + } + } + PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval)); + PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow)); + PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25)); + PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25)); + +} + +ble_error_t BlueNRGGap::createConnection () +{ + tBleStatus ret; + + /* + Before creating connection, set parameters according + to previous or current procedure (ADV and/or SCAN) + */ + setConnectionParameters(); + + /* + Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, + Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max + */ + ret = aci_gap_create_connection(scanInterval, + scanWindow, + _peerAddrType, + (unsigned char*)_peerAddr, + addr_type, + conn_min_interval, conn_max_interval, 0, + SUPERV_TIMEOUT, CONN_L1, CONN_L1); + + //_connecting = false; + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Connection started.\n"); + _connecting = false; + return BLE_ERROR_NONE; + } +} + +ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) +{ + /* avoid compiler warnings about unused variables */ + (void)connectionParams; + + setScanParams(scanParams->getInterval(), + scanParams->getWindow(), + scanParams->getTimeout(), + scanParams->getActiveScanning() + ); + + // Save the peer address + for(int i=0; i<BDADDR_SIZE; i++) { + _peerAddr[i] = peerAddr[i]; + } + _peerAddrType = peerAddrType; + + _connecting = true; + + if(_scanning) { + stopScan(); + } else { + PRINTF("Calling createConnection from connect()\n\r"); + return createConnection(); + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the advertising policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode) +{ + advertisingPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the scanning policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode) +{ + scanningPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Get the current advertising policy filter mode. + + @returns The advertising policy filter mode. +*/ +/**************************************************************************/ +Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const +{ + return advertisingPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Get the current scanning policy filter mode. + + @returns The scanning policy filter mode. + +*/ +/**************************************************************************/ +Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const +{ + return scanningPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGap's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::reset(void) +{ + PRINTF("BlueNRGGap::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (Gap::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + AdvToFlag = false; + ScanToFlag = false; + + /* Clear derived class members */ + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + return BLE_ERROR_NONE; +} + +void BlueNRGGap::setConnectionInterval(uint16_t interval) { + conn_min_interval = interval; + conn_max_interval = interval; +} + +Gap::Role_t BlueNRGGap::getGapRole(void) +{ + return (gapRole); +} + +void BlueNRGGap::setGapRole(Gap::Role_t role) +{ + gapRole = role; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,403 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTClient + * @brief BlueNRG BLE_API GattClient Adaptation + * @{ + */ + +#include "BlueNRGGattClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +#include <new> +#include <assert.h> + +ble_error_t BlueNRGGattClient::createGattConnectionClient(Gap::Handle_t connectionHandle) +{ + if(MAX_ACTIVE_CONNECTIONS <= _numConnections) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + for(uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + + if(_connectionPool[i] == NULL) { + BlueNRGGattConnectionClient *gattConnectionClient = new(std::nothrow) BlueNRGGattConnectionClient(this, connectionHandle); + + if (gattConnectionClient == NULL) { + return BLE_ERROR_NO_MEM; + } + + _connectionPool[i] = gattConnectionClient; + _connectionPool[i]->onServiceDiscoveryTermination(terminationCallback); + _numConnections++; + + PRINTF("createGattConnectionClient: _connectionPool index=%d\r\n", i); + PRINTF("createGattConnectionClient: succesfully added new gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + break; + } + } + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattClient::removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason) +{ + + PRINTF("removeGattConnectionClient: connectionHandle=%d reason=0x%x\r\n", connectionHandle, reason); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("removeGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("removeGattConnectionClient: Found gattConnectionClient\r\n"); + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + PRINTF("removeGattConnectionClient: succesfully removed gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + + break; + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + + return BLE_ERROR_NONE; +} + +BlueNRGGattConnectionClient * BlueNRGGattClient::getGattConnectionClient(Gap::Handle_t connectionHandle) { + PRINTF("getGattConnectionClient\r\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("getGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("getGattConnectionClient: Found gattConnectionClient\r\n"); + return _connectionPool[i]; + } + } + + return NULL; +} + +void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code) { + + if(error_code != BLE_STATUS_SUCCESS) { + return; + } + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->gattProcedureCompleteCB(error_code); +} + +void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServicesCB(event_data_length, + attribute_data_length, + attribute_data_list); +} + +void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServiceCB(event_data_length, + handles_info_list); +} + +ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->findServiceChars(); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharsCB(event_data_length, + handle_value_pair_length, + handle_value_pair); +} + +void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharByUUIDCB(event_data_length, + attr_handle, + attr_value); +} + +void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->discAllCharacDescCB(event_data_length, + format, + handle_uuid_pair); +} + +void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charReadCB(event_data_length, + attribute_value); +} + +void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWritePrepareCB(event_data_length, + attribute_handle, + offset, + part_attr_value); +} + +void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWriteExecCB(event_data_length); +} + +ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattClient launchServiceDiscovery\n\r"); + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->launchServiceDiscovery(sc, cc, matchingServiceUUID, matchingCharacteristicUUIDIn); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, matchingServiceUUID); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, startHandle, endHandle); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +bool BlueNRGGattClient::isServiceDiscoveryActive(void) const +{ + bool isSDActive = false; + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + isSDActive |= _connectionPool[i]->isServiceDiscoveryActive(); + } + } + + return isSDActive; +} + +void BlueNRGGattClient::terminateServiceDiscovery(void) +{ + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + _connectionPool[i]->terminateServiceDiscovery(); + } + } +} + +void BlueNRGGattClient::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; ++i) { + if (_connectionPool[i]) { + _connectionPool[i]->onServiceDiscoveryTermination(callback); + } + } +} + +ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->read(attributeHandle, offset); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->write(cmd, attributeHandle, length, value); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(characteristic.getConnectionHandle()); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverCharacteristicDescriptors(characteristic, discoveryCallback, terminationCallback); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattClient's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattClient::reset(void) +{ + PRINTF("BlueNRGGattClient::reset\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if(_connectionPool[i] != NULL) { + _connectionPool[i]->reset(); + + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + } + } + + return BLE_ERROR_NONE; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,816 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGattConnectionClient + * @brief BlueNRG GattConnectionClient Adaptation + * @{ + */ + +#include "BlueNRGGattConnectionClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" +#include "ble_debug.h" + +// #define PRINTF printf + +static uint8_t props_mask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 + }; + +void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code) +{ + if(error_code != BLE_STATUS_SUCCESS) { + _currentState = GATT_IDLE; + return; + } + + // Service Discovery complete +/* + if(_currentState != GATT_IDLE && + _currentState != GATT_DISCOVERY_TERMINATED && + _currentState != GATT_WRITE_CHAR && + _currentState != GATT_READ_CHAR) { +*/ + if(_currentState == GATT_SERVICE_DISCOVERY) { + findServiceChars(); + return; + } + + if(_currentState == GATT_CHAR_DESC_DISCOVERY) { + _currentState = GATT_IDLE; + if(charDescTerminationCallback != NULL) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { + _characteristic, + BLE_ERROR_NONE + }; + charDescTerminationCallback(¶ms); + } + return; + } + + // Read complete + if(_currentState == GATT_READ_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processReadResponse(&readCBParams); + free((void*)(readCBParams.data)); + readCBParams.data = NULL; + return; + } + + // Write complete + if(_currentState == GATT_WRITE_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); + return; + } +} + +void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numAttr; + + numAttr = (event_data_length - 1) / attribute_data_length; + + offset = 0; + for (i=0; i<numAttr; i++) { + startHandle = attribute_data_list[offset]; + endHandle = attribute_data_list[offset+2]; + + // UUID Type + if (attribute_data_length == 6) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4]; + PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(attribute_data_list+offset+4, UUID::LSB); + +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + + } + + PRINTF("Setup serviceIndex = %d\n\r", _numServices); + discoveredService[_numServices].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += attribute_data_length; + } + + PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr); + +} + +void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numHandlePairs; + + numHandlePairs = (event_data_length - 1) / 2; + + offset = 0; + for (i=0; i<numHandlePairs; i++) { + startHandle = handles_info_list[offset]; + endHandle = handles_info_list[offset+2]; + + PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle); + + + if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle); + uuid = _matchingServiceUUID.getShortUUID(); + } else { +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02x", longUUIDBytes[i]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB); + } + + discoveredService[i].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += 4; + } +} + +void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) +{ + // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + uint8_t i, numChar, offset; + + numChar = (event_data_length - 1) / handle_value_pair_length; + + PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar); + + offset = 0; + for (i=0; i<numChar; i++) { + // UUID Type + if (handle_value_pair_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(handle_value_pair+offset+5, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & handle_value_pair[offset+2]); + p._read = (props_mask[1] & handle_value_pair[offset+2])>>1; + p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2; + p._write = (props_mask[3] & handle_value_pair[offset+2])>>3; + p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4; + p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5; + p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = handle_value_pair[offset+2]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = handle_value_pair[offset]; + valueHandle = handle_value_pair[offset+3]; + lastHandle = valueHandle+1; + PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle); + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; + + offset += handle_value_pair_length; + } +} + +void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) +{ + // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + + PRINTF("serviceCharByUUIDCB\n\r"); + + // UUID Type + if (event_data_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = attr_value[4]<<8|attr_value[3]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(attr_value+3, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & attr_value[0]); + p._read = (props_mask[1] & attr_value[0])>>1; + p._writeWoResp = (props_mask[2] & attr_value[0])>>2; + p._write = (props_mask[3] & attr_value[0])>>3; + p._notify = (props_mask[4] & attr_value[0])>>4; + p._indicate = (props_mask[5] & attr_value[0])>>5; + p._authSignedWrite = (props_mask[6] & attr_value[0])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = attr_value[0]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = attr_handle; + valueHandle = attr_value[1]; + lastHandle = valueHandle+1; + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + // update the last handle and call the characteristic discovery callback for previous char + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; +} + +ble_error_t BlueNRGGattConnectionClient::findServiceChars(void) +{ + PRINTF("findServiceChars\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + + DiscoveredService *service; + + // complete the discovery of the last characteristic of the previous service. + // Its last handle wasn't known before this point + // update the handle and call the characteristic discovery callback. + if (_servIndex != 0 && _numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle()); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars = 0; + + // We finished chars discovery for all services + if(_servIndex >= _numServices) { + PRINTF("!!!We finished chars discovery for all services!!!\n\r"); + //_currentState = GATT_CHARS_DISCOVERY_COMPLETE; + + terminateServiceDiscovery(); + + return BLE_ERROR_NONE; + } + + service = &discoveredService[_servIndex]; + /* + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID()); + } else { + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); + } + */ + + if(serviceDiscoveryCallback) { + serviceDiscoveryCallback(service); + } + + PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex); + //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle()); + + if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) { + PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r"); + ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle()); + } else { + + uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID()); + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; +#ifdef DEBUG + PRINTF("findServiceChars C UUID-"); + for(unsigned i = 0; i < 2; i++) { + PRINTF("%02X", short_uuid[i]); + } + PRINTF("\n\r"); +#endif + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID(); +#ifdef DEBUG + PRINTF("(findServiceChars) C UUID-"); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", uuid[i]); + } + PRINTF("\r\n"); +#endif + } + + ret = aci_gatt_disc_charac_by_uuid(_connectionHandle, + service->getStartHandle(), + service->getEndHandle(), + uuid_type, + uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _servIndex++; + } + + PRINTF("findServiceChars ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + unsigned j; + + if(isServiceDiscoveryActive()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if(!sc && !cc) { + // nothing to do + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r"); + return BLE_ERROR_NONE; + } + + serviceDiscoveryCallback = sc; + characteristicDiscoveryCallback = cc; + _matchingServiceUUID = matchingServiceUUID; + _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn; + + //reset services + _numServices = 0; + _numChars = 0; + _servIndex = 0; + for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) { + discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE); + } + + if(matchingServiceUUID == BLE_UUID_UNKNOWN) { + + // Wildcard: search for all services + PRINTF("Wildcard: search for all services\r\n"); + ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle); + + } else { + PRINTF("search for specific services\r\n"); + + uint8_t type = matchingServiceUUID.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID()); +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x"); + for(j = 0; j < 2; j++) { + PRINTF("%02X", short_uuid[j]); + } + PRINTF("\n\r"); +#endif + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; + + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)matchingServiceUUID.getBaseUUID(); + +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x"); + for(j = 0; j < 16; j++) { + PRINTF("%02X", uuid[j]); + } + PRINTF("\n\r"); +#endif + } + + // search for specific service by UUID + ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_SERVICE_DISCOVERY; + } + + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)matchingServiceUUID; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)startHandle; + (void)endHandle; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const +{ + if(_currentState == GATT_SERVICE_DISCOVERY) { + return true; + } + + return false; +} + +void BlueNRGGattConnectionClient::terminateServiceDiscovery(void) +{ + _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED; + + if (terminationCallback) { + terminationCallback(_connectionHandle); + } +} + +void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value) +{ + // copy the data read, they will be forwarded to the user once the procedure + // has completed + readCBParams.connHandle = _connectionHandle; + readCBParams.offset = 0; + readCBParams.len = event_data_length; + readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length)); + memcpy((void*)(readCBParams.data), attribute_value, event_data_length); +} + +ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + /* avoid compiler warnings about unused variables */ + (void)offset; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // Save the attribute_handle not provided by evt_att_read_resp + gattc->readCBParams.handle = attributeHandle; + + ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle); + + if(ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_READ_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } +} + +void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) +{ + // Update the write response params + writeCBParams.handle = attribute_handle; + writeCBParams.offset = offset; + writeCBParams.len = event_data_length-4; //(?) + writeCBParams.data = part_attr_value; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length) +{ + /* avoid compiler warnings about unused variables */ + (void)event_data_length; + + writeCBParams.connHandle = _connectionHandle; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + /* avoid compiler warnings about unused variables */ + (void)cmd; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // We save the write response params (used by the callback) because + // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE + gattc->writeCBParams.connHandle = _connectionHandle; + gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD; + gattc->writeCBParams.handle = attributeHandle; + gattc->writeCBParams.offset = 0; + gattc->writeCBParams.len = length; + gattc->writeCBParams.data = value; + + ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); + + if (ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_WRITE_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } + +} + +void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + GattAttribute::Handle_t attHandle; + UUID uuid; + uint8_t i, numCharacDesc, offset, handle_uuid_length; + + handle_uuid_length = 4; //Handle + UUID_16 + if (format == 2) + handle_uuid_length = 18; //Handle + UUID_128 + + numCharacDesc = (event_data_length - 1) / handle_uuid_length; + + offset = 0; + + PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n", + event_data_length, format); + + + for (i=0; i<numCharacDesc; i++) { + memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle)); + + // UUID Type + if (handle_uuid_length == 4) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2]; + PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB); +#ifdef DEBUG + PRINTF("D UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + } + + if(charDescDiscoveryCallback != NULL) { + CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { + _characteristic, + DiscoveredCharacteristicDescriptor( + _characteristic.getGattClient(), + _connectionHandle, + attHandle, + uuid + ) + }; + charDescDiscoveryCallback(¶ms); + } + + _numCharDesc++; + + offset += handle_uuid_length; + } +} + +ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { + + tBleStatus ret; + + if(_currentState != GATT_IDLE) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + charDescDiscoveryCallback = discoveryCallback; + charDescTerminationCallback = terminationCallback; + + GattAttribute::Handle_t valueHandle = characteristic.getValueHandle(); + GattAttribute::Handle_t lastHandle = characteristic.getLastHandle(); + + PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle); + ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle); + + if (ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_CHAR_DESC_DISCOVERY; + _characteristic = characteristic; + return BLE_ERROR_NONE; + } + switch (ret) { + case BLE_STATUS_INVALID_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattConnectionClient::reset(void) { + PRINTF("BlueNRGGattConnectionClient::reset\n"); + + /* Clear all state, including private members */ + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + _numServices = 0; + _servIndex = 0; + _numChars = 0; + _numCharDesc = 0; + + /* Clear class members */ + memset(discoveredService, 0, sizeof(discoveredService)); + memset(discoveredChar, 0, sizeof(discoveredChar)); + + // free response if allocated + if(readCBParams.data) { + free((void*)(readCBParams.data)); + } + + return BLE_ERROR_NONE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,755 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTSERVER + * @brief BlueNRG BLE_API GattServer Adaptation + * @{ + */ + +#include "BlueNRGGattServer.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/**************************************************************************/ +/*! + @brief Adds a new service to the GATT table on the peripheral + + @params[in] service + Pointer to instance of the Gatt Server to add + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::addService(GattService &service) +{ + /* ToDo: Make sure we don't overflow the array, etc. */ + /* ToDo: Make sure this service UUID doesn't already exist (?) */ + /* ToDo: Basic validation */ + + tBleStatus ret; + uint8_t type; + uint16_t short_uuid; + uint8_t primary_short_uuid[2]; + uint8_t primary_base_uuid[16]; + uint8_t char_base_uuid[16]; + const uint8_t *base_uuid; + const uint8_t *base_char_uuid; + + uint8_t charsCount = service.getCharacteristicCount(); + const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount; + + // check that there is enough characteristics left in the + // characteristic array. + if (charsCount > available_characteristics) { + PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics); + return BLE_ERROR_NO_MEM; + } + + const uint16_t maxAttrRecords = computeAttributesRecord(service); + + type = (service.getUUID()).shortOrLong(); + PRINTF("AddService(): Type:%d\n\r", type); + + /* Add the service to the BlueNRG */ + short_uuid = (service.getUUID()).getShortUUID(); + STORE_LE_16(primary_short_uuid, short_uuid); + + if(type==UUID::UUID_TYPE_LONG) { + base_uuid = (service.getUUID()).getBaseUUID(); + + COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]); + } + + ret = BLE_STATUS_SUCCESS; + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_serv(UUID_TYPE_16, + primary_short_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_serv(UUID_TYPE_128, + primary_base_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_OUT_OF_HANDLE: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case ERR_UNSPECIFIED_ERROR: + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_ERROR: + default: + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + + + service.setHandle(servHandle); + //serviceHandleVector.push_back(servHandle); + PRINTF("added servHandle handle =%u\n\r", servHandle); + uint16_t bleCharacteristic; + + //iterate to include all characteristics + for (uint8_t i = 0; i < charsCount; i++) { + GattCharacteristic *p_char = service.getCharacteristic(i); + uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); + + uint8_t int_8_uuid[2]; + STORE_LE_16(int_8_uuid, char_uuid); + + type = (p_char->getValueAttribute().getUUID()).shortOrLong(); + + if(type==UUID::UUID_TYPE_LONG) { + base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); +#ifdef DEBUG + for(uint8_t j=0; j<16; j++) { + PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]); + } + PRINTF("\n\r"); +#endif + COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]); + } + + PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); + /* + * Gatt_Evt_Mask -> HardCoded (0) + * Encryption_Key_Size -> Hardcoded (16) + * isVariable (variable length value field) -> Hardcoded (1) + */ + uint8_t Gatt_Evt_Mask = 0x0; + + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP; + } + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; + } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_16, + int_8_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_128, + char_base_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + case BLE_STATUS_CHARAC_ALREADY_EXISTS: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); + + p_characteristics[characteristicCount++] = p_char; + /* Set the characteristic value handle */ + p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE); + PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle()); + + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + ble_error_t err = write(p_char->getValueAttribute().getHandle(), + p_char->getValueAttribute().getValuePtr(), + p_char->getValueAttribute().getLength(), false /* localOnly */); + if (err) { + PRINTF("ERROR HERE !!!!\r\n"); + return err; + } + } + + // add descriptors now + uint16_t descHandle = 0; + PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); + + for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { + GattAttribute *descriptor = p_char->getDescriptor(descIndex); + uint8_t desc_uuid[16] = { 0 }; + + + uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT; + STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID()); + + if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) { + desc_uuid_type = CHAR_DESC_TYPE_128_BIT; + const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID(); + + COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]); + } + + ret = aci_gatt_add_char_desc(service.getHandle(), + bleCharacteristic, + desc_uuid_type, + desc_uuid, + descriptor->getMaxLength(), + descriptor->getLength(), + descriptor->getValuePtr(), + CHAR_DESC_SECURITY_PERMISSION, + CHAR_DESC_ACCESS_PERMISSION, + GATT_NOTIFY_ATTRIBUTE_WRITE, + MIN_ENCRY_KEY_SIZE, + CHAR_ATTRIBUTE_LEN_IS_FIXED, + &descHandle); + PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); + + switch (ret) { + case BLE_STATUS_SUCCESS: + PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); + descriptor->setHandle(descHandle); + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_INVALID_OPERATION: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + } + + serviceCount++; + + //FIXME: There is no GattService pointer array in GattServer. + // There should be one? (Only the user is aware of GattServices!) Report to forum. + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on char handle + + @param[in] attributeHandle + The handle of the GattCharacteristic to read from + @param[in] buffer + Buffer to hold the the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes read into the buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) +{ + tBleStatus ret; + uint16_t charHandle = attributeHandle; + + ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer); + + if(ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on the connection + and char handle + + @param[in] connectionHandle + The handle of the connection + @param[in] attributeHandle + The handle of the GattCharacteristic to write to + @param[in] buffer + Data to use when updating the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes in buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + uint8_t buffer[], + uint16_t *lengthP) { + + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)attributeHandle; + (void)buffer; + (void)lengthP; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t, + const uint8_t[], + uint16_t, bool localOnly) { + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)localOnly; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly) +{ + /* avoid compiler warnings about unused variables */ + (void)localOnly; + + // check that the len of the data to write are compatible with the characteristic + GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle); + if (!characteristic) { + PRINTF("characteristic not found\r\n"); + return BLE_ERROR_INVALID_PARAM; + } + + // if the attribute handle is the attribute handle of the characteristic value then + // write the value + if (attributeHandle == characteristic->getValueHandle()) { + // assert the len in input is correct for this characteristic + const GattAttribute& value_attribute = characteristic->getValueAttribute(); + + // reject write if the lenght exceed the maximum lenght of this attribute + if (value_attribute.getMaxLength() < len) { + PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + // reject write if the attribute size is fixed and the lenght in input is different than the + // length of the attribute. + if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) { + PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + tBleStatus ret; + + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + + PRINTF("updating bleCharacteristic valueHandle=%u,\ + corresponding serviceHandle=%u len=%d\n\r", + attributeHandle, bleCharHandleMap.find(charHandle)->second, len); + + /* + * If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. + */ + ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } else { + // write this handle has a descriptor handle + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + uint16_t service_handle = bleCharHandleMap.find(charHandle)->second; + + tBleStatus ret = aci_gatt_set_desc_value( + service_handle, + charHandle, + attributeHandle, + 0, + len, + buffer + ); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } +} + +/**************************************************************************/ +/*! + @brief Reads a value according to the handle provided + + @param[in] attributeHandle + The handle of the attribute to read from + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle) +{ + uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); + + GattReadCallbackParams readParams; + readParams.handle = attributeHandle; + + //PRINTF("readParams.handle = %d\n\r", readParams.handle); + HCIDataReadEvent(&readParams); + + //EXIT: + if(gapConnectionHandle != 0){ + //PRINTF("Calling aci_gatt_allow_read\n\r"); + aci_gatt_allow_read(gapConnectionHandle); + } + + return BLE_ERROR_NONE; +} + +// ask if the write request should be accepted of rejected +// return 0 in case of success or an ATT error response in +// case of faillure +uint8_t BlueNRGGattServer::Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length, + const uint8_t* data) { + + GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle); + if(!characteristic) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF; + } + + // check if the data length is in range + if (characteristic->getValueAttribute().getMaxLength() < data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + // if the length of the characteristic value is fixed + // then the data in input should be of that length + if (characteristic->getValueAttribute().hasVariableLength() == false && + characteristic->getValueAttribute().getMaxLength() != data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + GattWriteAuthCallbackParams params = { + connection_handle, + attr_handle, + /* offset */ 0, + data_length, + data, + /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED + }; + + return characteristic->authorizeWrite(¶ms) & 0xFF; +} + +/**************************************************************************/ +/*! + @brief Returns the GattCharacteristic according to the handle provided + + @param[in] attrHandle + The handle of the attribute + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) +{ + GattCharacteristic *p_char = NULL; + int i; + uint16_t handle, handle_1; + + PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle); + for(i=0; i<characteristicCount; i++) + { + handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + PRINTF("handle(%d)=%d\n\r", i, handle); + if(i==characteristicCount-1)//Last Characteristic check + { + if(attrHandle>=handle) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); + break; + } + } + else { + handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + //Testing if attribute handle is between two Characteristic Handles + if(attrHandle>=handle && attrHandle<handle_1) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); + break; + } else continue; + } + } + + return p_char; +} + +void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { + this->handleDataWrittenEvent(params); +} + +void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { + PRINTF("Called HCIDataReadEvent\n\r"); + this->handleDataReadEvent(params); +} + +void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { + this->handleEvent(type, charHandle); +} + +void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { + this->handleDataSentEvent(count); +} + + +ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { + // <TODO> + return (ble_error_t)0; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::reset(void) +{ + PRINTF("BlueNRGGattServer::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (GattServer::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + /* Clear class members */ + memset(p_characteristics, 0, sizeof(p_characteristics)); + memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles)); + serviceCount = 0; + characteristicCount = 0; + + return BLE_ERROR_NONE; +} + + +/// compute the number of attributes needed by this service. +uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) { + uint16_t attribute_records = 1; + + for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) { + // add two attributes, one for the characteristic declaration + // and the other for the characteristic value. + attribute_records += 2; + + const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index); + const uint8_t properties = characteristic->getProperties(); + // if notify or indicate are present, two attributes are + // needed + if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) || + (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { + attribute_records += 2; + } + + // if broadcast is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) { + attribute_records += 2; + } + + // if extended properties flag is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) { + attribute_records += 2; + } + + attribute_records += characteristic->getDescriptorCount(); + } + + // for some reason, if there is just a service, this value should + // be equal to 5 + if (attribute_records == 1) { + attribute_records = 5; + } + + return attribute_records; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,421 @@ +/** + ****************************************************************************** + * @file ble_hci.c + * @author AMS/HESA Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "ble_gp_timer.h" +#include "ble_debug.h" + +#include "stm32_bluenrg_ble.h" + +#if BLE_CONFIG_DBG_ENABLE +#undef PRINTF +#endif + +#define HCI_LOG_ON 0 + +#define HCI_READ_PACKET_NUM_MAX (0x40) + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tListNode hciReadPktPool; +tListNode hciReadPktRxQueue; + +// betzw - DEBUG: +//#define POOL_CNT +#ifdef POOL_CNT +#include <stdio.h> +static unsigned int nr_hciReadPktPool; +static unsigned int lowest_nr_hciReadPktPool; +#endif // POOL_CNT + +/* pool of hci read packets */ +static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; + +static volatile uint8_t hci_timer_id; +static volatile uint8_t hci_timeout; + +void hci_timeout_callback(void) +{ + hci_timeout = 1; + return; +} + +void HCI_Init(void) +{ + uint8_t index; + +#ifdef POOL_CNT + nr_hciReadPktPool = 0; +#endif // POOL_CNT + + /* Initialize list heads of ready and free hci data packet queues */ + list_init_head (&hciReadPktPool); + list_init_head (&hciReadPktRxQueue); + + /* Initialize the queue of free hci data packets */ + for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) + { + list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif // POOL_CNT + } + +#ifdef POOL_CNT + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif // POOL_CNT +} + +#define HCI_PCK_TYPE_OFFSET 0 +#define EVENT_PARAMETER_TOT_LEN_OFFSET 2 + +/** + * Verify if HCI packet is correctly formatted. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * @return 0 if HCI packet is as expected + */ +int HCI_verify(const tHciDataPacket * hciReadPacket) +{ + const uint8_t *hci_pckt = hciReadPacket->dataBuff; + + if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) + return 1; /* Incorrect type. */ + + if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) + return 2; /* Wrong length (packet truncated or too long). */ + + return 0; +} + +void HCI_Process(void) +{ + tHciDataPacket * hciReadPacket = NULL; + +#ifdef POOL_CNT + printf("betzw(%s, %d): nr_hciReadPktPool = %u (lowest = %u)\r\n", __func__, __LINE__, + nr_hciReadPktPool, lowest_nr_hciReadPktPool); +#endif // POOL_CNT + + Disable_SPI_IRQ(); + uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); + /* process any pending events read */ + while(list_empty == FALSE) + { + list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + Enable_SPI_IRQ(); + HCI_Event_CB(hciReadPacket->dataBuff); + Disable_SPI_IRQ(); + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + list_empty = list_is_empty(&hciReadPktRxQueue); + } + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG. */ + HCI_HandleSPI(); + Enable_SPI_IRQ(); +} + +BOOL HCI_Queue_Empty(void) +{ + return list_is_empty(&hciReadPktRxQueue); +} + +/** + * When an interrupt is raised by BlueNRG, + * just signal that a new event (availability of SPI data to be read) + * needs to be processed. + */ +void HCI_Isr(void) +{ + signalEventsToProcess(); +} + +/** + * Now, SPI Data are handled in user space. + * In case it has to be called in ISR, take care to + * call Disable_SPI_IRQ/Enable_SPI_IRQ in a proper way. + * The calls Disable_SPI_IRQ/Enable_SPI_IRQ have not been removed + * from this code for backward compatibility. + */ +void HCI_HandleSPI(void) +{ + tHciDataPacket * hciReadPacket = NULL; + uint8_t data_len; + + Clear_SPI_EXTI_Flag(); + while(BlueNRG_DataPresent()){ + if (list_is_empty (&hciReadPktPool) == FALSE){ + + /* enqueueing a packet for read */ + list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool--; + if(nr_hciReadPktPool < lowest_nr_hciReadPktPool) + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif + + data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); + if(data_len > 0){ + hciReadPacket->data_len = data_len; + if(HCI_verify(hciReadPacket) == 0) { + list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); + } else { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else { + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else{ + // HCI Read Packet Pool is empty, wait for a free packet. + Clear_SPI_EXTI_Flag(); + return; + } + + Clear_SPI_EXTI_Flag(); + } +} + +void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){ +#if HCI_LOG_ON + PRINTF("HCI <- "); + for(int i=0; i < n_bytes1; i++) + PRINTF("%02X ", *((uint8_t*)data1 + i)); + for(int i=0; i < n_bytes2; i++) + PRINTF("%02X ", *((uint8_t*)data2 + i)); + PRINTF("\n"); +#endif + + Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); +} + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) +{ + hci_command_hdr hc; + + hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); + hc.plen= plen; + + uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; + header[0] = HCI_COMMAND_PKT; + Osal_MemCpy(header+1, &hc, sizeof(hc)); + + hci_write(header, param, sizeof(header), plen); +} + +static void move_list(tListNode * dest_list, tListNode * src_list) +{ + pListNode tmp_node; + + while(!list_is_empty(src_list)){ + list_remove_tail(src_list, &tmp_node); + list_insert_head(dest_list, tmp_node); + } +} + + /* It ensures that we have at least half of the free buffers in the pool. */ +static void free_event_list(void) +{ + tHciDataPacket * pckt; + + Disable_SPI_IRQ(); + + while(list_get_size(&hciReadPktPool) < HCI_READ_PACKET_NUM_MAX/2){ + list_remove_head(&hciReadPktRxQueue, (tListNode **)&pckt); + list_insert_tail(&hciReadPktPool, (tListNode *)pckt); + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG */ + HCI_HandleSPI(); + } + + Enable_SPI_IRQ(); +} + +int hci_send_req(struct hci_request *r, BOOL async) +{ + uint8_t *ptr; + uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + hci_event_pckt *event_pckt; + hci_uart_pckt *hci_hdr; + int to = DEFAULT_TIMEOUT; + struct timer t; + tHciDataPacket * hciReadPacket = NULL; + tListNode hciTempQueue; + + list_init_head(&hciTempQueue); + + free_event_list(); + + hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); + + if(async){ + return 0; + } + + /* Minimum timeout is 1. */ + if(to == 0) + to = 1; + + Timer_Set(&t, to); + + while(1) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + evt_le_meta_event *me; + int len; + + while(1){ + + Disable_SPI_IRQ(); + HCI_HandleSPI(); + Enable_SPI_IRQ(); + + if(Timer_Expired(&t)){ + goto failed; + } + if(!HCI_Queue_Empty()){ + break; + } + } + + /* Extract packet from HCI event queue. */ + Disable_SPI_IRQ(); + list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + + hci_hdr = (void *)hciReadPacket->dataBuff; + + if(hci_hdr->type == HCI_EVENT_PKT){ + + event_pckt = (void *) (hci_hdr->data); + + ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); + len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); + + switch (event_pckt->evt) { + + case EVT_CMD_STATUS: + cs = (void *) ptr; + + if (cs->opcode != opcode) + goto failed; + + if (r->event != EVT_CMD_STATUS) { + if (cs->status) { + goto failed; + } + break; + } + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_CMD_COMPLETE: + cc = (void *) ptr; + + if (cc->opcode != opcode) + goto failed; + + ptr += EVT_CMD_COMPLETE_SIZE; + len -= EVT_CMD_COMPLETE_SIZE; + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_LE_META_EVENT: + me = (void *) ptr; + + if (me->subevent != r->event) + break; + + len -= 1; + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, me->data, r->rlen); + goto done; + + case EVT_HARDWARE_ERROR: + goto failed; + + default: + break; + } + } + + /* If there are no more packets to be processed, be sure there is at list one + packet in the pool to process the expected event. + If no free packets are available, discard the processed event and insert it + into the pool. */ + if(list_is_empty(&hciReadPktPool) && list_is_empty(&hciReadPktRxQueue)){ + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); + hciReadPacket=NULL; + } + else { + /* Insert the packet in a different queue. These packets will be + inserted back in the main queue just before exiting from send_req(), so that + these events can be processed by the application. + */ + list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); + hciReadPacket = NULL; + } + + HCI_HandleSPI(); + + Enable_SPI_IRQ(); + + } + +failed: + if(hciReadPacket != NULL) { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + move_list(&hciReadPktRxQueue, &hciTempQueue); + Enable_SPI_IRQ(); + return -1; + +done: + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + move_list(&hciReadPktRxQueue, &hciTempQueue); + + Enable_SPI_IRQ(); + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,837 @@ +/** + ****************************************************************************** + * @file ble_hci_le.c + * @author AMG RF Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +int hci_reset(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_RESET; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_disconnect(uint16_t handle, uint8_t reason) +{ + struct hci_request rq; + disconnect_cp cp; + uint8_t status; + + cp.handle = handle; + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) +{ + struct hci_request rq; + read_local_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + + *hci_version = resp.hci_version; + *hci_revision = btohs(resp.hci_revision); + *lmp_pal_version = resp.lmp_pal_version; + *manufacturer_name = btohs(resp.manufacturer_name); + *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); + + return 0; +} + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) +{ + struct hci_request rq; + le_read_buffer_size_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_BUFFER_SIZE; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *pkt_len = resp.pkt_len; + *max_pkt = resp.max_pkt; + + return 0; +} + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter) +{ + struct hci_request rq; + le_set_adv_parameters_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.min_interval = min_interval; + adv_cp.max_interval = max_interval; + adv_cp.advtype = advtype; + adv_cp.own_bdaddr_type = own_bdaddr_type; + adv_cp.direct_bdaddr_type = direct_bdaddr_type; + if(direct_bdaddr != NULL) + Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); + adv_cp.chan_map = chan_map; + adv_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_PARAMETERS; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_adv_data_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.length = length; + Osal_MemCpy(adv_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_DATA; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertise_enable(uint8_t enable) +{ + struct hci_request rq; + le_set_advertise_enable_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.enable = enable?1:0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter) +{ + struct hci_request rq; + le_set_scan_parameters_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.type = type; + scan_cp.interval = interval; + scan_cp.window = window; + scan_cp.own_bdaddr_type = own_bdaddr_type; + scan_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) +{ + struct hci_request rq; + le_set_scan_enable_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.enable = enable?1:0; + scan_cp.filter_dup = filter_dup; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_ENABLE; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_rand(uint8_t random_number[8]) +{ + struct hci_request rq; + le_rand_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_RAND; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + Osal_MemCpy(random_number, resp.random, 8); + + return 0; +} + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_scan_response_data_cp scan_resp_cp; + uint8_t status; + + Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); + scan_resp_cp.length = length; + Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; + rq.cparam = &scan_resp_cp; + rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) +{ + struct hci_request rq; + le_read_adv_channel_tx_power_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *tx_power_level = resp.level; + + return 0; +} + +int hci_le_set_random_address(tBDAddr bdaddr) +{ + struct hci_request rq; + le_set_random_address_cp set_rand_addr_cp; + uint8_t status; + + Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); + Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; + rq.cparam = &set_rand_addr_cp; + rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_read_bd_addr(tBDAddr bdaddr) +{ + struct hci_request rq; + read_bd_addr_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_BD_ADDR; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_BD_ADDR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); + + return 0; +} + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) +{ + struct hci_request rq; + le_create_connection_cp create_cp; + uint8_t status; + + Osal_MemSet(&create_cp, 0, sizeof(create_cp)); + create_cp.interval = interval; + create_cp.window = window; + create_cp.initiator_filter = initiator_filter; + create_cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); + create_cp.own_bdaddr_type = own_bdaddr_type; + create_cp.min_interval=min_interval; + create_cp.max_interval=max_interval; + create_cp.latency = latency; + create_cp.supervision_timeout=supervision_timeout; + create_cp.min_ce_length=min_ce_length; + create_cp.max_ce_length=max_ce_length; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN; + rq.cparam = &create_cp; + rq.clen = LE_CREATE_CONN_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_create_connection_cancel(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN_CANCEL; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) +{ + struct hci_request rq; + le_encrypt_cp params; + le_encrypt_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemCpy(params.key, key, 16); + Osal_MemCpy(params.plaintext, plaintextData, 16); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ENCRYPT; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + le_ltk_neg_reply_cp params; + le_ltk_neg_reply_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + params.handle = 1; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_LTK_NEG_REPLY; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CLEAR_WHITE_LIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0){ + return BLE_STATUS_TIMEOUT; + } + + return status; +} + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) +{ + struct hci_request rq; + le_add_device_to_white_list_cp params; + uint8_t status; + + params.bdaddr_type = bdaddr_type; + Osal_MemCpy(params.bdaddr, bdaddr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; + rq.cparam = ¶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/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1309 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB05A1 cp; + gap_init_rp resp; + + cp.role = role; + cp.privacy_enabled = privacy_enabled; + cp.device_name_char_len = device_name_char_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} +tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB04A1 cp; + gap_init_rp resp; + + cp.role = role; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + SlaveConnIntervMin = htobs(SlaveConnIntervMin); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + SlaveConnIntervMax = htobs(SlaveConnIntervMax); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB05A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.directed_adv_type = directed_adv_type; + cp.adv_interv_min = adv_interv_min; + cp.adv_interv_max = adv_interv_max; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB04A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_io_capability(uint8_t io_capability) +{ + struct hci_request rq; + uint8_t status; + gap_set_io_capability_cp cp; + + cp.io_capability = io_capability; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_IO_CAPABILITY; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode) +{ + struct hci_request rq; + gap_set_auth_requirement_cp cp; + uint8_t status; + + cp.mitm_mode = mitm_mode; + cp.oob_enable = oob_enable; + Osal_MemCpy(cp.oob_data, oob_data, 16); + cp.min_encryption_key_size = min_encryption_key_size; + cp.max_encryption_key_size = max_encryption_key_size; + cp.use_fixed_pin = use_fixed_pin; + cp.fixed_pin = htobl(fixed_pin); + cp.bonding_mode = bonding_mode; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) +{ + struct hci_request rq; + gap_set_author_requirement_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorization_enable = authorization_enable; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) +{ + struct hci_request rq; + gap_passkey_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.passkey = htobl(passkey); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_PASSKEY_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) +{ + struct hci_request rq; + gap_authorization_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorize = authorize; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB05A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + cp.own_address_type = own_address_type; + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB04A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) +{ + struct hci_request rq; + gap_set_undirected_connectable_cp cp; + uint8_t status; + + cp.own_addr_type = own_addr_type; + cp.adv_filter_policy = adv_filter_policy; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) +{ + struct hci_request rq; + gap_slave_security_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.bonding = bonding; + cp.mitm_protection = mitm_protection; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[32]; + uint8_t indx = 0; + + if (AdvLen > (sizeof(buffer)-1)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvLen; + indx++; + + Osal_MemCpy(buffer + indx, AdvData, AdvLen); + indx += AdvLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_UPDATE_ADV_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) +{ + struct hci_request rq; + gap_delete_ad_type_cp cp; + uint8_t status; + + cp.ad_type = ad_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_DELETE_AD_TYPE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required) +{ + struct hci_request rq; + gap_get_security_level_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; + rq.rparam = &resp; + rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *mitm_protection = resp.mitm_protection; + *bonding = resp.bonding; + *oob_data = resp.oob_data; + *passkey_required = resp.passkey_required; + + return resp.status; +} + +tBleStatus aci_gap_configure_whitelist(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) +{ + struct hci_request rq; + gap_terminate_cp cp; + uint8_t status; + + cp.handle = htobs(conn_handle); + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_clear_security_database(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) +{ + struct hci_request rq; + gap_allow_rebond_cp_IDB05A1 cp; + uint8_t status; + + cp.conn_handle = conn_handle; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_allow_rebond_IDB04A1(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_limited_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_general_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_name_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = use_reconn_addr; + indx++; + + Osal_MemCpy(buffer + indx, reconn_addr, 6); + indx += 6; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB05A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB04A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.use_reconn_addr = use_reconn_addr; + Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_start_selective_conn_establish_proc_cp cp; + uint8_t status; + + if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.num_whitelist_entries = num_whitelist_entries; + + Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_create_connection_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CREATE_CONNECTION; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; + rq.cparam = &procedure_code; + rq.clen = 1; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_connection_update_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) +{ + struct hci_request rq; + gap_send_pairing_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.force_rebond = force_rebond; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + gap_resolve_private_address_rp rp; + + Osal_MemCpy(cp.address, private_address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); + + return 0; +} +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + uint8_t status; + + Osal_MemCpy(cp.address, address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_set_broadcast_mode_cp cp; + uint8_t status; + uint8_t indx = 0; + uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; + + if (variable_size > sizeof(cp.var_len_data) ) + return BLE_STATUS_INVALID_PARAMS; + + cp.adv_interv_min = htobs(adv_interv_min); + cp.adv_interv_max = htobs(adv_interv_max); + cp.adv_type = adv_type; + cp.own_addr_type = own_addr_type; + + cp.var_len_data[indx] = adv_data_length; + indx++; + Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); + indx += adv_data_length; + cp.var_len_data[indx] = num_whitelist_entries; + indx ++; + Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_BROADCAST_MODE; + rq.cparam = &cp; + rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_observation_proc_cp cp; + uint8_t status; + + cp.scan_interval = scan_interval; + cp.scan_window = scan_window; + cp.scan_type = scan_type; + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_OBSERVATION_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) +{ + struct hci_request rq; + gap_is_device_bonded_cp cp; + uint8_t status; + + cp.peer_address_type = peer_address_type; + Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_IS_DEVICE_BONDED; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) +{ + struct hci_request rq; + gap_get_bonded_devices_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_BONDED_DEVICES; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (rp.status) { + return rp.status; + } + + *num_devices = rp.num_addr; + if(device_list != NULL) + Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1505 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.c +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : File with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_gatt_init(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INIT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[19]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, service_uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = service_type; + indx++; + + buffer[indx] = max_attr_records; + indx++; + + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle) +{ + struct hci_request rq; + gatt_include_serv_rp resp; + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + service_handle = htobs(service_handle); + Osal_MemCpy(buffer, &service_handle, 2); + indx += 2; + + included_start_handle = htobs(included_start_handle); + Osal_MemCpy(buffer+indx, &included_start_handle, 2); + indx += 2; + + included_end_handle = htobs(included_end_handle); + Osal_MemCpy(buffer+indx, &included_end_handle, 2); + indx += 2; + + if(included_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } else { + uuid_len = 16; + } + + buffer[indx] = included_uuid_type; + indx++; + + Osal_MemCpy(buffer + indx, included_uuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INCLUDE_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *included_handle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[25]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + buffer[indx] = charValueLen; + indx++; + + buffer[indx] = charProperties; + indx++; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *charHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle) +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = descValueMaxLen; + indx++; + + buffer[indx] = descValueLen; + indx++; + + if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + Osal_MemCpy(buffer + indx, descValue, descValueLen); + indx += descValueLen; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = accPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR_DESC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *descHandle = btohs(resp.handle); + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = charValOffset; + indx++; + + buffer[indx] = charValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charValue, charValueLen); + indx += charValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_char_cp cp; + + cp.service_handle = htobs(servHandle); + cp.char_handle = htobs(charHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_CHAR; + rq.cparam = &cp; + rq.clen = GATT_DEL_CHAR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_service(uint16_t servHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_serv_cp cp; + + cp.service_handle = htobs(servHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_inc_serv_cp cp; + + cp.service_handle = htobs(servHandle); + cp.inc_serv_handle = htobs(includeServHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_INC_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_INC_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) +{ + struct hci_request rq; + uint8_t status; + gatt_set_evt_mask_cp cp; + + cp.evt_mask = htobs(event_mask); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_EVT_MASK; + rq.cparam = &cp; + rq.clen = GATT_SET_EVT_MASK_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_exchange_config_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_EXCHANGE_CONFIG; + rq.cparam = &cp; + rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) +{ + struct hci_request rq; + uint8_t status; + att_find_info_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_INFO_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_find_by_type_value_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + Osal_MemCpy(cp.uuid, uuid, 2); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_group_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_prepare_write_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.value_offset = htobs(value_offset); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) +{ + struct hci_request rq; + uint8_t status; + att_execute_write_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.execute = execute; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_prim_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_prim_service_by_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; + rq.cparam = &cp; + rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, + uint16_t end_service_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_find_included_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_service_handle); + cp.end_handle = htobs(end_service_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_of_serv_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_attr_handle = htobs(start_attr_handle); + cp.end_attr_handle = htobs(end_attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t charUuidType, + const uint8_t* charUuid) +{ + struct hci_request rq; + uint8_t status; + + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + start_handle = htobs(start_handle); + Osal_MemCpy(buffer + indx, &start_handle, 2); + indx += 2; + + end_handle = htobs(end_handle); + Osal_MemCpy(buffer + indx, &end_handle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == 0x01){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_descriptors_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.char_val_handle = htobs(char_val_handle); + cp.char_end_handle = htobs(char_end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_read_using_charac_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; + rq.cparam = &cp; + rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles) +{ + struct hci_request rq; + uint8_t status; + gatt_read_multiple_charac_val_cp cp; + + if(num_handles*2 > sizeof(cp.set_of_handles)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.num_handles = htobs(num_handles); + Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_long_charac_val_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; + rq.cparam = &cp; + rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_signed_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_confirm_indication_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_CONFIRM_INDICATION; + rq.cparam = &cp; + rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = write_status; + indx += 1; + + buffer[indx] = err_code; + indx += 1; + + buffer[indx] = att_val_len; + indx += 1; + + Osal_MemCpy(buffer + indx, att_val, att_val_len); + indx += att_val_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(uint16_t conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ALLOW_READ; + rq.cparam = &cp; + rq.clen = GATT_ALLOW_READ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission) +{ + struct hci_request rq; + gatt_set_security_permission_cp cp; + uint8_t status; + + cp.service_handle = htobs(service_handle); + cp.attr_handle = htobs(attr_handle); + cp.security_permission = security_permission; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; + rq.cparam = &cp; + rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + charDescHandle = htobs(charDescHandle); + Osal_MemCpy(buffer + indx, &charDescHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charDescValOffset, 2); + indx += 2; + + buffer[indx] = charDescValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); + indx += charDescValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_DESC_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_cp cp; + gatt_read_handle_val_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = btohs(rp.value_len); + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_offset_cp cp; + gatt_read_handle_val_offset_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rp.value_len; + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value) +{ + struct hci_request rq; + uint8_t status; + gatt_upd_char_val_ext_cp cp; + + if(value_length > sizeof(cp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.service_handle = htobs(service_handle); + cp.char_handle = htobs(char_handle); + cp.update_type = update_type; + cp.char_length = htobs(char_length); + cp.value_offset = htobs(value_offset); + cp.value_length = value_length; + Osal_MemCpy(cp.value, value, value_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL_EXT; + rq.cparam = &cp; + rq.clen = GATT_UPD_CHAR_VAL_EXT_CP_SIZE + value_length; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,266 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number) +{ + struct hci_request rq; + hal_get_fw_build_number_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_FW_BUILD_NUMBER; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *build_number = rp.build_number; + + return 0; +} + +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((len+2) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = offset; + indx++; + + buffer[indx] = len; + indx++; + + Osal_MemCpy(buffer + indx, val, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + hal_read_config_data_cp cp; + hal_read_config_data_rp rp; + + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_READ_CONFIG_DATA; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rq.rlen-1; + + Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) +{ + struct hci_request rq; + hal_set_tx_power_level_cp cp; + uint8_t status; + + cp.en_high_power = en_high_power; + cp.pa_level = pa_level; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets) +{ + struct hci_request rq; + hal_le_tx_test_packet_number_rp resp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_LE_TX_TEST_PACKET_NUMBER; + rq.rparam = &resp; + rq.rlen = sizeof(resp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *number_of_packets = btohl(resp.number_of_packets); + + return 0; +} + +tBleStatus aci_hal_device_standby(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_DEVICE_STANDBY; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_start(uint8_t rf_channel) +{ + struct hci_request rq; + hal_tone_start_cp cp; + uint8_t status; + + cp.rf_channel = rf_channel; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_START; + rq.cparam = &cp; + rq.clen = HAL_TONE_START_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_stop(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_STOP; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]) +{ + struct hci_request rq; + hal_get_link_status_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_LINK_STATUS; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(link_status,rp.link_status,sizeof(link_status)); + for(int i = 0; i < 8; i++) + conn_handle[i] = btohs(rp.conn_handle[i]); + + return 0; +} + +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot) +{ + struct hci_request rq; + hal_get_anchor_period_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_ANCHOR_PERIOD; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *anchor_period = btohl(rp.anchor_period); + *max_free_slot = btohl(rp.max_free_slot); + + return 0; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,117 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB05A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.min_ce_length = htobs(min_ce_length); + cp.max_ce_length = htobs(max_ce_length); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB04A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,269 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_updater_aci.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_updater_reboot(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_get_updater_version(uint8_t *version) +{ + struct hci_request rq; + get_updater_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_VERSION; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) +{ + struct hci_request rq; + get_updater_bufsize_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_BUFSIZE; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_reset_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = htobl(address); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_SECTOR; + rq.cparam = &cp; + rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_program_data_block(uint32_t address, + uint16_t len, + const uint8_t *data) +{ + struct hci_request rq; + uint8_t status; + updater_prog_data_block_cp cp; + + if( len > sizeof(cp.data)) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(len); + Osal_MemCpy(cp.data, data, len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_read_data_block(uint32_t address, + uint16_t data_len, + uint8_t *data) +{ + struct hci_request rq; + updater_read_data_block_cp cp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + + if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(data_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; + rq.rparam = buffer; + rq.rlen = data_len + 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + // First byte is status + Osal_MemCpy(data, buffer+1, data_len); + + return buffer[0]; +} + +tBleStatus aci_updater_calc_crc(uint32_t address, + uint8_t num_sectors, + uint32_t *crc) +{ + struct hci_request rq; + updater_calc_crc_cp cp; + updater_calc_crc_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + cp.address = htobl(address); + cp.num_sectors = num_sectors; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_CALC_CRC; + rq.cparam = &cp; + rq.clen = UPDATER_CALC_CRC_CP_SIZE; + rq.rparam = &resp; + rq.rlen = UPDATER_CALC_CRC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *crc = btohl(resp.crc); + + return resp.status; +} + +tBleStatus aci_updater_hw_version(uint8_t *version) +{ + struct hci_request rq; + updater_hw_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_HW_VERSION; + rq.rparam = &resp; + rq.rlen = UPDATER_HW_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,423 @@ + +#include "ble_hal.h" +#include "ble_hal_types.h" +#include "ble_status.h" +#include "bluenrg_aci.h" +#include "bluenrg_utils.h" +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "ble_osal.h" +#include "string.h" +#include "stm32_bluenrg_ble.h" + +#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 +#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 + +#define BASE_ADDRESS 0x10010000 + +#define FW_OFFSET (2*1024) // 2 KB +#define FW_OFFSET_MS 0 +#define FULL_STACK_SIZE (66*1024) // 66 KB +#define BOOTLOADER_SIZE (2*1024) // 2 kB +#define SECTOR_SIZE (2*1024) // 2 KB + +// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + +// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 +#define CRC_POLY 0x04C11DB7 // the poly without the x**32 + +#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC + +#define IFR_SIZE 192 +#define IFR_BASE_ADDRESS 0x10020000 +#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data + +#if BLUENRG_MS +#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET +#else +#define IFR_WRITE_OFFSET_BEGIN 0 +#endif + + +#define BLUE_FLAG_OFFSET 0x8C0 +#define MAX_ERASE_RETRIES 2 +#define MAX_WRITE_RETRIES 2 +#define MIN_WRITE_BLOCK_SIZE 4 +#define MAX_WRITE_BLOCK_SIZE 64 // 64 bytes +#define READ_BLOCK_SIZE 64 // 64 bytes + +#define RETRY_COMMAND(func, num_ret, error) \ +{ \ + uint8_t num_retries; \ + num_retries = 0; \ + error = 0; \ + while (num_retries++ < num_ret) { \ + if (func == BLE_STATUS_SUCCESS) \ + break; \ + if (num_retries == num_ret) \ + error = BLE_UTIL_ACI_ERROR; \ + } \ +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, + they are extended with 0xFF until sector size is reached +*/ +static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) +{ + uint32_t i, j, a1; + uint32_t crc, value; + + crc = 0; + for (i = 0; i < SECTOR_SIZE; i += 4) { + uint8_t *dataw = (uint8_t *) &value; + + dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; + dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; + dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; + dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; + + crc = crc ^ value; + for (j = 0; j < 32; j ++) { + a1 = (crc >> 31) & 0x1; + crc = (crc << 1) ^ (a1 * CRC_POLY); + } + } + + return crc; +} + +int program_device(const uint8_t *fw_image, uint32_t fw_size) +{ + uint8_t version, num_erase_retries, status, write_block_size; + uint32_t address; + uint32_t crc, crc2, crc_size; + uint32_t fw_offset = FW_OFFSET; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + if(aci_updater_hw_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version==0x31){ + // It does not contain bootloader inside first sector. It may contain code. + fw_offset = FW_OFFSET_MS; + } + + if (fw_size != FULL_STACK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + if (fw_size % MIN_WRITE_BLOCK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + + /*********************************************************************** + * Erase BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + /*********************************************************************** + * Erase and Program sectors + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE) { + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(BASE_ADDRESS + i); + for (int j=i; ((j<i+SECTOR_SIZE)&&(j<fw_size)); j += write_block_size) { + + write_block_size = MIN(fw_size-j, MAX_WRITE_BLOCK_SIZE); + + RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, write_block_size, fw_image+j), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + break; + } + if (status == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + } + + /*********************************************************************** + * Verify firmware + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE){ + address = BASE_ADDRESS + i; + if(aci_updater_calc_crc(address, 1, &crc)) + return BLE_UTIL_ACI_ERROR; + + crc_size = MIN(fw_size-i,SECTOR_SIZE); + + crc2 = updater_calc_crc(fw_image+i,crc_size); + if(crc!=crc2) + return BLE_UTIL_CRC_ERROR; + } + + /*********************************************************************** + * Write BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +int read_IFR(uint8_t *data) +{ + uint8_t version, offset; + tBleStatus ret; + + offset = 0; + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + /*********************************************************************** + * Reading last 3 IFR 64-byte blocks + ************************************************************************/ + for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(BASE_ADDRESS+i, READ_BLOCK_SIZE, (data+offset)); + offset += READ_BLOCK_SIZE; + if(ret) return BLE_UTIL_ACI_ERROR; + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; + +} + +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) +{ + IFR_config->stack_mode = data[0]; + IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); + IFR_config->master_sca = data[30]; + IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); + IFR_config->year = BCD_TO_INT(data[41]); + IFR_config->month = BCD_TO_INT(data[42]); + IFR_config->day = BCD_TO_INT(data[43]); +} + +int IFR_validate(IFR_config2_TypeDef *IFR_config) +{ +#if BLUENRG_MS + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) +#else + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) +#endif + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode + if(IFR_config->master_sca > 7) + return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->day > 31 || IFR_config->day < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + + return BLE_STATUS_SUCCESS; +} + +/* TODO: Function to generate data from given options. */ + +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) +{ + data[0] = IFR_config->stack_mode; + HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); + data[30] = IFR_config->master_sca; + HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); + data[41] = INT_TO_BCD(IFR_config->year); + data[42] = INT_TO_BCD(IFR_config->month); + data[43] = INT_TO_BCD(IFR_config->day); +} + + +int program_IFR(const IFR_config_TypeDef *ifr_image) +{ + uint8_t version, num_erase_retries; + tBleStatus ret; +#if BLUENRG_MS + const uint8_t *ifr_data = (uint8_t *)ifr_image; +#else + uint8_t ifr_data[SECTOR_SIZE]; +#endif + uint8_t hwVersion; + uint16_t fwVersion; + + if(getBlueNRGVersion(&hwVersion, &fwVersion)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + +#ifndef BLUENRG_MS + /*********************************************************************** + * READ IFR data + ************************************************************************/ + for(int i = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_data+i); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + } +#endif + + /*********************************************************************** + * Erase & Flashing IFR sectors + ************************************************************************/ +#ifndef BLUENRG_MS + Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); +#endif + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(IFR_BASE_ADDRESS); + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += MAX_WRITE_BLOCK_SIZE, j += MAX_WRITE_BLOCK_SIZE) { + RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, MAX_WRITE_BLOCK_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); + if (ret != BLE_STATUS_SUCCESS) + break; + } + if (ret == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + + /*********************************************************************** + * Verify IFR + ************************************************************************/ + { + uint8_t ifr_updated[READ_BLOCK_SIZE]; + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE, j += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ifr_data+j, READ_BLOCK_SIZE) != 0) + return BLE_UTIL_WRONG_VERIFY; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) +{ + uint8_t ifr_updated[READ_BLOCK_SIZE]; + uint8_t version, ret = BLE_STATUS_SUCCESS; + + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + for(int i = 0; i < IFR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, READ_BLOCK_SIZE) != 0) + { + ret = BLE_UTIL_WRONG_VERIFY; + break; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return ret; +} + +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) +{ + uint8_t status; + uint8_t hci_version, lmp_pal_version; + uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; + + status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, + &manufacturer_name, &lmp_pal_subversion); + + if (status == BLE_STATUS_SUCCESS) { + *hwVersion = hci_revision >> 8; + *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number + *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number + *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number + } + + return status; +} + +uint8_t getBlueNRGUpdaterVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(version)) + return BLE_UTIL_ACI_ERROR; + + if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_updater_hw_version(version)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t isHWBootloader_Patched(void) +{ + uint8_t status, version; + uint32_t crc, address = 0x10010000; + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); + if (status != BLE_STATUS_SUCCESS) + return 0; + + if (crc == BOOTLOADER_CRC_NOT_PATCHED) + return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +#include "ble_gp_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function sets a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * @param[in] t A pointer to the timer + * @param[in] interval The interval before the timer expires. + * + */ +void +Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +Timer_Expired(struct timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + tClockTime diff = (Clock_Time() - t->start) + 1; + return t->interval < diff; + +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +tClockTime +Timer_Remaining(struct timer *t) +{ + return t->start + t->interval - Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +#ifdef __DMA_LP__ + +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID) +{ + TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, + (pf_TIMER_TimerCallBack_t) timercb); + TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); + + return (BLE_STATUS_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) +{ + TIMER_Delete(timerID); + + return (BLE_STATUS_SUCCESS); +} + +#endif /* __DMA_LP__ */ +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,119 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Circular Linked List Implementation. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/****************************************************************************** + * Include Files +******************************************************************************/ +#include <ble_hal_types.h> +#include "ble_list.h" + +/****************************************************************************** + * Function Definitions +******************************************************************************/ +void list_init_head (tListNode * listHead) +{ + listHead->next = listHead; + listHead->prev = listHead; +} + +uint8_t list_is_empty (tListNode * listHead) +{ + return ((listHead->next == listHead)? TRUE:FALSE); +} + +void list_insert_head (tListNode * listHead, tListNode * node) +{ + node->next = listHead->next; + node->prev = listHead; + listHead->next = node; + (node->next)->prev = node; +} + + +void list_insert_tail (tListNode * listHead, tListNode * node) +{ + node->next = listHead; + node->prev = listHead->prev; + listHead->prev = node; + (node->prev)->next = node; +} + + +void list_remove_node (tListNode * node) +{ + (node->prev)->next = node->next; + (node->next)->prev = node->prev; +} + + +void list_remove_head (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->next; + list_remove_node (listHead->next); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_remove_tail (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->prev; + list_remove_node (listHead->prev); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_insert_node_after (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node->next; + node->prev = ref_node; + ref_node->next = node; + (node->next)->prev = node; +} + + +void list_insert_node_before (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node; + node->prev = ref_node->prev; + ref_node->prev = node; + (node->prev)->next = node; +} + + +int list_get_size (tListNode * listHead) +{ + int size = 0; + tListNode * temp = listHead->next; + while (temp != listHead) + { + size++; + temp = temp->next; + } + return (size); +} + +void list_get_next_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->next; +} + + +void list_get_prev_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->prev; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,72 @@ +/** +****************************************************************************** +* @file ble_osal.c +* @author AMS - HEA&RF BU / CL +* @version V1.0.0 +* @date 04-July-2014 +* @brief Implementation of OS abstraction layer functions used by the +* library. +****************************************************************************** +* @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> +#include <ble_osal.h> + + /** + * @brief Osal_MemCpy + * @param dest: Pointer to the destination buffer + * @param src : Pointer to the source buffer + * @param size: Number of bytes to copy from the source to the destination + * buffer + * @retval Pointer to the destination buffer + */ +void* Osal_MemCpy(void *dest, const void *src, unsigned int size) +{ + return(memcpy(dest,src,size)); +} + +/** + * @brief Osal_MemSet + * @param ptr : Pointer to block of memory to fill + * @param value: Value to assign to each byte of the memory block + * @param size : Number of bytes to be set to "value" + * @retval Pointer to the filled block of memory + */ +void* Osal_MemSet(void *ptr, int value, unsigned int size) +{ + return(memset(ptr,value,size)); +} + +/****************************************************************************** + * local Functions + *****************************************************************************/ + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ + +#include "ble_clock.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/wait_api.h" + #include "mbed-drivers/rtc_time.h" +#else + #include "wait_api.h" + #include "rtc_time.h" +#endif + +const uint32_t CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + //Not Used +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return clock(); +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,715 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file btle.cpp + * @author STMicroelectronics + * @brief Implementation BlueNRG Init and helper functions. + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + + +#include "btle.h" +#include "ble/Gap.h" +#include "ble/GapEvents.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" + +#include "bluenrg_targets.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* C File Includes ------------------------------------------------------------------*/ +#include <stdio.h> +#include <string.h> +#include "ble_hci.h" +#include "ble_hci_const.h" +#include "bluenrg_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" +#include "bluenrg_utils.h" + +#include "ble_hal_types.h" +#include "ble_hal.h" +#include "ble_gp_timer.h" +#include "ble_osal.h" +#include "ble_sm.h" +#include "ble_debug.h" + +#ifdef __cplusplus +} +#endif + +#define IDB04A1 0 +#define IDB05A1 1 + +/* See file 'bluenrg_targets.h' for details regarding the BLUENRG_STACK_MODE */ +#define STACK_MODE BLUENRG_STACK_MODE + +void HCI_Input(tHciDataPacket * hciReadPacket); + +uint16_t g_gap_service_handle = 0; +uint16_t g_appearance_char_handle = 0; +uint16_t g_device_name_char_handle = 0; +uint16_t g_preferred_connection_parameters_char_handle = 0; + +/* Private variables ---------------------------------------------------------*/ +volatile uint8_t set_connectable = 1; + +static char versionString[32]; +uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ + +/**************************************************************************/ +/*! + @brief Init the BTLE stack with the specified role + @returns void +*/ +/**************************************************************************/ +void btleInit(void) +{ + PRINTF("btleInit>>\n\r"); + + int ret; + uint8_t hwVersion; + uint16_t fwVersion; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* get the BlueNRG HW and FW versions */ + getBlueNRGVersion(&hwVersion, &fwVersion); + + /* + * Reset BlueNRG again otherwise we won't + * be able to change its MAC address. + * aci_hal_write_config_data() must be the first + * command after reset otherwise it will fail. + */ + BlueNRG_RST(); + + if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ + bnrg_expansion_board = IDB05A1; + } + + /* set BLE version string */ + setVersionString(hwVersion, fwVersion); + + if (bnrg_expansion_board == IDB05A1) { + uint8_t stackMode = STACK_MODE; + ret = aci_hal_write_config_data(CONFIG_DATA_MODE_OFFSET, + CONFIG_DATA_MODE_LEN, + &stackMode); + } + + ret = aci_gatt_init(); + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GATT_Init failed.\n"); + } + if (bnrg_expansion_board == IDB05A1) { + ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1, + 0, + 0x18, + &service_handle, + &dev_name_char_handle, + &appearance_char_handle); + } else { + // IDB04A1 is configured as peripheral by default + ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + } + + // read the default static address and inject it into the GAP object + { + Gap::Address_t BLE_address_BE = { 0 }; + uint8_t data_len_out; + aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS, BDADDR_SIZE, &data_len_out, BLE_address_BE); + // FIXME error handling of this function + BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE); + } + + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GAP_Init failed.\n"); + } + + //FIXME: Security and passkey set by default + ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, + OOB_AUTH_DATA_ABSENT, + NULL, + 7, + 16, + USE_FIXED_PIN_FOR_PAIRING, + 123456, + BONDING); + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Auth Req set failed.\n"); + } + + aci_hal_set_tx_power_level(1,4); + + g_gap_service_handle = service_handle; + g_appearance_char_handle = appearance_char_handle; + g_device_name_char_handle = dev_name_char_handle; + //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API + /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, + strlen(name), (tHalUint8 *)name);*/ + + signalEventsToProcess(); + // update the peripheral preferred conenction parameters handle + // This value is hardcoded at the moment. + g_preferred_connection_parameters_char_handle = 10; + + return; +} + +/**************************************************************************/ +/*! + @brief mbedOS + + @param[in] void + + @returns +*/ +/**************************************************************************/ +int btle_handler_pending = 0; + +void btle_handler(void) +{ + btle_handler_pending = 0; + BlueNRGGap::getInstance().Process(); + HCI_HandleSPI(); + HCI_Process(); +} + +/* set BLE Version string */ +void setVersionString(uint8_t hwVersion, uint16_t fwVersion) +{ + if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) { + snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u", + hwVersion>>4, (hwVersion&0x0F), + fwVersion>>8, (fwVersion&0x00F0)>>4); + } else { + snprintf(versionString, sizeof(versionString), "ST (unknown spec)"); + } +} + +/* get BLE Version string */ +const char* getVersionString(void) +{ + return versionString; +} + +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type) +{ + tBleStatus ret; + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + if(bnrg_expansion_board == IDB05A1) { + PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window); + PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type); + ret = aci_gap_start_observation_procedure(scan_interval, + scan_window, + scan_type, + own_address_type, + 0); // 1 to filter duplicates + } else { + ret = BLE_STATUS_INVALID_CID; + } + + return ret; + +} + +/*! + @brief Not Used + + @param[in] void + + @returns +*/ +void SPI_Poll(void) +{ + //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); + return; +} + +void Attribute_Modified_CB(evt_blue_aci *blue_evt) +{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t *att_data; + uint8_t offset; + + if (bnrg_expansion_board == IDB05A1) { + evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = evt->offset; + } else { + evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = 0; + } + + //Extract the GattCharacteristic from p_characteristics[] and find the properties mask + GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle); + if(p_char!=NULL) { + GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE; + PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]); + PRINTF("getProperties 0x%x\n\r",p_char->getProperties()); + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; + } + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; + } + PRINTF("currentHandle %d\n\r", currentHandle); + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && + currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { + + GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1; + + PRINTF("*****NOTIFICATION CASE\n\r"); + //Now Check if data written in Enable or Disable + if((uint16_t)att_data[0]==1) { + //PRINTF("Notify ENABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle); + } else { + //PRINTF("Notify DISABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle); + } + return; + } + + //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) && + currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) { + + PRINTF("*****WRITE CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = p_char->getValueAttribute().getHandle(); + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle); + //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + BlueNRGGattServer::getInstance().write( + p_char->getValueAttribute().getHandle(), + (uint8_t*)att_data, + data_length, + false + ); + } + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } else { + PRINTF("*****WRITE DESCRIPTOR CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = attr_handle; + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } + } + +} + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************************/ + /*! + @brief Handle HCI Stack Event + + @param[in] pckt + Event Packet sent by the stack to be decoded + + @returns + */ + /**************************************************************************/ + extern void HCI_Event_CB(void *pckt) { + hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; + hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; + + if(hci_pckt->type != HCI_EVENT_PKT) + return; + + switch(event_pckt->evt){ + + case EVT_DISCONN_COMPLETE: + { + PRINTF("EVT_DISCONN_COMPLETE\n"); + + evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data; + + if(BlueNRGGap::getInstance().getGapRole() == Gap::CENTRAL) { + BlueNRGGattClient::getInstance().removeGattConnectionClient(evt->handle, evt->reason); + } + + BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason); + } + break; + + case EVT_LE_META_EVENT: + { + PRINTF("EVT_LE_META_EVENT\n"); + + evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; + + switch(evt->subevent){ + + case EVT_LE_CONN_COMPLETE: + { + PRINTF("EVT_LE_CONN_COMPLETE\n"); + Gap::Address_t ownAddr; + Gap::AddressType_t ownAddrType; + BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr); + + Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + Gap::Role_t role; + + evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; + + BlueNRGGap::getInstance().setConnectionHandle(cc->handle); + BlueNRGGap::ConnectionParams_t connectionParams = { + /* minConnectionInterval = */ cc->interval, + /* maxConnectionInterval = */ cc->interval, + /* slaveLatency = */ cc->latency, + /* connectionSupervisionTimeout = */ cc->supervision_timeout + }; + + BlueNRGGap::getInstance().setConnectionInterval(cc->interval); + + switch (cc->peer_bdaddr_type) { + case PUBLIC_ADDR: + peerAddrType = BLEProtocol::AddressType::PUBLIC; + break; + case STATIC_RANDOM_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + break; + case RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE; + break; + case NON_RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE; + break; + } + //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role); + switch (cc->role) { + case 0: //master + role = Gap::CENTRAL; + BlueNRGGattClient::getInstance().createGattConnectionClient(cc->handle); + break; + case 1: + role = Gap::PERIPHERAL; + break; + default: + role = Gap::PERIPHERAL; + break; + } + + BlueNRGGap::getInstance().setGapRole(role); + + BlueNRGGap::getInstance().processConnectionEvent(cc->handle, + role, + peerAddrType, + cc->peer_bdaddr, + ownAddrType, + ownAddr, + &connectionParams); + } + break; + + case EVT_LE_ADVERTISING_REPORT: + PRINTF("EVT_LE_ADVERTISING_REPORT\n\r"); + /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */ + // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT) + // Formally the structure related to both events are identical except that for the ADV REPORT + // there is one more field (number of reports) which is not forwarded to upper layer. + // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT. + le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1); + PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + break; + } + } + break; + + case EVT_VENDOR: + { + evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; + //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode); + + switch(blue_evt->ecode){ + + case EVT_BLUE_GATT_WRITE_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_WRITE_PERMIT_REQ\r\n"); + evt_gatt_write_permit_req* write_req = (evt_gatt_write_permit_req*)blue_evt->data; + + // ask the local server if the write operation is authorized + uint8_t err_code = BlueNRGGattServer::getInstance().Write_Request_CB( + write_req->conn_handle, + write_req->attr_handle, + write_req->data_length, + write_req->data + ); + uint8_t write_status = err_code == 0 ? 0 : 1; + + // reply to the shield + aci_gatt_write_response( + write_req->conn_handle, + write_req->attr_handle, + write_status, + err_code, + write_req->data_length, + write_req->data + ); + } + break; + + case EVT_BLUE_GATT_READ_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r"); + evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle); + BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle); + } + break; + + case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: + { + PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r"); + /* this callback is invoked when a GATT attribute is modified + extract callback data and pass to suitable handler function */ + Attribute_Modified_CB(blue_evt); + } + break; + + //Any cases for Data Sent Notifications? + case EVT_BLUE_GATT_NOTIFICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_NOTIFICATION"); + break; + case EVT_BLUE_GATT_INDICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_INDICATION"); + break; + + case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r"); + evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_data_length, + pr->attribute_data_list); + } + break; + case EVT_BLUE_ATT_READ_BY_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r"); + evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle, + pr->event_data_length, + pr->handle_value_pair_length, + pr->handle_value_pair); + } + break; + case EVT_BLUE_ATT_READ_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_RESP\n\r"); + evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_value); + } + break; + case EVT_BLUE_ATT_EXEC_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle, + pr->event_data_length); + } + break; + case EVT_BLUE_ATT_PREPARE_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_handle, + pr->offset, + pr->part_attr_value); + } + break; + case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP: + { + PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r"); + evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle, + pr->event_data_length, + pr->attr_handle, + pr->attr_value); + } + break; + case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r"); + evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle, + pr->event_data_length, + pr->handles_info_list); + } + break; + case EVT_BLUE_ATT_FIND_INFORMATION_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r"); + evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle, + pr->event_data_length, + pr->format, + pr->handle_uuid_pair); + } + break; + case EVT_BLUE_GATT_PROCEDURE_COMPLETE: + { + evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code); + BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code); + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_REQ: + { + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_REQ\r\n"); + evt_l2cap_conn_upd_req *evt = (evt_l2cap_conn_upd_req*)blue_evt->data; + if(bnrg_expansion_board == IDB05A1) { + // we assume the application accepts the request from the slave + aci_l2cap_connection_parameter_update_response_IDB05A1(evt->conn_handle, + evt->interval_min, + evt->interval_max, + evt->slave_latency, + evt->timeout_mult, + CONN_L1, CONN_L2, + evt->identifier, + 0x0000); + } + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_RESP: + { + evt_l2cap_conn_upd_resp *evt = (evt_l2cap_conn_upd_resp*)blue_evt->data; + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_RESP code=0x%x, result=0x%x\r\n", evt->code, evt->result); + } + break; + + case EVT_LE_CONN_UPDATE_COMPLETE: + { + evt_le_connection_update_complete *evt = (evt_le_connection_update_complete*)blue_evt->data; + PRINTF("EVT_LE_CONN_UPDATE_COMPLETE status=0x%x\r\n", evt->status); + } + break; + + case EVT_BLUE_GAP_DEVICE_FOUND: + { + evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data; + PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + } + break; + + case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + { + evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data; + //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code); + + switch(pr->procedure_code) { + case GAP_OBSERVATION_PROC_IDB05A1: + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL); + break; + } + } + break; + } + } + break; + } + return ; + } + + +#ifdef __cplusplus +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,217 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.cpp + * @author CL + * @version V1.0.0 + * @date 15-June-2015 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRGGap.h" +#include "BlueNRGDevice.h" +#include "btle.h" + +// FIXME: find a better way to get the instance of the BlueNRG device +extern BlueNRGDevice bluenrgDeviceInstance; + + +//////////////////////////////////////// +// Start of C function wrappers +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32_bluenrg_ble.h" +#include "ble_debug.h" + + +void BlueNRG_RST(void) +{ + bluenrgDeviceInstance.reset(); +} + +uint8_t BlueNRG_DataPresent(void) +{ + return (bluenrgDeviceInstance.dataPresent()); +} + + +/** + * @brief This function is a utility to print the log time +* in the format HH:MM:SS:MSS (DK GUI time format) + * @param None + * @retval None + */ +void print_csv_time(void){ +#ifdef PRINT_CSV_FORMAT + uint32_t ms = 0;//ms_counter; + PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000); +#endif +} + +/** + * @brief Writes data to a serial interface. + * @param data1 : 1st buffer + * @param data2 : 2nd buffer + * @param n_bytes1: number of bytes in 1st buffer + * @param n_bytes2: number of bytes in 2nd buffer + * @retval None + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, + int32_t n_bytes2) +{ + struct timer t; + + Timer_Set(&t, CLOCK_SECOND/10); + +#ifdef PRINT_CSV_FORMAT + print_csv_time(); + for (int i=0; i<n_bytes1; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data1)[i]); + } + for (int i=0; i<n_bytes2; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data2)[i]); + } + PRINT_CSV("\n"); +#endif + + while(1){ + if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; + if(Timer_Expired(&t)){ + break; + } + } +} + + +/** + * @brief Activate internal bootloader using pin. + * @param None + * @retval None + */ +void BlueNRG_HW_Bootloader(void) +{ + // Reset BlueNRG SPI interface + BlueNRG_RST(); + + // Send an ACI command to reboot BlueNRG in bootloader mode + // The safest way to get in bootloader mode is keeping high + // the interrupt pin during reset, but this would require many + // changes to the current mbed driver + aci_updater_start(); +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size) +{ + int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size); + + return ret; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2); + + return ret; +} + +/** + * @brief Enable SPI IRQ. + * @param None + * @retval None + */ +void Enable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.enable_irq(); +} + +void signalEventsToProcess(void) { + if(btle_handler_pending == 0) { + btle_handler_pending = 1; + bluenrgDeviceInstance.signalEventsToProcess(BLE::DEFAULT_INSTANCE); + } +} + +/** + * @brief Disable SPI IRQ. + * @param None + * @retval None + */ +void Disable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.disable_irq(); +} + +/** + * @brief Clear Pending SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_IRQ(void) +{ +} + +/** + * @brief Clear EXTI (External Interrupt) line for SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_EXTI_Flag(void) +{ +} + + + + +#ifdef __cplusplus +} +#endif +// End of C function wrappers +//////////////////////////////////////// + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <ble_payload.h> + +Payload::Payload() { + stringLength = 0; + payloadUnitCount = 0; + payload = NULL; +} + +Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + stringLength = string_ength; + payloadUnitCount = 0; + payload = NULL; + + int index = 0; + while( index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + UnitPayload *obj = new UnitPayload[payloadUnitCount]; + int i=0; + int c=0; + int j,k; + + while(i<payloadUnitCount) + { + obj[i].length=tokenString[c]; + obj[i].id=tokenString[c+1]; + + obj[i].data = new uint8_t[obj[i].length]; + for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) + { + obj[i].data[k]=tokenString[j]; + + } + + c=c+obj[i].length+1; + i++; + + } + payload = obj; +} + +uint8_t Payload::getPayloadUnitCount() { + return payloadUnitCount; +} + +uint8_t Payload::getIDAtIndex(int index) { + return payload[index].get_id(); +} + +uint8_t Payload::getLengthAtIndex(int index) { + return payload[index].get_length(); +} + +uint8_t* Payload::getDataAtIndex(int index) { + return payload[index].get_data(); +} + +int8_t Payload::getInt8AtIndex(int index) { + uint8_t* str = payload[index].get_data(); + int8_t value = (int8_t)str[0]; + return value; +} + +uint16_t Payload::getUint16AtIndex(int index) { + uint16_t* str = (uint16_t*)payload[index].get_data(); + uint16_t value = str[0]; + return value; +} + +uint8_t* Payload::getSerializedAdDataAtIndex(int index) { + uint8_t length = payload[index].get_length(); + uint8_t* data = payload[index].get_data(); + uint8_t id = payload[index].get_id(); + uint8_t *serializedAdData = new uint8_t[length]; + + serializedAdData[0] = id; + for(int i=0; i<length-1; i++) { + serializedAdData[i+1] = data[i]; + } + return serializedAdData; +} + +Payload::~Payload() { + int i = 0; + + if(payload) { + while(i<payloadUnitCount) { + if(payload->data) { + delete[] payload->data; + payload->data = NULL; + } + } + delete[] payload; + payload = NULL; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,93 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ble_utils.h" + +/**************************************************************************/ +/*! + @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power + +*/ +/**************************************************************************/ +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(dBMLevel==-18) { + EN_HIGH_POWER = 0; + PA_LEVEL = 0; + } + else if(dBMLevel==-15) { + EN_HIGH_POWER = 0; + PA_LEVEL = 1; + } + else if(dBMLevel==-14) { + EN_HIGH_POWER = 1; + PA_LEVEL = 0; + } + else if(dBMLevel==-12) { + EN_HIGH_POWER = 0; + PA_LEVEL = 2; + } + else if(dBMLevel==-11) { + EN_HIGH_POWER = 1; + PA_LEVEL = 1; + } + else if(dBMLevel==-9) { + EN_HIGH_POWER = 0; + PA_LEVEL = 3; + } + else if(dBMLevel==-8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 2; + } + else if(dBMLevel==-6) { + EN_HIGH_POWER = 0; + PA_LEVEL = 4; + } + else if(dBMLevel==-5) { + EN_HIGH_POWER = 1; + PA_LEVEL = 3; + } + else if(dBMLevel==-2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 4; + } + else if(dBMLevel==0) { + EN_HIGH_POWER = 0; + PA_LEVEL = 6; + } + else if(dBMLevel==2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 5; + } + else if(dBMLevel==4) { + EN_HIGH_POWER = 1; + PA_LEVEL = 6; + } + else if(dBMLevel==5) { + EN_HIGH_POWER = 0; + PA_LEVEL = 7; + } + else if(dBMLevel==8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + else { + ret = ERR_INVALID_HCI_CMD_PARAMS; + } + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Beacon/source/main.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,101 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <events/mbed_events.h> +#include <mbed.h> +#include "ble/BLE.h" +#include "ble/services/iBeacon.h" + +static iBeacon* ibeaconPtr; + +static EventQueue eventQueue(/* event count */ 4 * EVENTS_EVENT_SIZE); + +/** + * This function is called when the ble initialization process has failled + */ +void onBleInitError(BLE &ble, ble_error_t error) +{ + /* Initialization error handling should go here */ +} + +void printMacAddress() +{ + /* Print out device MAC address to the console*/ + Gap::AddressType_t addr_type; + Gap::Address_t address; + BLE::Instance().gap().getAddress(&addr_type, address); + printf("DEVICE MAC ADDRESS: "); + for (int i = 5; i >= 1; i--){ + printf("%02x:", address[i]); + } + printf("%02x\r\n", address[0]); +} + +/** + * Callback triggered when the ble initialization process has finished + */ +void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) +{ + BLE& ble = params->ble; + ble_error_t error = params->error; + + if (error != BLE_ERROR_NONE) { + /* In case of error, forward the error handling to onBleInitError */ + onBleInitError(ble, error); + return; + } + + /* Ensure that it is the default instance of BLE */ + if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { + return; + } + + /** + * The Beacon payload has the following composition: + * 128-Bit / 16byte UUID = E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61 + * Major/Minor = 0x1122 / 0x3344 + * Tx Power = 0xC8 = 200, 2's compliment is 256-200 = (-56dB) + * + * Note: please remember to calibrate your beacons TX Power for more accurate results. + */ + static const uint8_t uuid[] = {0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4, + 0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61}; + uint16_t majorNumber = 1122; + uint16_t minorNumber = 3344; + uint16_t txPower = 0xC8; + ibeaconPtr = new iBeacon(ble, uuid, majorNumber, minorNumber, txPower); + + ble.gap().setAdvertisingInterval(1000); /* 1000ms. */ + ble.gap().startAdvertising(); + + printMacAddress(); +} + +void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { + BLE &ble = BLE::Instance(); + eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); +} + +int main() +{ + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(scheduleBleEventsProcessing); + ble.init(bleInitComplete); + + eventQueue.dispatch_forever(); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/.mbed Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +ROOT=.
Binary file mbed-os-example-ble-master/BLE_Button/img/button_depressed.png has changed
Binary file mbed-os-example-ble-master/BLE_Button/img/button_pressed.png has changed
Binary file mbed-os-example-ble-master/BLE_Button/img/connection.png has changed
Binary file mbed-os-example-ble-master/BLE_Button/img/discovery.png has changed
Binary file mbed-os-example-ble-master/BLE_Button/img/register_to_notifications.png has changed
Binary file mbed-os-example-ble-master/BLE_Button/img/scan_results.png has changed
Binary file mbed-os-example-ble-master/BLE_Button/img/start_scan.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/mbed-os.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/mbed_app.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,35 @@ +{ + "config": { + "ble_button_pin_name": { + "help": "The pin name used as button in this application", + "macro_name": "BLE_BUTTON_PIN_NAME", + "required": true + } + }, + "target_overrides": { + "NRF51_DK": { + "ble_button_pin_name": "BUTTON1" + }, + "NRF52_DK": { + "ble_button_pin_name": "BUTTON1" + }, + "MTB_UBLOX_NINA_B1": { + "ble_button_pin_name": "BUTTON1" + }, + "K64F": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"], + "ble_button_pin_name": "SW2" + }, + "NUCLEO_F401RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"], + "ble_button_pin_name": "USER_BUTTON" + }, + "DISCO_L475VG_IOT01A": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"], + "ble_button_pin_name": "USER_BUTTON" + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,15 @@ +{ + "name": "ble-button", + "version": "0.0.1", + "description": "The *input service template* demonstrates the use of a simple input (boolean values) from a read-only characteristic.", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "bin": "./source", + "dependencies": { + "ble": "^2.0.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/readme.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,99 @@ +BLE_Button is a BLE service template. It handles a read-only characteristic with a simple input (boolean values). The input's source is the button on the board itself - the characteristic's value changes when the button is pressed or released. + +The template covers: + +1. Setting up advertising and connection modes. + +1. Creating an input characteristic: read-only, boolean, with notifications. + +1. Constructing a service class and adding it to the BLE stack. + +1. Assigning UUIDs to the service and its characteristic. + +1. Pushing notifications when the characteristic's value changes. + +# Running the application + +## Requirements + +The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : + +- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. + +- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +### Porting this example on new boards + +This example requires a board with at least a button to work. While the pin name of the button is defined for the `NRF51_DK`, `NRF52_DK`, `K64F` and `NUCLEO_F401RE`, it is not specified for other boards. + +It is easy to add the button configuration for your board: +* Open the file named `mbed_app.json` at the root of this example. +* In the section `target_overides` add a new object named after your target if it doesn't exist. This object contain overridden parameters for your target. +* Override the property `ble_button_pin_name` in your target object. The value of the property should be equal to the pin name to use as a button. + +As an example, this is the JSON bit which has to be added in the `target_overrides` section of `mbed_app.json` for a `NUCLEO_F411RE` board. + +```json + "NUCLEO_F411RE": { + "ble_button_pin_name": "USER_BUTTON" + } +``` + +<span> **Note:** You can get more informations about the configuration system in the [documentation](https://github.com/ARMmbed/mbed-os/blob/master/docs/config_system.md)</span> + +<span> **Important:** If your target use an ST BLE shield, other parameters have to be overridden for your target. More information are available in the global [README](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md#targets-for-ble)</span> + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Checking for success + +**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. + +1. Build the application and install it on your board as explained in the building instructions. +1. Open the BLE scanner on your phone. +1. Start a scan. + +  + + **figure 1** How to start scan using nRF Master Control Panel 4.0.5 + +1. Find your device; it should appear with the name `Button` in the scanner. + +  + + **figure 2** Scan results using nRF Master Control Panel 4.0.5 + +1. Establish a connection with the device. + +  + + **figure 3** How to establish a connection using Master Control Panel 4.0.5 + +1. Discover the services and the characteristics on the device. The *Button service* has the UUID `0xA000` and includes the *Button state characteristic* which has the UUID `0xA001`. Depending on your scanner, non standard 16-bit UUID's can be displayed as 128-bit UUID's. If it is the case the following format will be used: `0000XXXX-0000-1000-8000-00805F9B34FB` where `XXXX` is the hexadecimal representation of the 16-bit UUID value. + +  + + **figure 4** Representation of the Button service using Master Control Panel 4.0.5 + +1. Register for the notifications sent by the button state characteristic then the scanner will automatically receive a notification containing the new state of the button every time the state of the button changes. + +  + + **figure 5** How to register to notifications using Master Control Panel 4.0.5 + + +1. Pressing Button 1 on your board updates the state of the button and sends a notification to the scanner. The new state of the button characteristic value should be equal to 0x01. + +  + + **figure 6** Notification of button pressed using Master Control Panel 4.0.5 + +1. Releasing Button 1 on your board updates the state of the button and sends a notification to the scanner. The new state of the button characteristic value should be equal to 0x00. + +  + + **figure 7** Notification of button depressed using Master Control Panel 4.0.5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/#b630517008bbe47592927cc8e5dfcd2e5b9de968
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/.gitignore Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,9 @@ +# vim temporary files +*.sw* + +# yotta files +build +yotta_modules +yotta_targets +.yotta.json +upload.tar.gz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,34 @@ +# BLE-X-NUCLEO-IDB0XA1 + +BLE_API wrapper Library for X-NUCLEO-IDB05A1 BlueNRG (Bluetooth Low Energy) Expansion Board + +## Introduction + +This firmware package implements the port of BLE_API to STMicroelectronics' [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) Bluetooth Low Energy Nucleo Expansion Board. + +### Arduino Connector Compatibility Warning + +X-NUCLEO-IDB05A1 is Arduino compatible with an exception: instead of using pin **D13** for the SPI clock, pin **D3** is used. +The default configuration for this library is having the SPI clock on pin **D3**. + +To be fully Arduino compatible, X-NUCLEO-IDB05A1 needs a small HW patch. + +For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor **R4** and instead soldering zero resistor **R6**. + +In case you patch your board, then you also have to configure this library to use pin **D13** to drive the SPI clock. To this aim you need to compile this driver with macro `BLUENRG_PIN_SPI_SCK=D13` defined. + +If you use pin **D13** for the SPI clock, please be aware that on STM32 Nucleo boards you may **not** drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin **D13**. + +Referring to the current list of tested platforms (see [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) page), the patch is required by [ST-Nucleo-F103RB](https://developer.mbed.org/platforms/ST-Nucleo-F103RB/); [ST-Nucleo-F302R8](https://developer.mbed.org/platforms/ST-Nucleo-F302R8/); [ST-Nucleo-F411RE](https://developer.mbed.org/platforms/ST-Nucleo-F411RE/); [ST-Nucleo-F446RE](https://developer.mbed.org/platforms/ST-Nucleo-F446RE/); and [FRDM-K64F](https://developer.mbed.org/platforms/FRDM-K64F/). + +### Firmware update + +For better performance and compatibility with latest mbed API, you should update firmware of X-NUCLEO-IDB05A1 component by using this simple [application](https://developer.mbed.org/teams/ST/code/BlueNRG-MS-Stack-Updater). + +### Driver configuration + +In order to use the BlueNRG-MS module together with other targets, you need to set the macros defined in file [bluenrg_targets.h](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/bluenrg/bluenrg_targets.h). Please, update the [mbed_lib.json](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/mbed_lib.json) to include the list of extra macros that configure the driver for your target. + +## Example Applications + +To run BLE example applications using X-NUCLEO-IDB05A1 Expansion Board based on mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli), please refer to section [Using ST shield on other targets](https://github.com/ARMmbed/mbed-os-example-ble#using-st-nucleo-shield-on-other-targets) in the official [mbed-os-example-ble](https://github.com/ARMmbed/mbed-os-example-ble) page.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.h + * @author STMicroelectronics + * @brief Header file for BLEDeviceInstanceBase based BlueNRGDevice + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_DEVICE_H__ +#define __BLUENRG_DEVICE_H__ + +#define BLUENRG +#define DEBUG_BLUENRG_USER + +#include "btle.h" + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "ble/BLEInstanceBase.h" +#include "ble/BLE.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" + + +class BlueNRGDevice : public BLEInstanceBase +{ + +public: + BlueNRGDevice(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, PinName irq); + virtual ~BlueNRGDevice(void); + + virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback); + virtual ble_error_t shutdown(void); + virtual const char *getVersion(void); + virtual Gap& getGap(); + virtual const Gap& getGap() const; + virtual GattServer& getGattServer(); + virtual const GattServer& getGattServer() const; + virtual void waitForEvent(void); + + virtual GattClient& getGattClient() { + return BlueNRGGattClient::getInstance(); + } + + virtual SecurityManager& getSecurityManager() { + return *sm; + } + + virtual const SecurityManager& getSecurityManager() const { + return *sm; + } + void reset(void); + virtual bool hasInitialized(void) const { + return isInitialized; + } + + uint8_t getUpdaterHardwareVersion(uint8_t *hw_version); + int updateFirmware(const uint8_t *fw_image, uint32_t fw_size); + bool dataPresent(); + int32_t spiRead(uint8_t *buffer, uint8_t buff_size); + int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2); + void disable_irq(); + void enable_irq(); + + virtual void processEvents(); + +private: + bool isInitialized; + + SPI spi_; + DigitalOut nCS_; + DigitalOut rst_; + InterruptIn irq_; + + //FIXME: TBI (by now just placeholders to let build + /*** betzw: placeholders ***/ + SecurityManager *sm; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ +#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ + +#include "ble/DiscoveredCharacteristic.h" + +class BlueNRGGattClient; /* forward declaration */ + +class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic { +public: + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + + void setLastHandle(GattAttribute::Handle_t lastHandleIn); +}; + +#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGGap.h + * @author STMicroelectronics + * @brief Header file for BlueNRG BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GAP_H__ +#define __BLUENRG_GAP_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/Gap.h" + +#define BLE_CONN_HANDLE_INVALID 0x0 +#define BDADDR_SIZE 6 + +#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020) +#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000) +#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0) + +// Scanning and Connection Params used by Central for creating connection +#define GAP_OBSERVATION_PROC (0x80) + +#define SCAN_P (0x0010) +#define SCAN_L (0x0010) +#define SUPERV_TIMEOUT (0xC80) +#define CONN_P(x) ((int)((x)/1.25f)) +#define CONN_L(x) ((int)((x)/0.625f)) +#define CONN_P1 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_P2 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_L1 (0x0008) +#define CONN_L2 (0x0008) +#define GUARD_INT 5 //msec +#define MIN_INT_CONN 0x0006 //=>7.5msec +#define MAX_INT_CONN 0x0C80 //=>4000msec +#define DEF_INT_CONN 0x0140 //=>400msec (default value for connection interval) + +/**************************************************************************/ +/*! + \brief + +*/ +/**************************************************************************/ +class BlueNRGGap : public Gap +{ +public: + static BlueNRGGap &getInstance() { + static BlueNRGGap m_instance; + return m_instance; + } + + enum Reason_t { + DEVICE_FOUND, + DISCOVERY_COMPLETE + }; + + /* Functions that must be implemented from Gap */ + virtual ble_error_t setAddress(addr_type_t type, const BLEProtocol::AddressBytes_t address); + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address); + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &); + virtual ble_error_t startAdvertising(const GapAdvertisingParams &); + virtual ble_error_t stopAdvertising(void); + virtual ble_error_t stopScan(); + virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);} + virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);} + virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);} + virtual ble_error_t disconnect(DisconnectionReason_t reason); + virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason); + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params); + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); + + virtual ble_error_t setDeviceName(const uint8_t *deviceName); + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); + virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance); + virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP); + + virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode); + virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode); + virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const; + virtual ScanningPolicyMode_t getScanningPolicyMode(void) const; + + virtual ble_error_t setTxPower(int8_t txPower); + virtual void getPermittedTxPowerValues(const int8_t **, size_t *); + + virtual ble_error_t connect(const Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams); + + virtual ble_error_t reset(void); + + void Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI); + ble_error_t createConnection(void); + + void setConnectionHandle(uint16_t con_handle); + uint16_t getConnectionHandle(void); + + bool getIsSetAddress(); + + // ADV timeout handling + Timeout& getAdvTimeout(void) { + return advTimeout; + } + uint8_t getAdvToFlag(void) { + return AdvToFlag; + } + void setAdvToFlag(void); + + // SCAN timeout handling + Timeout& getScanTimeout(void) { + return scanTimeout; + } + uint8_t getScanToFlag(void) { + return ScanToFlag; + } + void setScanToFlag(void); + + void Process(void); + + GapScanningParams* getScanningParams(void); + + virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams); + + void setConnectionInterval(uint16_t interval); + Gap::Role_t getGapRole(void); + void setGapRole(Gap::Role_t role); + +private: + uint16_t m_connectionHandle; + Role_t gapRole; + AddressType_t addr_type; + Address_t _peerAddr; + AddressType_t _peerAddrType; + uint8_t bdaddr[BDADDR_SIZE]; + bool _scanning; + bool _connecting; + bool isSetAddress; + uint8_t deviceAppearance[2]; + + // ADV timeout handling + Timeout advTimeout; + bool AdvToFlag; + + // SCAN timeout handling + Timeout scanTimeout; + bool ScanToFlag; + + static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) { + return (duration * 625) / 1000; + } + + uint16_t scanInterval; + uint16_t scanWindow; + uint16_t advInterval; + uint16_t slaveConnIntervMin; + uint16_t slaveConnIntervMax; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + void setAdvParameters(void); + void setConnectionParameters(void); + + Gap::AdvertisingPolicyMode_t advertisingPolicyMode; + Gap::ScanningPolicyMode_t scanningPolicyMode; + + Whitelist_t whitelistAddresses; + + ble_error_t updateAdvertisingData(void); + + BlueNRGGap() : AdvToFlag(false), ScanToFlag(false) { + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + addr_type = BLEProtocol::AddressType::RANDOM_STATIC; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + isSetAddress = false; + memset(deviceAppearance, 0, sizeof(deviceAppearance)); + } + + BlueNRGGap(BlueNRGGap const &); + void operator=(BlueNRGGap const &); + + GapAdvertisingData _advData; + GapAdvertisingData _scanResponse; +}; + +#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,157 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattClient.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CLIENT_H__ +#define __BLUENRG_GATT_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattConnectionClient.h" + +using namespace std; + +#define MAX_ACTIVE_CONNECTIONS 7 + +class BlueNRGGattClient : public GattClient +{ +public: + static BlueNRGGattClient &getInstance() { + static BlueNRGGattClient m_instance; + return m_instance; + } + + ble_error_t createGattConnectionClient(Gap::Handle_t connectionHandle); + ble_error_t removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason); + + /* Functions that must be implemented from GattClient */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + virtual bool isServiceDiscoveryActive(void) const; + virtual void terminateServiceDiscovery(void); + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback); + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + virtual ble_error_t write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + virtual ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + virtual ble_error_t reset(void); + + void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code); + + void primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(Gap::Handle_t connectionHandle); + + void serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length); + + +protected: + + BlueNRGGattClient(): _connectionPool() {}; + + ServiceDiscovery::TerminationCallback_t terminationCallback; + +private: + + BlueNRGGattClient(BlueNRGGattClient const &); + void operator=(BlueNRGGattClient const &); + + BlueNRGGattConnectionClient *_connectionPool[MAX_ACTIVE_CONNECTIONS]; + uint8_t _numConnections; + + BlueNRGGattConnectionClient * getGattConnectionClient(Gap::Handle_t connectionHandle); + +}; + +#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,185 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattConnectionClient.cpp + * @author STMicroelectronics + * @brief Header file for BlueNRGGattConnectionClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CONNECTION_CLIENT_H__ +#define __BLUENRG_GATT_CONNECTION_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" + +using namespace std; + +#define BLE_TOTAL_DISCOVERED_SERVICES 10 +#define BLE_TOTAL_DISCOVERED_CHARS 10 + +class BlueNRGGattConnectionClient +{ +public: + + enum { + GATT_IDLE, + GATT_SERVICE_DISCOVERY, + GATT_CHAR_DESC_DISCOVERY, + //GATT_CHARS_DISCOVERY_COMPLETE, + //GATT_DISCOVERY_TERMINATED, + GATT_READ_CHAR, + GATT_WRITE_CHAR + }; + + /* Functions that must be implemented from GattClient */ + ble_error_t launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + bool isServiceDiscoveryActive(void) const; + void terminateServiceDiscovery(void); + void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + } + ble_error_t read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + ble_error_t write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + ble_error_t reset(void); + + void gattProcedureCompleteCB(uint8_t error_code); + + void primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(void); + + void serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(uint8_t event_data_length); + +protected: + + BlueNRGGattConnectionClient(BlueNRGGattClient *gattClient, Gap::Handle_t connectionHandle): + discoveredService(), + discoveredChar(), + readCBParams(), + writeCBParams(), + _characteristic() { + + //PRINTF("BlueNRGGattConnectionClient construtor: connHandle=%d\n\r", connectionHandle); + + _gattClient = gattClient; + _connectionHandle = connectionHandle; + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + } + + ServiceDiscovery::ServiceCallback_t serviceDiscoveryCallback; + ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback; + ServiceDiscovery::TerminationCallback_t terminationCallback; + CharacteristicDescriptorDiscovery::DiscoveryCallback_t charDescDiscoveryCallback; + CharacteristicDescriptorDiscovery::TerminationCallback_t charDescTerminationCallback; + +private: + + BlueNRGGattConnectionClient(BlueNRGGattConnectionClient const &); + void operator=(BlueNRGGattConnectionClient const &); + ~BlueNRGGattConnectionClient() {}; + + BlueNRGGattClient *_gattClient; + + Gap::Handle_t _connectionHandle; + DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES]; + BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS]; + + GattReadCallbackParams readCBParams; + GattWriteCallbackParams writeCBParams; + + // The char for which the descriptor discovery has been launched + DiscoveredCharacteristic _characteristic; + + UUID _matchingServiceUUID; + UUID _matchingCharacteristicUUIDIn; + uint8_t _currentState; + uint8_t _numServices, _servIndex; + uint8_t _numChars; + uint8_t _numCharDesc; + + friend class BlueNRGGattClient; +}; + +#endif /* __BLUENRG_GATT_CONNECTION_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_SERVER_H__ +#define __BLUENRG_GATT_SERVER_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattService.h" +#include "ble/GattServer.h" +#include <vector> +#include <map> + +#define BLE_TOTAL_CHARACTERISTICS 10 + +using namespace std; + +class BlueNRGGattServer : public GattServer +{ +public: + static BlueNRGGattServer &getInstance() { + static BlueNRGGattServer m_instance; + return m_instance; + } + + enum HandleEnum_t { + CHAR_HANDLE = 0, + CHAR_VALUE_HANDLE, + CHAR_DESC_HANDLE + }; + + /* Functions that must be implemented from GattServer */ + virtual ble_error_t addService(GattService &); + virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t initializeGATTDatabase(void); + + virtual bool isOnDataReadAvailable() const { + return true; + } + + virtual ble_error_t reset(void); + + /* BlueNRG Functions */ + void eventCallback(void); + //void hwCallback(void *pckt); + ble_error_t Read_Request_CB(uint16_t attributeHandle); + uint8_t Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, + uint8_t data_length, const uint8_t* data + ); + GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle); + void HCIDataWrittenEvent(const GattWriteCallbackParams *params); + void HCIDataReadEvent(const GattReadCallbackParams *params); + void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle); + void HCIDataSentEvent(unsigned count); + +private: + + // compute the number of attribute record needed by a service + static uint16_t computeAttributesRecord(GattService& service); + + + static const int MAX_SERVICE_COUNT = 10; + uint8_t serviceCount; + uint8_t characteristicCount; + uint16_t servHandle, charHandle; + + std::map<uint16_t, uint16_t> bleCharHandleMap; // 1st argument is characteristic, 2nd argument is service + GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS]; + uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS]; + + BlueNRGGattServer() { + serviceCount = 0; + characteristicCount = 0; + }; + + BlueNRGGattServer(BlueNRGGattServer const &); + void operator=(BlueNRGGattServer const &); + + static const int CHAR_DESC_TYPE_16_BIT=0x01; + static const int CHAR_DESC_TYPE_128_BIT=0x02; + static const int CHAR_DESC_SECURITY_PERMISSION=0x00; + static const int CHAR_DESC_ACCESS_PERMISSION=0x03; + static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_CLOCK_H__ +#define __BLE_CLOCK_H__ + +#include <ble_hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __BLE_CLOCK_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file ble_debug.h + * @author CL + * @version V1.0.0 + * @date 04-July-2014 + * @brief This file defines print functions for debug purposes. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLE_DEBUG_H +#define __BLE_DEBUG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> + +/* Exported macro ------------------------------------------------------------*/ +//#define DEBUG +#ifdef DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Print the data travelling over the SPI in the .csv format for the GUI*/ +//#define PRINT_CSV_FORMAT +#ifdef PRINT_CSV_FORMAT +#include <stdio.h> +#define PRINT_CSV(...) printf(__VA_ARGS__) +#else +#define PRINT_CSV(...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __BLE_DEBUG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_gp_timer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : General purpose timer library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_GP_TIMER_H__ +#define __BLE_GP_TIMER_H__ + +#include "ble_clock.h" +#include "ble_status.h" +#ifdef __DMA_LP__ +#include "stm32xx_timerserver.h" +#endif /* __DMA_LP__ */ + +/** + * timer + * + * A structure that represents a timer. Use Timer_Set() to set the timer. + * + */ +struct timer { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + tClockTime start; + tClockTime interval; + +#endif +}; + +typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); + +/** + * Timer_Set + * + * @param[in] t Pointer to a timer structure + * @param[in] interval timeout value + * + * This function sets the timeout value of a timer. + * + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * Timer_Reset + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the time it previously expired. + * + */ +void Timer_Reset(struct timer *t); + +/** + * Timer_Restart + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the current time. + * + */ +void Timer_Restart(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns TRUE if timer is expired, FALSE otherwise. + * + */ +int Timer_Expired(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns the time needed for expiration. + * + * @return Time before timer's expiration. + */ +tClockTime Timer_Remaining(struct timer *t); + +#ifdef __DMA_LP__ +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID); + +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); +#endif /* __DMA_LP__ */ + +#endif /* __BLE_GP_TIMER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,108 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_H__ +#define __BLE_HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void signalEventsToProcess(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __BLE_HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_TYPES_H__ +#define __BLE_HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __BLE_HAL_TYPES_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,126 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.0, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_H_ +#define __BLE_HCI_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ble_hal_types.h" +#include "ble_link_layer.h" +#include <ble_list.h> + +#define HCI_READ_PACKET_SIZE 128 //71 + +/** + * Maximum payload of HCI commands that can be sent. Change this value if needed. + * This value can be up to 255. + */ +#define HCI_MAX_PAYLOAD_SIZE 128 + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_READ_PACKET_SIZE]; + uint8_t data_len; +} tHciDataPacket; + +struct hci_request { + uint16_t ogf; + uint16_t ocf; + int event; + void *cparam; + int clen; + void *rparam; + int rlen; +}; + +typedef enum +{ + BUSY, + AVAILABLE +} HCI_CMD_STATUS_t; + + +/** + * This function must be used to pass the packet received from the HCI + * interface to the BLE Stack HCI state machine. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * + */ +void HCI_Input(tHciDataPacket *hciReadPacket); + +/** + * Initialization function. Must be done before any data can be received from + * BLE controller. + */ +void HCI_Init(void); + +/** + * Callback used to pass events to application. + * + * @param[in] pckt The event. + * + */ +extern void HCI_Event_CB(void *pckt); + +/** + * Processing function that must be called after an event is received from + * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if + * necessary. +*/ +void HCI_Process(void); + +/** + * @brief Check if queue of HCI event is empty or not. + * @note This funtion can be used to check if the event queue from BlueNRG is empty. This + * is useful when checking if it is safe to go to sleep. + * @return TRUE if event queue is empty. FALSE otherwhise. + */ +BOOL HCI_Queue_Empty(void); +/** + * Iterrupt service routine that must be called when the BlueNRG + * reports a packet received or an event to the host through the + * BlueNRG interrupt line. + */ +#ifdef __DMA_LP__ +void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); +void HCI_Process_Notification_Request(void); +void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); +void HCI_Wait_For_Response(void); +#else +void HCI_Isr(void); +void HCI_HandleSPI(void); + +int hci_send_req(struct hci_request *r, BOOL async); +#endif /* __DMA_LP__ */ + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#ifdef __cplusplus +} +#endif + + +#endif /* __BLE_HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,548 @@ +/****************************************************************************** +* +* File Description +* --------------------- +* This file defines constants and functions for HCI layer. +* See Bluetooth Core v 4.0, Vol. 2, Part E. +* +*******************************************************************************/ + +#ifndef __HCI_INTERNAL_H_ +#define __HCI_INTERNAL_H_ + +#include "ble_compiler.h" +#include "ble_hal_types.h" +#include "ble_clock.h" +#include "ble_link_layer.h" +#include "ble_hci.h" + +#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) + + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +typedef __packed struct _hci_uart_pckt{ + uint8_t type; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef __packed struct _hci_command_hdr{ + uint16_t opcode; /* OCF & OGF */ + uint8_t plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef __packed struct _hci_event_pckt{ + uint8_t evt; + uint8_t plen; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef __packed struct _hci_acl_hdr{ + uint16_t handle; /* Handle & Flags(PB, BC) */ + uint16_t dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef __packed struct _disconnect_cp{ + uint16_t handle; + uint8_t reason; +} PACKED disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 + +#define OCF_SET_EVENT_MASK 0x0001 +#define OCF_RESET 0x0003 + +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D +typedef __packed struct _read_transmit_power_level_cp{ + uint16_t handle; + uint8_t type; +} PACKED read_transmit_power_level_cp; +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 +typedef __packed struct _read_transmit_power_level_rp{ + uint8_t status; + uint16_t handle; + int8_t level; +} PACKED read_transmit_power_level_rp; +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 + +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 +#define OCF_HOST_BUFFER_SIZE 0x0033 +#define OCF_HOST_NUM_COMP_PKTS 0x0035 + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef __packed struct _read_local_version_rp{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t manufacturer_name; + uint16_t lmp_pal_subversion; +} PACKED read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_COMMANDS 0x0002 +#define OCF_READ_LOCAL_FEATURES 0x0003 + +#define OCF_READ_BD_ADDR 0x0009 +typedef __packed struct _read_bd_addr_rp{ + uint8_t status; + tBDAddr bdaddr; +} PACKED read_bd_addr_rp; +#define READ_BD_ADDR_RP_SIZE 7 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +#define OCF_READ_RSSI 0x0005 +typedef __packed struct _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef __packed struct _read_rssi_rp{ + uint8_t status; + uint16_t handle; + int8_t rssi; +} PACKED read_rssi_rp; +#define READ_RSSI_RP_SIZE 4 + + +/* LE commands */ +#define OGF_LE_CTL 0x08 + +#define OCF_LE_SET_EVENT_MASK 0x0001 +typedef __packed struct _le_set_event_mask_cp{ + uint8_t mask[8]; +} PACKED le_set_event_mask_cp; +#define LE_SET_EVENT_MASK_CP_SIZE 8 + +#define OCF_LE_READ_BUFFER_SIZE 0x0002 +typedef __packed struct _le_read_buffer_size_rp{ + uint8_t status; + uint16_t pkt_len; + uint8_t max_pkt; +} PACKED le_read_buffer_size_rp; +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 + +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 +typedef __packed struct _le_read_local_supported_features_rp{ + uint8_t status; + uint8_t features[8]; +} PACKED le_read_local_supported_features_rp; +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 + +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 +typedef __packed struct _le_set_random_address_cp{ + tBDAddr bdaddr; +} PACKED le_set_random_address_cp; +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 + +#define OCF_LE_SET_ADV_PARAMETERS 0x0006 +typedef __packed struct _le_set_adv_parameters_cp{ + uint16_t min_interval; + uint16_t max_interval; + uint8_t advtype; + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint8_t chan_map; + uint8_t filter; +} PACKED le_set_adv_parameters_cp; +#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 + +#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 +typedef __packed struct _le_read_adv_channel_tx_power_rp{ + uint8_t status; + int8_t level; +} PACKED le_read_adv_channel_tx_power_rp; +#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 + +#define OCF_LE_SET_ADV_DATA 0x0008 +typedef __packed struct _le_set_adv_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_adv_data_cp; +#define LE_SET_ADV_DATA_CP_SIZE 32 + +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 +typedef __packed struct _le_set_scan_response_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_scan_response_data_cp; +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 + +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A +typedef __packed struct _le_set_advertise_enable_cp{ + uint8_t enable; +} PACKED le_set_advertise_enable_cp; +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 + +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B +typedef __packed struct _le_set_scan_parameters_cp{ + uint8_t type; + uint16_t interval; + uint16_t window; + uint8_t own_bdaddr_type; + uint8_t filter; +} PACKED le_set_scan_parameters_cp; +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 + +#define OCF_LE_SET_SCAN_ENABLE 0x000C +typedef __packed struct _le_set_scan_enable_cp{ + uint8_t enable; + uint8_t filter_dup; +} PACKED le_set_scan_enable_cp; +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 + +#define OCF_LE_CREATE_CONN 0x000D +typedef __packed struct _le_create_connection_cp{ + uint16_t interval; + uint16_t window; + uint8_t initiator_filter; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_create_connection_cp; +#define LE_CREATE_CONN_CP_SIZE 25 + +#define OCF_LE_CREATE_CONN_CANCEL 0x000E + +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F +typedef __packed struct _le_read_white_list_size_rp{ + uint8_t status; + uint8_t size; +} PACKED le_read_white_list_size_rp; +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 + +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 +typedef __packed struct _le_add_device_to_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_add_device_to_white_list_cp; +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 +typedef __packed struct _le_remove_device_from_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_remove_device_from_white_list_cp; +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_CONN_UPDATE 0x0013 +typedef __packed struct _le_connection_update_cp{ + uint16_t handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_connection_update_cp; +#define LE_CONN_UPDATE_CP_SIZE 14 + +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 +typedef __packed struct _le_set_host_channel_classification_cp{ + uint8_t map[5]; +} PACKED le_set_host_channel_classification_cp; +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 + +#define OCF_LE_READ_CHANNEL_MAP 0x0015 +typedef __packed struct _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef __packed struct _le_read_channel_map_rp{ + uint8_t status; + uint16_t handle; + uint8_t map[5]; +} PACKED le_read_channel_map_rp; +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 + +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 +typedef __packed struct _le_read_remote_used_features_cp{ + uint16_t handle; +} PACKED le_read_remote_used_features_cp; +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 + +#define OCF_LE_ENCRYPT 0x0017 +typedef __packed struct _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef __packed struct _le_encrypt_rp{ + uint8_t status; + uint8_t encdata[16]; +} PACKED le_encrypt_rp; +#define LE_ENCRYPT_RP_SIZE 17 + +#define OCF_LE_RAND 0x0018 +typedef __packed struct _le_rand_rp{ + uint8_t status; + uint8_t random[8]; +} PACKED le_rand_rp; +#define LE_RAND_RP_SIZE 9 + +#define OCF_LE_START_ENCRYPTION 0x0019 +typedef __packed struct _le_start_encryption_cp{ + uint16_t handle; + uint8_t random[8]; + uint16_t diversifier; + uint8_t key[16]; +} PACKED le_start_encryption_cp; +#define LE_START_ENCRYPTION_CP_SIZE 28 + +#define OCF_LE_LTK_REPLY 0x001A +typedef __packed struct _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef __packed struct _le_ltk_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_reply_rp; +#define LE_LTK_REPLY_RP_SIZE 3 + +#define OCF_LE_LTK_NEG_REPLY 0x001B +typedef __packed struct _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef __packed struct _le_ltk_neg_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_neg_reply_rp; +#define LE_LTK_NEG_REPLY_RP_SIZE 3 + +#define OCF_LE_READ_SUPPORTED_STATES 0x001C +typedef __packed struct _le_read_supported_states_rp{ + uint8_t status; + uint8_t states[8]; +} PACKED le_read_supported_states_rp; +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 + +#define OCF_LE_RECEIVER_TEST 0x001D +typedef __packed struct _le_receiver_test_cp{ + uint8_t frequency; +} PACKED le_receiver_test_cp; +#define LE_RECEIVER_TEST_CP_SIZE 1 + +#define OCF_LE_TRANSMITTER_TEST 0x001E +typedef __packed struct _le_transmitter_test_cp{ + uint8_t frequency; + uint8_t length; + uint8_t payload; +} PACKED le_transmitter_test_cp; +#define LE_TRANSMITTER_TEST_CP_SIZE 3 + +#define OCF_LE_TEST_END 0x001F +typedef __packed struct _le_test_end_rp{ + uint8_t status; + uint16_t num_pkts; +} PACKED le_test_end_rp; +#define LE_TEST_END_RP_SIZE 3 + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3f + + +/*------------- Events -------------*/ +#define EVT_CONN_COMPLETE 0x03 +typedef __packed struct _evt_conn_complete{ + uint8_t status; + uint16_t handle; + tBDAddr bdaddr; + uint8_t link_type; + uint8_t encr_mode; +} PACKED evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef __packed struct _evt_disconn_complete{ + uint8_t status; + uint16_t handle; + uint8_t reason; +} PACKED evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef __packed struct _evt_encrypt_change{ + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} PACKED evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C + +#define EVT_CMD_COMPLETE 0x0E +typedef __packed struct _evt_cmd_complete{ + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef __packed struct _evt_cmd_status{ + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef __packed struct _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef __packed struct _evt_num_comp_pkts{ + uint8_t num_hndl; + /* variable length part */ +} PACKED evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +/* variable length part of evt_num_comp_pkts. */ +typedef __packed struct _evt_num_comp_pkts_param{ + uint16_t hndl; + uint16_t num_comp_pkts; +} PACKED evt_num_comp_pkts_param; +#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 + +#define EVT_DATA_BUFFER_OVERFLOW 0x1A +typedef __packed struct _evt_data_buffer_overflow{ + uint8_t link_type; +} PACKED evt_data_buffer_overflow; +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 + +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef __packed struct _evt_encryption_key_refresh_complete{ + uint8_t status; + uint16_t handle; +} PACKED evt_encryption_key_refresh_complete; +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 + +#define EVT_LE_META_EVENT 0x3E +typedef __packed struct _evt_le_meta_event{ + uint8_t subevent; + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef __packed struct _evt_le_connection_complete{ + uint8_t status; + uint16_t handle; + uint8_t role; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; +} PACKED evt_le_connection_complete; +#define EVT_LE_CONN_COMPLETE_SIZE 18 + +#define EVT_LE_ADVERTISING_REPORT 0x02 +typedef __packed struct _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t data_length; + uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef __packed struct _evt_le_connection_update_complete{ + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; +} PACKED evt_le_connection_update_complete; +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 + +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +typedef __packed struct _evt_le_read_remote_used_features_complete{ + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} PACKED evt_le_read_remote_used_features_complete; +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 + +#define EVT_LE_LTK_REQUEST 0x05 +typedef __packed struct _evt_le_long_term_key_request{ + uint16_t handle; + uint8_t random[8]; + uint16_t ediv; +} PACKED evt_le_long_term_key_request; +#define EVT_LE_LTK_REQUEST_SIZE 12 + +/** +* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, +* application can use @ref evt_blue_aci structure to parse the packet. +*/ +#define EVT_VENDOR 0xFF + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + + + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); + +typedef enum { + WAITING_TYPE, + WAITING_OPCODE1, + WAITING_OPCODE2, + WAITING_EVENT_CODE, + WAITING_HANDLE, + WAITING_HANDLE_FLAG, + WAITING_PARAM_LEN, + WAITING_DATA_LEN1, + WAITING_DATA_LEN2, + WAITING_PAYLOAD +}hci_state; + +typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); + +/* HCI library functions. */ + +int hci_send_req(struct hci_request *r, BOOL async); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,170 @@ +/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +* File Name : ble_hci_le.h +* Author : AMG RF FW team +* Version : V1.1.0 +* Date : 18-July-2016 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.1, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_LE_H_ +#define __BLE_HCI_LE_H_ + +#include "ble_hal_types.h" +#include "ble_link_layer.h" + +/** + * @defgroup HCI_Error_codes HCI Error codes + * @{ + */ +#define HCI_UNKNOWN_COMMAND 0x01 +#define HCI_NO_CONNECTION 0x02 +#define HCI_HARDWARE_FAILURE 0x03 +#define HCI_PAGE_TIMEOUT 0x04 +#define HCI_AUTHENTICATION_FAILURE 0x05 +#define HCI_PIN_OR_KEY_MISSING 0x06 +#define HCI_MEMORY_FULL 0x07 +#define HCI_CONNECTION_TIMEOUT 0x08 +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a +#define HCI_ACL_CONNECTION_EXISTS 0x0b +#define HCI_COMMAND_DISALLOWED 0x0c +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d +#define HCI_REJECTED_SECURITY 0x0e +#define HCI_REJECTED_PERSONAL 0x0f +#define HCI_HOST_TIMEOUT 0x10 +#define HCI_UNSUPPORTED_FEATURE 0x11 +#define HCI_INVALID_PARAMETERS 0x12 +#define HCI_OE_USER_ENDED_CONNECTION 0x13 +#define HCI_OE_LOW_RESOURCES 0x14 +#define HCI_OE_POWER_OFF 0x15 +#define HCI_CONNECTION_TERMINATED 0x16 +#define HCI_REPEATED_ATTEMPTS 0x17 +#define HCI_PAIRING_NOT_ALLOWED 0x18 +#define HCI_UNKNOWN_LMP_PDU 0x19 +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a +#define HCI_SCO_OFFSET_REJECTED 0x1b +#define HCI_SCO_INTERVAL_REJECTED 0x1c +#define HCI_AIR_MODE_REJECTED 0x1d +#define HCI_INVALID_LMP_PARAMETERS 0x1e +#define HCI_UNSPECIFIED_ERROR 0x1f +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 +#define HCI_UNIT_LINK_KEY_USED 0x26 +#define HCI_QOS_NOT_SUPPORTED 0x27 +#define HCI_INSTANT_PASSED 0x28 +#define HCI_PAIRING_NOT_SUPPORTED 0x29 +#define HCI_TRANSACTION_COLLISION 0x2a +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c +#define HCI_QOS_REJECTED 0x2d +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e +#define HCI_INSUFFICIENT_SECURITY 0x2f +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 +#define HCI_ROLE_SWITCH_PENDING 0x32 +#define HCI_SLOT_VIOLATION 0x34 +#define HCI_ROLE_SWITCH_FAILED 0x35 +#define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 +#define HCI_CONN_REJ_NO_CH_FOUND 0x39 +#define HCI_CONTROLLER_BUSY 0x3A +#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B +#define HCI_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_CONN_TERM_MIC_FAIL 0x3D +#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E +#define HCI_MAC_CONN_FAILED 0x3F +/** + * @} + */ + + +/* + * HCI library functions. + * Each function returns 0 in case of success, otherwise one of the error codes. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(uint8_t enable); + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter); + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter); + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); + +int hci_le_rand(uint8_t random_number[8]); + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); + +int hci_acl_data(const uint8_t * data, uint16_t len); + +int hci_le_set_random_address(tBDAddr bdaddr); + +int hci_read_bd_addr(tBDAddr bdaddr); + +int hci_le_read_white_list_size(uint8_t *size); + +int hci_le_clear_white_list(); + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); + +int hci_le_ltk_request_reply(uint8_t key[16]); + +int hci_le_ltk_request_neg_reply(); + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); + +int hci_le_create_connection_cancel(void); + +int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level); + +int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi); + +int hci_le_read_local_supported_features(uint8_t *features); + +int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); + +int hci_le_read_supported_states(uint8_t states[8]); + +int hci_le_receiver_test(uint8_t frequency); + +int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); + +int hci_le_test_end(uint16_t *num_pkts); + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion); + + + +#endif /* __BLE_HCI_LE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,161 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_link_layer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's link layer. It contains +* definition of functions for link layer, most of which are +* mapped to HCI commands. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef _BLE_LINK_LAYER_H +#define _BLE_LINK_LAYER_H + +#include <ble_status.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + *@name Advertising filter + *Advertising policy for filtering (white list related) + *@{ + */ +#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ +#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ +/** + * @} + */ + + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef uint8_t tBDAddr[6]; + + +/** + *@name Bluetooth address types + * Bluetooth address types + *@{ + */ +#define PUBLIC_ADDR (0) +#define RANDOM_ADDR (1) +#define STATIC_RANDOM_ADDR (1) +#define RESOLVABLE_PRIVATE_ADDR (2) +#define NON_RESOLVABLE_PRIVATE_ADDR (3) +/** + * @} + */ + +/** + *@name Directed advertising types + * Type of advertising during directed advertising + *@{ + */ +#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) +#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) +/** + * @} + */ + +/** + * @name Advertising type + * @{ + */ + +/** + * undirected scannable and connectable + */ +#define ADV_IND (0x00) + +/** + * directed non scannable + */ +#define ADV_DIRECT_IND (0x01) + +/** + * scannable non connectable + */ +#define ADV_SCAN_IND (0x02) + +/** + * non-connectable and no scan response + */ +#define ADV_NONCONN_IND (0x03) + +/** + * scan response + */ +#define SCAN_RSP (0x04) + +/** + * @} + */ + +/* 0X05-0XFF RESERVED */ + +/** + * @name Advertising ranges + * @{ + */ + +/** + * lowest allowed interval value for connectable types(20ms)..multiple of 625us + */ +#define ADV_INTERVAL_LOWEST_CONN (0X0020) + +/** + * highest allowed interval value (10.24s)..multiple of 625us. + */ +#define ADV_INTERVAL_HIGHEST (0X4000) + +/** + * lowest allowed interval value for non connectable types + * (100ms)..multiple of 625us. + */ +#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) + +/** + * @} + */ + +/** + * @name Advertising channels + * @{ + */ +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 +/** + * @} + */ + +/** + * @name Scan_types Scan types + * @{ + */ +#define PASSIVE_SCAN 0 +#define ACTIVE_SCAN 1 +/** + * @} + */ + +/** + * @} + */ + + +#endif /* _BLE_LINK_LAYER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,47 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for linked list library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef _BLE_LIST_H_ +#define _BLE_LIST_H_ + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +uint8_t list_is_empty (tListNode * listHead); + +void list_insert_head (tListNode * listHead, tListNode * node); + +void list_insert_tail (tListNode * listHead, tListNode * node); + +void list_remove_node (tListNode * node); + +void list_remove_head (tListNode * listHead, tListNode ** node ); + +void list_remove_tail (tListNode * listHead, tListNode ** node ); + +void list_insert_node_after (tListNode * node, tListNode * ref_node); + +void list_insert_node_before (tListNode * node, tListNode * ref_node); + +int list_get_size (tListNode * listHead); + +void list_get_next_node (tListNode * ref_node, tListNode ** node); + +void list_get_prev_node (tListNode * ref_node, tListNode ** node); + +#endif /* _BLE_LIST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_OSAL_H__ +#define __BLE_OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __BLE_OSAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,158 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_sm.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's security manager. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_SM_H__ +#define __BLE_SM_H__ + +/****************************************************************************** +* Macros +*****************************************************************************/ + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/* IO capabilities */ +/** + * @anchor IO_capabilities + * @name IO capabilities + * @{ + */ +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define IO_CAP_KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) +/** + * @} + */ + +/** + * @anchor Auth_req + * @name Authentication requirements + * @{ + */ +#define BONDING (0x01) +#define NO_BONDING (0x00) +/** + * @} + */ + +/** + * @anchor MITM_req + * @name MITM protection requirements + * @{ + */ +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor OOB_Data + * @name Out-Of-Band data + * @{ + */ +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) +/** + * @} + */ + +/** + * @anchor Author_req + * @name Authorization requirements + * @{ + */ +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor Conn_authorization + * @name Connection authorization + * @{ + */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) +/** + * @} + */ + +/** + * @anchor Use_fixed_pin + * @name Use fixed pin + * @{ + */ +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +/** + * @} + */ + +/** + * @anchor link_security_status + * @name Link security status + * @{ + */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) +/** + * @} + */ + +/** + * @anchor SMP_pairing_failed_codes + * @name SMP pairing failed reason codes + * @{ + */ +#define PASSKEY_ENTRY_FAILED (0x01) +#define OOB_NOT_AVAILABLE (0x02) +#define AUTH_REQ_CANNOT_BE_MET (0x03) +#define CONFIRM_VALUE_FAILED (0x04) +#define PAIRING_NOT_SUPPORTED (0x05) +#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) +#define CMD_NOT_SUPPORTED (0x07) +#define UNSPECIFIED_REASON (0x08) +#define VERY_EARLY_NEXT_ATTEMPT (0x09) +#define SM_INVALID_PARAMS (0x0A) +/** + * @} + */ + +/** + * @anchor pairing_failed_codes + * @name Pairing failed error codes + * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event + * @{ + */ +#define SM_PAIRING_SUCCESS (0x00) +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,188 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_status.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file with BLE Stack status codes. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_STATUS_H__ +#define __BLE_STATUS_H__ + +#include <ble_hal_types.h> + +/** @addtogroup Middlewares + * @{ + */ + +/** @defgroup ST + * @{ + */ + +/** @defgroup SimpleBlueNRG_HCI + * @{ + */ + +/** @defgroup ble_status Bluetooth Status/Error Codes + * @{ + */ + +typedef uint8_t tBleStatus; + +/* Error Codes as specified by the specification + * according to the spec the error codes range + * from 0x00 to 0x3F + */ +/** + * @name Standard error codes + * @brief Standard error codes. See Core v 4.1, Vol. 2, part D. + * @{ + */ +#define ERR_CMD_SUCCESS (0x00) +#define BLE_STATUS_SUCCESS (0x00) +#define ERR_UNKNOWN_HCI_COMMAND (0x01) +#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) + +#define ERR_AUTH_FAILURE (0x05) +#define ERR_PIN_OR_KEY_MISSING (0x06) +#define ERR_MEM_CAPACITY_EXCEEDED (0x07) +#define ERR_CONNECTION_TIMEOUT (0x08) + +#define ERR_COMMAND_DISALLOWED (0x0C) + +#define ERR_UNSUPPORTED_FEATURE (0x11) +#define ERR_INVALID_HCI_CMD_PARAMS (0x12) +#define ERR_RMT_USR_TERM_CONN (0x13) +#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) +#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) +#define ERR_LOCAL_HOST_TERM_CONN (0x16) + +#define ERR_UNSUPP_RMT_FEATURE (0x1A) + +#define ERR_INVALID_LMP_PARAM (0x1E) +#define ERR_UNSPECIFIED_ERROR (0x1F) + +#define ERR_LL_RESP_TIMEOUT (0x22) +#define ERR_LMP_PDU_NOT_ALLOWED (0x24) + +#define ERR_INSTANT_PASSED (0x28) + +#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) +#define ERR_CONTROLLER_BUSY (0x3A) + +#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) + +#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) + +#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) + + +/** + * @} + */ +/** + * @name Vendor-specific error codes + * @brief Error codes defined by ST related to BlueNRG stack + * @{ + */ +/** + * The command cannot be executed due to the current state of the device. + */ +#define BLE_STATUS_FAILED (0x41) +/** + * Some parameters are invalid. + */ +#define BLE_STATUS_INVALID_PARAMS (0x42) +/** + * It is not allowed to start the procedure (e.g. another the procedure is ongoing + * or cannot be started on the given handle). + */ +#define BLE_STATUS_NOT_ALLOWED (0x46) +/** + * Unexpected error. + */ +#define BLE_STATUS_ERROR (0x47) +#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) + +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +#define BLE_STATUS_INVALID_CID (0x50) + +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) +#define BLE_STATUS_IRK_NOT_FOUND (0x5B) +#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) +#define BLE_STATUS_SEC_DB_FULL (0x5D) +#define BLE_STATUS_DEV_NOT_BONDED (0x5E) +#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) + +#define BLE_STATUS_INVALID_HANDLE (0x60) +#define BLE_STATUS_INVALID_PARAMETER (0x61) +#define BLE_STATUS_OUT_OF_HANDLE (0x62) +#define BLE_STATUS_INVALID_OPERATION (0x63) +#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) +#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) +#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) + +/** + * Returned when no valid slots are available (e.g. when there are no available state machines). + */ +#define BLE_STATUS_NO_VALID_SLOT (0x82) + +/** + * Returned when a scan window shorter than minimum allowed value has been requested (i.e. 2ms) + */ + +#define BLE_STATUS_SCAN_WINDOW_SHORT (0x83) +/** + * Returned when the maximum requested interval to be allocated is shorter then the current + * anchor period and a there is no submultiple for the current anchor period that is between + * the minimum and the maximum requested intervals. + */ + +#define BLE_STATUS_NEW_INTERVAL_FAILED (0x84) +/** + * Returned when the maximum requested interval to be allocated is greater than the current anchor + * period and there is no multiple of the anchor period that is between the minimum and the maximum + * requested intervals. + */ + +#define BLE_STATUS_INTERVAL_TOO_LARGE (0x85) +/** + * Returned when the current anchor period or a new one can be found that is compatible to the + * interval range requested by the new slot but the maximum available length that can be allocated is + * less than the minimum requested slot length. + */ + +#define BLE_STATUS_LENGTH_FAILED (0x86) +/** + * @} + */ + +/** + * @name Library Error Codes + * @brief Error codes defined by ST related to MCU library. + * @{ + */ +#define BLE_STATUS_TIMEOUT (0xFF) +#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) +#define BLE_STATUS_NULL_PARAM (0xF1) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,813 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci_const.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with ACI definitions for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_CONST_H_ +#define __BLUENRG_ACI_CONST_H_ + +#include "ble_compiler.h" +#include "ble_link_layer.h" +#include "ble_hci_const.h" +#include "bluenrg_gatt_server.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define OCF_HAL_GET_FW_BUILD_NUMBER 0x0000 +typedef __packed struct _hal_get_fw_build_number_rp{ + uint8_t status; + uint16_t build_number; +} PACKED hal_get_fw_build_number_rp; +#define HAL_GET_FW_BUILD_NUMBER_RP_SIZE 3 +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +#define OCF_HAL_READ_CONFIG_DATA 0x000D +typedef __packed struct _hal_read_config_data_cp{ + uint8_t offset; +} PACKED hal_read_config_data_cp; +#define HAL_READ_CONFIG_DATA_RP_SIZE 1 +typedef __packed struct _hal_read_config_data_rp{ + uint8_t status; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE]; +} PACKED hal_read_config_data_rp; + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef __packed struct _hal_set_tx_power_level_cp{ + uint8_t en_high_power; + uint8_t pa_level; +} PACKED hal_set_tx_power_level_cp; +#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 + +#define OCF_HAL_DEVICE_STANDBY 0x0013 + +#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014 +typedef __packed struct _hal_le_tx_test_packet_number_rp{ + uint8_t status; + uint32_t number_of_packets; +} PACKED hal_le_tx_test_packet_number_rp; + +#define OCF_HAL_TONE_START 0x0015 +typedef __packed struct _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_HAL_TONE_STOP 0x0016 +#define OCF_HAL_GET_LINK_STATUS 0x0017 +typedef __packed struct _hal_get_link_status_rp{ + uint8_t status; + uint8_t link_status[8]; + uint16_t conn_handle[8]; +} PACKED hal_get_link_status_rp; + +#define OCF_HAL_GET_ANCHOR_PERIOD 0x0019 +typedef __packed struct _hal_get_anchor_period_rp{ + uint8_t status; + uint32_t anchor_period; + uint32_t max_free_slot; +} PACKED hal_get_anchor_period_rp; + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef __packed struct _get_updater_version_rp{ + uint8_t status; + uint8_t version; +} PACKED get_updater_version_rp; +#define GET_UPDATER_VERSION_RP_SIZE 2 + +#define OCF_GET_UPDATER_BUFSIZE 0x0023 +typedef __packed struct _get_updater_bufsize_rp{ + uint8_t status; + uint8_t buffer_size; +} PACKED get_updater_bufsize_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 + +#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 + +#define OCF_UPDATER_ERASE_SECTOR 0x0026 +typedef __packed struct _updater_erase_sector_cp{ + uint32_t address; +} PACKED updater_erase_sector_cp; +#define UPDATER_ERASE_SECTOR_CP_SIZE 4 + +#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 +#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_prog_data_block_cp{ + uint32_t address; + uint16_t data_len; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; +} PACKED updater_prog_data_block_cp; + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef __packed struct _updater_read_data_block_cp{ + uint32_t address; + uint16_t data_len; +} PACKED updater_read_data_block_cp; +#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[VARIABLE_SIZE]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef __packed struct _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef __packed struct _updater_calc_crc_rp{ + uint8_t status; + uint32_t crc; +} PACKED updater_calc_crc_rp; +#define UPDATER_CALC_CRC_RP_SIZE 5 + +#define OCF_UPDATER_HW_VERSION 0x002A +typedef __packed struct _updater_hw_version_rp{ + uint8_t status; + uint8_t version; +} PACKED updater_hw_version_rp; +#define UPDATER_HW_VERSION_RP_SIZE 2 + +#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 + +#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 + +#define OCF_GAP_SET_DISCOVERABLE 0x0083 + +#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 +typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ + uint8_t own_bdaddr_type; + uint8_t directed_adv_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint16_t adv_interv_min; + uint16_t adv_interv_max; +} PACKED gap_set_direct_conectable_cp_IDB05A1; + +typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB04A1; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef __packed struct _gap_set_io_capability_cp{ + uint8_t io_capability; +} PACKED gap_set_io_capability_cp; +#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 + +#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 +typedef __packed struct _gap_set_auth_requirement_cp{ + uint8_t mitm_mode; + uint8_t oob_enable; + uint8_t oob_data[16]; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t bonding_mode; +} PACKED gap_set_auth_requirement_cp; +#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 + +#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 +typedef __packed struct _gap_set_author_requirement_cp{ + uint16_t conn_handle; + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef __packed struct _gap_passkey_response_cp{ + uint16_t conn_handle; + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef __packed struct _gap_authorization_response_cp{ + uint16_t conn_handle; + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 + +#define OCF_GAP_INIT 0x008A +typedef __packed struct _gap_init_cp_IDB05A1{ + uint8_t role; + uint8_t privacy_enabled; + uint8_t device_name_char_len; +} PACKED gap_init_cp_IDB05A1; +#define GAP_INIT_CP_SIZE_IDB05A1 3 + +typedef __packed struct _gap_init_cp_IDB04A1{ + uint8_t role; +} PACKED gap_init_cp_IDB04A1; +#define GAP_INIT_CP_SIZE_IDB04A1 1 +typedef __packed struct _gap_init_rp{ + uint8_t status; + uint16_t service_handle; + uint16_t dev_name_char_handle; + uint16_t appearance_char_handle; +} PACKED gap_init_rp; +#define GAP_INIT_RP_SIZE 7 + +#define OCF_GAP_SET_NON_CONNECTABLE 0x008B +typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ + uint8_t advertising_event_type; + uint8_t own_address_type; +#endif +} PACKED gap_set_non_connectable_cp_IDB05A1; + +typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp_IDB04A1; + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef __packed struct _gap_set_undirected_connectable_cp{ + uint8_t adv_filter_policy; + uint8_t own_addr_type; +} PACKED gap_set_undirected_connectable_cp; +#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 + +#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D +typedef __packed struct _gap_slave_security_request_cp{ + uint16_t conn_handle; + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef __packed struct _gap_delete_ad_type_cp{ + uint8_t ad_type; +} PACKED gap_delete_ad_type_cp; +#define GAP_DELETE_AD_TYPE_CP_SIZE 1 + +#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 +typedef __packed struct _gap_get_security_level_rp{ + uint8_t status; + uint8_t mitm_protection; + uint8_t bonding; + uint8_t oob_data; + uint8_t passkey_required; +} PACKED gap_get_security_level_rp; +#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 + +#define OCF_GAP_SET_EVT_MASK 0x0091 +typedef __packed struct _gap_set_evt_mask_cp{ + uint16_t evt_mask; +} PACKED gap_set_evt_mask_cp; +#define GAP_SET_EVT_MASK_CP_SIZE 2 + +#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 + +#define OCF_GAP_TERMINATE 0x0093 +typedef __packed struct _gap_terminate_cp{ + uint16_t handle; + uint8_t reason; +} PACKED gap_terminate_cp; +#define GAP_TERMINATE_CP_SIZE 3 + +#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 + +#define OCF_GAP_ALLOW_REBOND_DB 0x0095 + +typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ + uint16_t conn_handle; +} PACKED gap_allow_rebond_cp_IDB05A1; + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef __packed struct _gap_start_limited_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_limited_discovery_proc_cp; +#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 +typedef __packed struct _gap_start_general_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_general_discovery_proc_cp; +#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 +typedef __packed struct _gap_start_name_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_name_discovery_proc_cp; +#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 + +#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 + +#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; + +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t use_reconn_addr; + tBDAddr reconn_addr; +} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; + +#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B +#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 +typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t num_whitelist_entries; + uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; +} PACKED gap_start_selective_conn_establish_proc_cp; + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef __packed struct _gap_create_connection_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_create_connection_cp; +#define GAP_CREATE_CONNECTION_CP_SIZE 24 + +#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D + +#define OCF_GAP_START_CONNECTION_UPDATE 0x009E +typedef __packed struct _gap_start_connection_update_cp{ + uint16_t conn_handle; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_connection_update_cp; +#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 + +#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F +typedef __packed struct _gap_send_pairing_request_cp{ + uint16_t conn_handle; + uint8_t force_rebond; +} PACKED gap_send_pairing_request_cp; +#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 + +#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 +typedef __packed struct _gap_resolve_private_address_cp{ + tBDAddr address; +} PACKED gap_resolve_private_address_cp; +#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 +typedef __packed struct _gap_resolve_private_address_rp{ + uint8_t status; + tBDAddr address; +} PACKED gap_resolve_private_address_rp; + +#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 +#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 +typedef __packed struct _gap_set_broadcast_mode_cp{ + uint16_t adv_interv_min; + uint16_t adv_interv_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; +} PACKED gap_set_broadcast_mode_cp; + +#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 +typedef __packed struct _gap_start_observation_proc_cp{ + uint16_t scan_interval; + uint16_t scan_window; + uint8_t scan_type; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_observation_proc_cp; + +#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 +typedef __packed struct _gap_get_bonded_devices_rp{ + uint8_t status; + uint8_t num_addr; + uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; +} PACKED gap_get_bonded_devices_rp; + +#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 +typedef __packed struct _gap_is_device_bonded_cp{ + uint8_t peer_address_type; + tBDAddr peer_address; +} PACKED gap_is_device_bonded_cp; + + +#define OCF_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef __packed struct _gatt_add_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_serv_rp; +#define GATT_ADD_SERV_RP_SIZE 3 + +#define OCF_GATT_INCLUDE_SERV 0x0103 +typedef __packed struct _gatt_include_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_include_serv_rp; +#define GATT_INCLUDE_SERV_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR 0x0104 +typedef __packed struct _gatt_add_char_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_rp; +#define GATT_ADD_CHAR_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR_DESC 0x0105 +typedef __packed struct _gatt_add_char_desc_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_desc_rp; +#define GATT_ADD_CHAR_DESC_RP_SIZE 3 + +#define OCF_GATT_UPD_CHAR_VAL 0x0106 + +#define OCF_GATT_DEL_CHAR 0x0107 +typedef __packed struct _gatt_del_char_cp{ + uint16_t service_handle; + uint16_t char_handle; +} PACKED gatt_del_char_cp; +#define GATT_DEL_CHAR_CP_SIZE 4 + +#define OCF_GATT_DEL_SERV 0x0108 +typedef __packed struct _gatt_del_serv_cp{ + uint16_t service_handle; +} PACKED gatt_del_serv_cp; +#define GATT_DEL_SERV_CP_SIZE 2 + +#define OCF_GATT_DEL_INC_SERV 0x0109 +typedef __packed struct _gatt_del_inc_serv_cp{ + uint16_t service_handle; + uint16_t inc_serv_handle; +} PACKED gatt_del_inc_serv_cp; +#define GATT_DEL_INC_SERV_CP_SIZE 4 + +#define OCF_GATT_SET_EVT_MASK 0x010A +typedef __packed struct _gatt_set_evt_mask_cp{ + uint32_t evt_mask; +} PACKED gatt_set_evt_mask_cp; +#define GATT_SET_EVT_MASK_CP_SIZE 4 + +#define OCF_GATT_EXCHANGE_CONFIG 0x010B +typedef __packed struct _gatt_exchange_config_cp{ + uint16_t conn_handle; +} PACKED gatt_exchange_config_cp; +#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 + +#define OCF_ATT_FIND_INFO_REQ 0x010C +typedef __packed struct _att_find_info_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED att_find_info_req_cp; +#define ATT_FIND_INFO_REQ_CP_SIZE 6 + +#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D +#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 +typedef __packed struct _att_find_by_type_value_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[2]; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU - 7]; +} PACKED att_find_by_type_value_req_cp; + +#define OCF_ATT_READ_BY_TYPE_REQ 0x010E +#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_type_req_cp; + +#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F +#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_group_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_group_type_req_cp; + +#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 +#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val +typedef __packed struct _att_prepare_write_req_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t value_offset; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU-5]; +} PACKED att_prepare_write_req_cp; + +#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 +typedef __packed struct _att_execute_write_req_cp{ + uint16_t conn_handle; + uint8_t execute; +} PACKED att_execute_write_req_cp; +#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 + +#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 +typedef __packed struct _gatt_disc_all_prim_serivces_cp{ + uint16_t conn_handle; +} PACKED gatt_disc_all_prim_services_cp; +#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 + +#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 +typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ + uint16_t conn_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_disc_prim_service_by_uuid_cp; +#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid + +#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 +typedef __packed struct _gatt_disc_find_included_services_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED gatt_find_included_services_cp; +#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 + +#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 +typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ + uint16_t conn_handle; + uint16_t start_attr_handle; + uint16_t end_attr_handle; +} PACKED gatt_disc_all_charac_of_serv_cp; +#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 + +#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 + +#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ + uint16_t conn_handle; + uint16_t char_val_handle; + uint16_t char_end_handle; +} PACKED gatt_disc_all_charac_descriptors_cp; +#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 + +#define OCF_GATT_READ_CHARAC_VAL 0x0118 +typedef __packed struct _gatt_read_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_val_cp; +#define GATT_READ_CHARAC_VAL_CP_SIZE 4 + +#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 +typedef __packed struct _gatt_read_using_charac_uuid_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_read_using_charac_uuid_cp; +#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID + +#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A +typedef __packed struct _gatt_read_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_val_cp; +#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 + +#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B +#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles +typedef __packed struct _gatt_read_multiple_charac_val_cp{ + uint16_t conn_handle; + uint8_t num_handles; + uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_read_multiple_charac_val_cp; + +#define OCF_GATT_WRITE_CHAR_VALUE 0x011C + +#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D +#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_write_long_charac_val_cp; + +#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E +#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_charac_reliable_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; +} PACKED gatt_write_charac_reliable_cp; + +#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F +#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; +} PACKED gatt_write_long_charac_desc_cp; + +#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 +typedef __packed struct _gatt_read_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_desc_cp; +#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 + +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 +typedef __packed struct _gatt_read_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_desc_cp; +#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 +#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 3]; +} PACKED gatt_write_without_resp_cp; + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 +#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_signed_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 13]; +} PACKED gatt_signed_write_without_resp_cp; + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 +typedef __packed struct _gatt_confirm_indication_cp{ + uint16_t conn_handle; +} PACKED gatt_confirm_indication_cp; +#define GATT_CONFIRM_INDICATION_CP_SIZE 2 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef __packed struct _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 +typedef __packed struct _gatt_set_security_permission_cp{ + uint16_t service_handle; + uint16_t attr_handle; + uint8_t security_permission; +} PACKED gatt_set_security_permission_cp; +#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_GATT_READ_HANDLE_VALUE 0x012A +typedef __packed struct _gatt_read_handle_val_cp{ + uint16_t attr_handle; +} PACKED gatt_read_handle_val_cp; +#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 +typedef __packed struct _gatt_read_handle_val_rp{ + uint8_t status; + uint16_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; +} PACKED gatt_read_handle_val_rp; + +#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B +typedef __packed struct _gatt_read_handle_val_offset_cp{ + uint16_t attr_handle; + uint8_t offset; +} PACKED gatt_read_handle_val_offset_cp; +#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 +typedef __packed struct _gatt_read_handle_val_offset_rp{ + uint8_t status; + uint8_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; +} PACKED gatt_read_handle_val_offset_rp; + +#define OCF_GATT_UPD_CHAR_VAL_EXT 0x012C +#define GATT_UPD_CHAR_VAL_EXT_CP_SIZE 10 // without value +typedef __packed struct _gatt_upd_char_val_ext_cp{ + uint16_t service_handle; + uint16_t char_handle; + uint8_t update_type; + uint16_t char_length; + uint16_t value_offset; + uint8_t value_length; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_UPD_CHAR_VAL_EXT_CP_SIZE]; +} PACKED gatt_upd_char_val_ext_cp; + +#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 +typedef __packed struct _l2cap_conn_param_update_req_cp{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_update_req_cp; +#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 + +#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint16_t min_ce_length; + uint16_t max_ce_length; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; + +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; + +/** + * @defgroup BlueNRG_Events BlueNRG events (vendor specific) + * @{ + */ + +/** + * Vendor specific event for BlueNRG. + */ +typedef __packed struct _evt_blue_aci{ + uint16_t ecode; /**< One of the BlueNRG event codes. */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_blue_aci; + + +/** + * @} + */ + +#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gap.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GAP layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BNRG_GAP_H__ +#define __BNRG_GAP_H__ + +#include <ble_link_layer.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + * @name GAP UUIDs + * @{ + */ +#define GAP_SERVICE_UUID (0x1800) +#define DEVICE_NAME_UUID (0x2A00) +#define APPEARANCE_UUID (0x2A01) +#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) +#define RECONNECTION_ADDR_UUID (0x2A03) +#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) +/** + * @} + */ + +/** + * @name Characteristic value lengths + * @{ + */ +#define DEVICE_NAME_CHARACTERISTIC_LEN (8) +#define APPEARANCE_CHARACTERISTIC_LEN (2) +#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) +#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) +#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) +/** + * @} + */ + +/*------------- AD types for adv data and scan response data ----------------*/ + +/** + * @defgroup AD_Types AD Types + * @brief AD Types + * @{ + */ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +/** + * @anchor Flags_AD_Type_bits + * @name Flags AD Type bits + * @brief Bits in Flags AD Type + * @{ + */ +#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) +#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) +#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) +#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) +#define FLAG_BIT_LE_BR_EDR_HOST (0x10) +/** + * @} + */ + +/** + * @name Service UUID AD types + * @{ + */ +#define AD_TYPE_16_BIT_SERV_UUID (0x02) +#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) +#define AD_TYPE_32_BIT_SERV_UUID (0x04) +#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) +#define AD_TYPE_128_BIT_SERV_UUID (0x06) +#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) +/** + * @} + */ + +/* LOCAL NAME AD types */ +/** + * @name Local name AD types + * @{ + */ +#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) +#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) +/** + * @} + */ + +/* TX power level AD type*/ +#define AD_TYPE_TX_POWER_LEVEL (0x0A) + +/* Class of device */ +#define AD_TYPE_CLASS_OF_DEVICE (0x0D) + +/* security manager TK value AD type */ +#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) + +/* security manager OOB flags */ +#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) + +/* slave connection interval AD type */ +#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) + +/* service solicitation UUID list Ad types*/ +/** + * @name Service solicitation UUID list AD types + * @{ + */ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) +#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) +/** + * @} + */ + +/* service data AD type */ +#define AD_TYPE_SERVICE_DATA (0x16) + +/* manufaturer specific data AD type */ +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/* appearance AD type */ +#define AD_TYPE_APPEARANCE (0x19) + +/* advertising interval AD type */ +#define AD_TYPE_ADVERTISING_INTERVAL (0x1A) + +/** + * @} + */ + +#define MAX_ADV_DATA_LEN (31) + +#define DEVICE_NAME_LEN (7) +#define BD_ADDR_SIZE (6) + +/** + * @name Privacy flag values + * @{ + */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) +/** + * @} + */ + +/** + * @name Intervals + * Intervals in terms of 625 micro sec + * @{ + */ +#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ +#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ +#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ +#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ +#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ +#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ +#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ +#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ +/** + * @} + */ + +/** + * @name Timeout values + * @{ + */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ +/** + * @} + */ + +/** + * @anchor gap_roles + * @name GAP Roles + * @{ +*/ +#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) +#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) + +#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) +#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) +/** + * @} + */ + +/** + * @anchor gap_procedure_codes + * @name GAP procedure codes + * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event + * and aci_gap_terminate_gap_procedure() command. + * @{ + */ +#define GAP_LIMITED_DISCOVERY_PROC (0x01) +#define GAP_GENERAL_DISCOVERY_PROC (0x02) +#define GAP_NAME_DISCOVERY_PROC (0x04) +#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) +#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) +#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) +#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) +#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1231 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gap_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GAP_ACI_H__ +#define __BLUENRG_GAP_ACI_H__ + +/** + *@addtogroup GAP GAP + *@brief GAP layer. + *@{ + */ + +/** + *@defgroup GAP_Functions GAP functions + *@brief API for GAP layer. + *@{ + */ + +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". + * @param privacy_enabled Enable (1) or disable (0) privacy. + * @param device_name_char_len Length of the device name characteristic + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, + uint8_t device_name_char_len, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Privacy Flag (peripheral role only) + * @li Reconnection Address (peripheral role only) + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB04A1(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); + +/** + * @brief Set the Device in non-discoverable mode. + * @note This command will disable the LL advertising. + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_discoverable(void); + +/** + * @brief Put the device in limited discoverable mode + * (as defined in GAP specification volume 3, section 9.2.3). + * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. + * The advertising can be disabled at any time by issuing + * aci_gap_set_non_discoverable() command. + * The AdvIntervMin and AdvIntervMax parameters are optional. If both + * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). + * Host can set the Local Name, a Service UUID list and the Slave Connection + * Minimum and Maximum. If provided, these data will be inserted into the + * advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() + * separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following + * standard AD types: + * @li AD Flags + * @li TX Power Level + * + * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates + * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. + * + * Example: + * @code + * + * #define ADV_INTERVAL_MIN_MS 100 + * #define ADV_INTERVAL_MAX_MS 200 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, + * (ADV_INTERVAL_MAX_MS*1000)/0.625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * sizeof(serviceUUIDList), serviceUUIDList, + * 0, 0); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 250 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 500 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg NO_WHITE_LIST_USE + * @arg WHITE_LIST_FOR_ONLY_SCAN + * @arg WHITE_LIST_FOR_ONLY_CONN + * @arg WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +/** + * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4). + * @note The device will be discoverable until the Host issue Aci_Gap_Set_Non_Discoverable command. + * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses + * the default values for advertising intervals (1.28 s and 2.56 s respectively for IDB04A1). + * When using connectable undirected advertising events:\n + * @li Adv_Interval_Min = 30 ms + * @li Adv_Interval_Max = 60 ms + * \nWhen using non-connectable advertising events or scannable undirected advertising events:\n + * @li Adv_Interval_Min = 100 ms + * @li Adv_Interval_Max = 150 ms + * Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided, + * these data will be inserted into the advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following standard AD types: + * @li AD Flags + * @li TX Power Level + * + * Usage example: + * + * @code + * + * #define ADV_INTERVAL_MIN_MS 800 + * #define ADV_INTERVAL_MAX_MS 900 + * #define CONN_INTERVAL_MIN_MS 100 + * #define CONN_INTERVAL_MAX_MS 300 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625, + * (ADV_INTERVAL_MAX_MS*1000)/625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * 0, NULL, + * (CONN_INTERVAL_MIN_MS*1000)/1250, + * (CONN_INTERVAL_MAX_MS*1000)/1250); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 1.28 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 2.56 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ONLY_SCAN + * @arg @ref WHITE_LIST_FOR_ONLY_CONN + * @arg @ref WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); + +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @param adv_interv_min Minimum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @param adv_interv_max Maximum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max); +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); + +/** + * @brief Set the IO capabilities of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param io_capability One of the allowed codes for IO Capability: + * @arg @ref IO_CAP_DISPLAY_ONLY + * @arg @ref IO_CAP_DISPLAY_YES_NO + * @arg @ref IO_CAP_KEYBOARD_ONLY + * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT + * @arg @ref IO_CAP_KEYBOARD_DISPLAY + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_io_capability(uint8_t io_capability); + +/** + * @brief Set the authentication requirements for the device. + * @note If the oob_enable is set to 0, oob_data will be ignored. + * This command has to be given only when the device is not in a connected state. + * @param mitm_mode MITM mode: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @param oob_enable If OOB data are present or not: + * @arg @ref OOB_AUTH_DATA_ABSENT + * @arg @ref OOB_AUTH_DATA_PRESENT + * @param oob_data Out-Of-Band data + * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process + * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process + * @param use_fixed_pin If application wants to use a fixed pin or not: + * @arg @ref USE_FIXED_PIN_FOR_PAIRING + * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING + * If a fixed pin is not used, it has to be provided by the application with + * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will + * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is + * accepted. + * @param bonding_mode One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode); + /** + * @brief Set the authorization requirements of the device. + * @note This command has to be given when connected to a device if authorization is required to access services + * which require authorization. + * @param conn_handle Handle of the connection. + * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required + * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables + * the authorization requirement in the device and when a remote device + * tries to read/write a characeristic with authorization requirements, the stack will + * send back an error response with "Insufficient authorization" error code. + * After pairing is complete a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event + * will be sent to the Host. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); + +/** + * @brief Provide the pass key that will be used during pairing. + * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param conn_handle Connection handle + * @param passkey Pass key that will be used during the pairing process. Must be a number between + * 0 and 999999. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); + +/** + * @brief Authorize a device to access attributes. + * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. + * + * @param conn_handle Connection handle + * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) + * @arg @ref CONNECTION_REJECTED : Reject (reject connection) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); + +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @param own_address_type If Privacy is disabled, then the peripheral address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the peripheral address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); + +/** + * @brief Put the device into undirected connectable mode. + * @note If privacy is enabled in the device, a resolvable private address is generated and used + * as the advertiser's address. If not, the address of the type specified in own_addr_type + * is used for advertising. + * @param own_addr_type Type of our address used during advertising: + * if BLUENRG (IDB04A1) + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * else if BLUENRG_MS (IDB05A1) + * If Privacy is disabled: + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled: + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_filter_policy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ALL + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); + +/** + * @brief Send a slave security request to the master. + * @note This command has to be issued to notify the master of the security requirements of the slave. + * The master may encrypt the link, initiate the pairing procedure, or reject the request. + * @param conn_handle Connection handle + * @param bonding One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @param mitm_protection If MITM protection is required or not: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); + +/** + * @brief Update advertising data. + * @note This command can be used to update the advertising data for a particular AD type. + * If the AD type specified does not exist, then it is added to the advertising data. + * If the overall advertising data length is more than 31 octets after the update, then + * the command is rejected and the old data is retained. + * @param AdvLen Length of AdvData array + * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification + * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. + * Example + * @code + * tBleStatus ret; + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; + * + * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * 8, local_name, 3, serviceUUIDList, 0, 0); + * ret = aci_gap_update_adv_data(5, manuf_data); + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); + +/** + * @brief Delete an AD Type + * @note This command can be used to delete the specified AD type from the advertisement data if + * present. + * @param ad_type One of the allowed AD types (see @ref AD_Types) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); + +/** + * @brief Get the current security settings + * @note This command can be used to get the current security settings of the device. + * @param mitm_protection @arg 0: Not required + * @arg 1: Required + * @param bonding @arg 0: No bonding mode + * @arg 1: Bonding mode + * @param oob_data @arg 0: Data absent + * @arg 1: Data present + * @param passkey_required @arg 0: Not required + * @arg 1: Fixed pin is present which is being used + * @arg 2: Passkey required for pairing. An event will be generated + * when required. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required); + +/** + * @brief Add addresses of bonded devices into the controller's whitelist. + * @note The command will return an error if there are no devices in the database or if it was unable + * to add the device into the whitelist. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_configure_whitelist(void); + +/** + * @brief Terminate a connection. + * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. + * @param conn_handle Connection handle + * @param reason Reason for requesting disconnection. The error code can be any of ones as specified + * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); + +/** + * @brief Clear the security database. + * @note All the devices in the security database will be removed. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_clear_security_database(void); + +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @param conn_handle + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB04A1(void); + +/** + * @brief Start the limited discovery procedure. + * @note The controller is commanded to start active scanning. When this procedure is started, + * only the devices in limited discoverable mode are returned to the upper layers. + * The procedure is terminated when either the upper layers issue a command to terminate the + * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code + * set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated + * due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC. + * The device found when the procedure is ongoing is returned to the upper layers through the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the general discovery procedure. + * @note The controller is commanded to start active scanning. The procedure is terminated when + * either the upper layers issue a command to terminate the procedure by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC + * or a timeout happens. When the procedure is terminated due to any of the above reasons, + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to + * @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to + * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the name discovery procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. Once a connection is established, GATT procedure is started to read the + * device name characteristic. When the read is completed (successfully or unsuccessfully), + * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also + * contains the name of the device if the device name was read successfully. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Start the auto connection establishment procedure. + * @note The devices specified are added to the white list of the controller and a LE_Create_Connection + * call will be made to the controller by GAP with the initiator filter policy set to + * use whitelist to determine which advertiser to connect to. When a command is issued to + * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the + * controller by GAP. + * The procedure is terminated when either a connection is successfully established with one of + * the specified devices in the white list or the procedure is explicitly terminated by issuing + * the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start a general connection establishment procedure. + * @note The host enables scanning in the controller with the scanner filter policy set + * to accept all advertising packets and from the scanning results all the devices + * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * The upper layer then has to select one of the devices to which it wants to connect + * by issuing the command aci_gap_create_connection(). The procedure is terminated + * when a connection is established or the upper layer terminates the procedure by + * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates); +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); + +/** + * @brief Start a selective connection establishment procedure. + * @note The GAP adds the specified device addresses into white list and enables scanning in + * the controller with the scanner filter policy set to accept packets only from + * devices in whitelist. All the devices found are sent to the upper layer by the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the + * devices to which it wants to connect by issuing the command aci_gap_create_connection(). + * On completion of the procedure a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated + * with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * The procedure is terminated when a connection is established or the upper layer terminates + * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure + * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start the direct connection establishment procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. The procedure can be terminated explicitly by the upper layer by issuing + * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the + * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller + * by GAP. + * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can + * be explicitly terminated by the upper layer by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is + * returned with the procedure code set to the corresponding procedure. + * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes"). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); + +/** + * @brief Start the connection parameter update procedure. + * @note Allowed by the Central to update the connection parameter of the specified connection. + * A Link Layer Connection Update procedure is started on the controller. + * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to + * the upper layer. + * @param conn_handle Handle of the connection for which the update procedure has to be started. + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Send a pairing request. + * @note Send the SM pairing request to start a pairing process from a Central. The authentication + * requirements and IO capabilities should be set before issuing this command using + * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). + * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. + * @param conn_handle Handle of the connection for which the pairing request has to be sent. + * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded + * @arg 0x01: Pairing request will be sent even if the device was previously bonded + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param[in] address Address to be resolved. + * @param[out] actual_address The public or static random address of the peer device, distributed during pairing phase. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); + +/** + * @brief This command gets the list of bonded devices. + * @note It returns the number of addresses and the corresponding address types and values. + * Example: + * @code + * tBleStatus ret; + * uint8_t num_devices = 0; + * uint8_t device_list[12*7]; + * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); + * for(int i = 0; i < num_devices; i+=7){ + * uint8_t addr_type = device_list[i]; + * uint8_t addr = device_list[i+1]; + * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); + * } + * @endcode + * + * @param[out] num_devices The number of bonded devices. + * @param[out] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address + * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. + * @param device_list_size Maximum size of the device_list buffer used to return the device list. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); + +/** + * @brief Puts the device into broadcast mode + * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address + * as specified in the own_addr_type parameter of the command. + * @param adv_interv_min Minimum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_interv_max Maximum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param own_addr_type If Privacy is disabled, the broadcaster address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the broadcaster address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_data_length Length of the advertising data in the advertising packet + * @param adv_data Advertising data used by the device while advertising + * @param num_whitelist_entries Number of devices to be added to whitelist + * @param addr_array It will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Starts an observation procedure, when the device is in Observer role. + * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer + * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth + * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. + * The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. + * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param own_address_type If Privacy is disabled, then the scanner address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the scanner address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates); + +/** + * @brief The command finds whether a device is bonded. + * @note If the device is using a resolvable private address and it has been bonded, then the command will return + * BLE_STATUS_SUCCESS. + * @param peer_address_type The address type of the peer device + * @arg @ref PUBLIC_ADDR. + * @arg @ref RANDOM_ADDR. + * @param peer_address Address used by the peer device while advertising. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address); + + +/** + * @} + */ + +/** + * @defgroup GAP_Events GAP events + * @{ + */ + +/** + * This event is generated by the controller when the limited discoverable + * mode ends due to timeout (180 seconds). No parameters in the event. + */ +#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) + + +/** + * This event is generated when the pairing process has completed successfully + * or a pairing procedure timeout has occurred or the pairing has failed. + * This is to notify the application that we have paired with a remote device + * so that it can take further actions or to notify that a timeout has occurred + * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. + */ +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +typedef __packed struct _evt_gap_pairing_cmplt{ + uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ + /** + * 0x00: Pairing Success. Pairing with a remote device was successful\n + * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n + * 0x02: Pairing Failed. The pairing failed with the remote device. + */ + uint8_t status; +} PACKED evt_gap_pairing_cmplt; + + +/** + * This event is generated by the Security manager to the application when a pass key is required for pairing. + * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. + * See @ref _evt_gap_pass_key_req. + */ +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +typedef __packed struct _evt_gap_pass_key_req{ + uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ +} PACKED evt_gap_pass_key_req; + + +/** + * This event is generated by the Security manager to the application when the application + * has set that authorization is required for reading/writing of attributes. This event will + * be generated as soon as the pairing is complete. When this event is received, + * aci_gap_authorization_response() command should be used by the application. + * See @ref _evt_gap_author_req. + */ +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +typedef __packed struct _evt_gap_author_req{ + uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ +} PACKED evt_gap_author_req; + +/** + * This event is generated when the slave security request is successfully sent to the master. + * No parameters for this event. + */ +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) + +/** + * This event is generated on the slave when a aci_gap_slave_security_request() is called to reestablish the bond + * with a master but the master has lost the bond. When this event is received, the upper layer has to issue the + * command aci_gap_allow_rebond() in order to allow the slave to continue the pairing process with the master. + * On the master this event is raised when aci_gap_send_pairing_request() is called to reestablish a bond with a slave + * but the slave has lost the bond. In order to create a new bond the master has to launch aci_gap_send_pairing_request() + * with force_rebond set to 1. + * No parameters for this event + */ +#define EVT_BLUE_GAP_BOND_LOST (0X0405) + +/** + * The event is given by the GAP layer to the upper layers when a device is discovered during scanning + * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. + */ +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef __packed struct _evt_gap_device_found{ + uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ + uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ + tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ + uint8_t data_length; /**< Length of advertising or scan response data. */ + uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ +} PACKED evt_gap_device_found; + +/** + * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated + * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. + */ +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef __packed struct _evt_gap_procedure_complete{ + uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ + /** + * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed + * due to authentication requirements). + */ + uint8_t status; + /** + * Procedure specific data.\n + * @li For Name Discovery Procedure:\n + * the name of the peer device if the procedure completed successfully. + * @li For General Connection Establishment Procedure:\n + * The reconnection address written to the peripheral device if the peripheral is privacy enabled + */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_gap_procedure_complete; + +/** + * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral + * is not able to resolve the private address of the peer device after connecting to it. + */ +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) +typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ + uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ +} PACKED evt_gap_addr_not_resolved_IDB05A1; +/** + * This event is raised when the reconnection address is generated during the general connection + * establishment procedure. The same address is set into the peer device also as a part of the general + * connection establishment procedure. In order to make use of the reconnection address the next time + * while connecting to the bonded peripheral, the application needs to use this reconnection address + * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() + * and aci_gap_start_auto_conn_establish_proc(). + */ +#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) +typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ + uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ +} PACKED evt_gap_reconnection_addr_IDB04A1; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1128 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GATT_ACI_H__ +#define __BLUENRG_GATT_ACI_H__ + +#include "bluenrg_gatt_server.h" + +/** + *@addtogroup GATT GATT + *@brief GATT layer. + *@{ + */ + +/** + *@defgroup GATT_Functions GATT functions + *@brief API for GATT layer. + *@{ + */ + +/** + * @brief Initialize the GATT layer for server and client roles. + * @note It adds also the GATT service with Service Changed Characteristic. + * Until this command is issued the GATT channel will not process any commands + * even if the connection is opened. This command has to be given + * before using any of the GAP features. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_init(void); + +/** + * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs + * to reserve the handle ranges for this service using max_attr_records parameter. This + * parameter specifies the maximum number of attribute records that can be added to this + * service (including the service attribute, include attribute, characteristic attribute, + * characteristic value attribute and characteristic descriptor attribute). Handle of the + * created service is returned. + * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors + * are allocated from the attribute pool. + * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field + * @param service_type Primary or secondary service. See @ref Service_type "Service Type". + * @param max_attr_records Maximum number of attribute records that can be added to this service + * (including the service declaration itself) + * @param[out] serviceHandle Handle of the Service. When this service is added to the service, + * a handle is allocated by the server to this service. Server also + * allocates a range of handles for this service from serviceHandle to + * <serviceHandle + max_attr_records>. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, + const uint8_t* service_uuid, + uint8_t service_type, + uint8_t max_attr_records, + uint16_t *serviceHandle); + +/** + * @brief Include a service given by included_start_handle and included_end_handle to another service + * given by service_handle. Attribute server creates an INCLUDE definition attribute and return + * the handle of this attribute in included_handle. + * @param service_handle Handle of the service to which another service has to be included + * @param included_start_handle Start Handle of the service which has to be included in service + * @param included_end_handle End Handle of the service which has to be included in service + * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". + * @param[in] included_uuid 16-bit or 128-bit UUID. + * @param[out] included_handle Handle of the include declaration. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle); + +/** + * @brief Add a characteristic to a service. + * @param serviceHandle Handle of the service to which the characteristic has to be added. + * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param charUuid 16-bit or 128-bit UUID. + * @param charValueLen Maximum length of the characteristic value. + * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, + * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". + * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @arg GATT_DONT_NOTIFY_EVENTS + * @arg GATT_NOTIFY_ATTRIBUTE_WRITE + * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP + * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. + * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client + * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE + * properties. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle); + +/** + * Add a characteristic descriptor to a service. + * @param serviceHandle Handle of the service to which the characteristic belongs + * @param charHandle Handle of the characteristic to which description has to be added. + * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG + * (Well_known_UUIDs) or a user-defined one. + * @param descValueMaxLen The maximum length of the descriptor value + * @param descValueLen Current Length of the characteristic descriptor value + * @param[in] descValue Value of the characteristic description + * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". + * @arg ATTR_NO_ACCESS + * @arg ATTR_ACCESS_READ_ONLY + * @arg ATTR_ACCESS_WRITE_REQ_ONLY + * @arg ATTR_ACCESS_READ_WRITE + * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE + * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param[out] descHandle Handle of the Characteristic Descriptor. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle); + +/** + * @brief Update a characteristic value in a service. + * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. The command is queued into the + * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, + * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or + * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate + * than what is allowed by the link. Throughput on BLE link depends on connection interval and + * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() + * for more info on how to suggest new connection parameters from a slave). If the application does not + * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function + * returns @ref BLE_STATUS_SUCCESS or any other error code.\n + * Example:\n + * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some + * notifications will be lost. + * @code + * tBleStatus Free_Fall_Notify(void) + * { + * uint8_t val; + * tBleStatus ret; + * + * val = 0x01; + * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); + * + * if (ret != BLE_STATUS_SUCCESS){ + * PRINTF("Error while updating FFall characteristic.\n") ; + * return BLE_STATUS_ERROR ; + * } + * return BLE_STATUS_SUCCESS; + * } + * @endcode + * Here if BlueNRG buffer become full, the application try again to send the notification. + * @code + * struct timer t; + * Timer_Set(&t, CLOCK_SECOND*10); + * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ + * // Radio is busy (buffer full). + * if(Timer_Expired(&t)) + * break; + * } + * @endcode + * + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic + * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, + * and the attribute value is of variable length, then the length of the attribute will + * be set to the charValueLen. If the charValOffset is set to a value greater than 0, + * then the length of the attribute will be set to the maximum length as specified for + * the attribute while adding the characteristic. + * @param charValueLen Length of the characteristic value in octets + * @param[in] charValue Characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue); +/** + * @brief Delete the specified characteristic from the service. + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); + +/** + * @brief Delete the specified service from the GATT server database. + * @param servHandle Handle of the service to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_service(uint16_t servHandle); + +/** + * @brief Delete the Include definition from the service. + * @param servHandle Handle of the service to which Include definition belongs + * @param includeServHandle Handle of the Included definition to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); + +/** + * @brief Perform an ATT MTU exchange procedure. + * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP + * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated + * to indicate the end of the procedure. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); + +/** + * @brief Send a @a Find @a Information @a Request. + * @note This command is used to obtain the mapping of attribute handles with their associated + * types. The responses of the procedure are given through the + * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by + * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range of attributes to be discovered on the server + * @param end_handle Ending handle of the range of attributes to be discovered on the server + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send a @a Find @a By @a Type @a Value @a Request + * @note The Find By Type Value Request is used to obtain the handles of attributes that + * have a given 16-bit UUID attribute type and a given attribute value. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid 2 octet UUID to find (little-endian) + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). + * @param attr_val Attribute value to find + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send a @a Read @a By @a Type @a Request + * @note The Read By Type Request is used to obtain the values of attributes where the attribute type + * is known but the handle is not known. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Read @a By @a Group @a Type @a Request + * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute + * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping + * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Prepare @a Write @a Request + * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param attr_handle The handle of the attribute to be written + * @param value_offset The offset of the first octet to be written + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). + * @param attr_val The value of the attribute to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send an @a Execute @a Write @a Request + * @note The Execute Write Request is used to request the server to write or cancel the write of all the + * prepared values currently held in the prepare queue from this client. + * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param execute @arg 0x00 Cancel all prepared writes + * @arg 0x01 Immediately write all pending prepared values. + * @return Value indicating success or error code. + */ +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); + +/** + * @brief This command will start the GATT client procedure to discover all primary services on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +/** + * @brief Start the procedure to discover the primary services of the specified UUID on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to find all included services. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle Start handle of the service + * @param end_handle End handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Start the procedure to discover all the characteristics of a given service. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_attr_handle Start attribute handle of the service + * @param end_attr_handle End attribute handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +/** + * @brief Start the procedure to discover all the characteristics specified by a UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Start attribute handle of the service + * @param end_handle End attribute handle of the service + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); + +/** + * @brief Start the procedure to discover all characteristic descriptors on the server. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. + * @param conn_handle Connection handle for which the command is given. + * @param char_val_handle Starting handle of the characteristic + * @param char_end_handle End handle of the characteristic + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +/** + * @brief Start the procedure to read the attribute value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to read all the characteristics specified by the UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range to be searched + * @param end_handle End handle of the range to be searched + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start a procedure to read multiple characteristic values from a server. + * @note This sub-procedure is used to read multiple Characteristic Values from a server when the + * client knows the Characteristic Value Handles. + * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param num_handles The number of handles for which the value has to be read + * @param set_of_handles The handles for which the attribute value has to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles); + +/** + * @brief Start the procedure to write a characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to write a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start the procedure to write a characteristic reliably. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to write a long characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP + * event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic descriptor + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start the procedure to write a characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to read the descriptor specified. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the descriptor to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to write a characteristic value without waiting for any response from the server. + * @note No events are generated after this command is executed. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 3) + * @param[in] attr_val Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start a signed write without response from the server. + * @note The procedure i used to write a characteristic value with an authentication signature without waiting + * for any response from the server. It cannot be used when the link is encrypted. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 13). + * @param attr_val Value to be written + * @return Value indicating success or error code + */ +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Confirm an indication + * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); + +/** + * @brief Allow or reject a write request from a client. + * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, + * then the status has to be set to 1 and the error code has to be set to the error code that has to be + * passed to the client. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n + * 0x01: The value cannot be written to the attribute specified by the attr_handle. + * @param err_code The error code that has to be passed to the client in case the write has to be rejected. + * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val); + +/** + * @brief Allow the GATT server to send a response to a read request from a client. + * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ + * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response + * can be sent to the client. So if the application wishes to update any of the attributes before + * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value + * and then give this command. The application should perform the required operations within 30 seconds, + * otherwise the GATT procedure will go to timeout. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_allow_read(uint16_t conn_handle); + +/** + * @brief Set the security permission for the attribute handle specified. + * @note Currently the setting of security permission is allowed only for client configuration descriptor. + * @param service_handle Handle of the service which contains the attribute whose security + * permission has to be modified. + * @param attr_handle Handle of the attribute whose security permission has to be modified. + * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission); + +/** + * @brief This command sets the value of the descriptor specified by charDescHandle. + * @param servHandle Handle of the service which contains the descriptor. + * @param charHandle Handle of the characteristic which contains the descriptor. + * @param charDescHandle Handle of the descriptor whose value has to be set. + * @param charDescValOffset Offset from which the descriptor value has to be updated. + * @param charDescValueLen Length of the descriptor value + * @param[in] charDescValue descriptor value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue); + +/** + * @brief Reads the value of the attribute handle specified from the local GATT database. + * @param attr_handle Handle of the attribute to read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + + /** + * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. + * @param attr_handle Handle of the attribute to read + * @param offset Offset from which the value needs to be read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); +/** + * @brief Update the value of a characteristic and sends notifications or indications. + * @note This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute + * up to 512 bytes and indicate selectively the generation of indications and notifications. + * @param service_handle Handle of the service to which the characteristic belongs. + * @param char_handle Handle of the characteristic + * @param update_type Bitmask that controls generation of notifications and indications. It can be a combination + * @arg @ref NOTIFICATION (0x01): send notification, if enabled. + * @arg @ref INDICATION (0x02): send indication, if enabled. + * If set to 0 no notifications or indications are sent. + * @param char_length Total length of the characteristic value. In case of a variable size characteristic, + * this field specifies the new length of the characteristic value after the update; + * in case of fixed length characteristic this field is ignored. + * @param value_offset The offset from which the attribute value has to be updated + * @param value_length Length of the value to be updated + * @param[out] value Updated characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value); + +/** + * @} + */ + + +/** + * @defgroup GATT_Events GATT events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** + * This event (if enabled, see @ref Gatt_Event_Mask "Gatt Event Mask") is raised to the application + * by the GATT server when a client modifies any attribute on the server, as consequence of one of + * the following GATT procedures: + * @li write without response + * @li signed write without response + * @li write characteristic value + * @li write long characteristic value + * @li reliable write. + * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. + */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint16_t offset; /**< Offset from which the write has been performed by the peer device */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB05A1; + +typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB04A1; + +/** + * This event is generated by the client/server to the application on a GATT timeout (30 seconds). + * See @ref _evt_gatt_procedure_timeout. + */ +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +typedef __packed struct _evt_gatt_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ +} PACKED evt_gatt_procedure_timeout; + +/** + * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). + * See @ref _evt_att_exchange_mtu_resp. + */ +#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) +typedef __packed struct _evt_att_exchange_mtu_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data (always 1). */ + uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ +} PACKED evt_att_exchange_mtu_resp; + +/** + * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and + * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. + */ +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef __packed struct _evt_att_find_information_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ + /** + * A sequence of handle-uuid pairs.\n + * @li if format=1, each pair is:\n + * [2 octets for handle, 2 octets for UUIDs] \n + * @li if format=2, each pair is:\n + * [2 octets for handle, 16 octets for UUIDs] + */ + uint8_t handle_uuid_pair[VARIABLE_SIZE]; +} PACKED evt_att_find_information_resp; + +/** + * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See + * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. + */ +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +typedef __packed struct _evt_att_find_by_type_val_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + /** + * Handles Information List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] + */ + uint8_t handles_info_list[VARIABLE_SIZE]; +} PACKED evt_att_find_by_type_val_resp; + +/** + * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and + * aci_gatt_disc_all_charac_of_serv(). + * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. + */ +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef __packed struct _evt_att_read_by_type_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ + /** + * Attribute Data List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] + */ + uint8_t handle_value_pair[VARIABLE_SIZE]; +} PACKED evt_att_read_by_type_resp; + +/** + * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). + * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. + */ +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +typedef __packed struct _evt_att_read_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ +} PACKED evt_att_read_resp; + +/** + * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). + * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. + */ +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +typedef __packed struct _evt_att_read_blob_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ +} PACKED evt_att_read_blob_resp; + +/** + * This event is generated in response to a @a Read @a Multiple @a Request. + * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. + */ +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +typedef __packed struct _evt_att_read_mult_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ +} PACKED evt_att_read_mult_resp; + +/** + * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). + * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. + */ +#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) +typedef __packed struct _evt_att_read_by_group_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_data_length; /**< The size of each Attribute Data. */ + /** + * A list of Attribute Data where the attribute data is composed by: + * @li 2 octets for Attribute Handle + * @li 2 octets for End Group Handle + * @li (attribute_data_length - 4) octets for Attribute Value + */ + uint8_t attribute_data_list[VARIABLE_SIZE]; +} PACKED evt_att_read_by_group_resp; + +/** + * This event is generated in response to a @a Prepare @a Write @a Request. + * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. + */ +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +typedef __packed struct _evt_att_prepare_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attribute_handle; /**< The handle of the attribute to be written. */ + uint16_t offset; /**< The offset of the first octet to be written. */ + uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ +} PACKED evt_att_prepare_write_resp; + +/** + * This event is generated in response to an @a Execute @a Write @a Request. + * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. + */ +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +typedef __packed struct _evt_att_exec_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Always 0. */ +} PACKED evt_att_exec_write_resp; + +/** + * This event is generated when an indication is received from the server. + * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. + */ +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +typedef __packed struct _evt_gatt_indication{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_indication; + +/** + * This event is generated when a notification is received from the server. + * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. + */ +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef __packed struct _evt_gatt_notification{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_attr_notification; + +/** + * This event is generated when a GATT client procedure completes either with error or successfully. + * See @ref _evt_gatt_procedure_complete. + */ +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef __packed struct _evt_gatt_procedure_complete{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ + uint8_t data_length; /**< Length of error_code field (always 1). */ + /** + * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). + */ + uint8_t error_code; +} PACKED evt_gatt_procedure_complete; + +/** + * This event is generated when an Error Response is received from the server. The error response can be given + * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended + * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. + */ +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +typedef __packed struct _evt_gatt_error_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t req_opcode; /**< The request that generated this error response. */ + uint16_t attr_handle; /**< The attribute handle that generated this error response. */ + uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ +} PACKED evt_gatt_error_resp; + +/** + * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using + * Characteristic UUID" procedure. + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. + */ +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + /** + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. + */ + uint8_t attr_value[VARIABLE_SIZE]; +} PACKED evt_gatt_disc_read_char_by_uuid_resp; + +/** + * This event is given to the application when a write request, write command or signed write command + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * If the write is rejected by the application, then the value of the attribute will not be modified. + * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. + * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef __packed struct _evt_gatt_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_write_permit_req; + +/** + * This event is given to the application when a read request or read blob request is received by the server + * from the client. This event will be given to the application only if the event bit for this event generation + * is set when the characteristic was added. + * On receiving this event, the application can update the value of the handle if it desires and when done + * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef __packed struct _evt_gatt_read_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ + uint8_t data_length; /**< Length of offset field. */ + uint16_t offset; /**< Contains the offset from which the read has been requested */ +} PACKED evt_gatt_read_permit_req; + +/** + * This event is given to the application when a read multiple request or read by type request is received + * by the server from the client. This event will be given to the application only if the event bit for this + * event generation is set when the characteristic was added. + * On receiving this event, the application can update the values of the handles if it desires and when done + * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_multi_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) +typedef __packed struct _evt_gatt_read_multi_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ +} PACKED evt_gatt_read_multi_permit_req; + +/** + * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2). + * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES. + * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value(). + * See @ref evt_gatt_tx_pool_vailable. + * + */ +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE (0x0C16) +typedef __packed struct _evt_gatt_tx_pool_available{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t available_buffers; /**< Length of data field. */ +} PACKED evt_gatt_tx_pool_available; + +/** + * This event is raised on the server when the client confirms the reception of an indication. + */ +#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT (0x0C17) +typedef __packed struct _evt_gatt_server_confirmation{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ +} PACKED evt_gatt_server_confirmation; +/** + * This event is given to the application when a prepare write request + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * Based on the response from the application, the attribute value will be modified by the stack. + * If the write is rejected by the application, then the value of the attribute will not be modified + * and an error response will be sent to the client, with the error code as specified by the application. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ (0x0C18) +typedef __packed struct _evt_gatt_prepare_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint16_t offset; /**< The offset from which the prepare write has been requested */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_prepare_write_permit_req; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,229 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gatt_server.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GATT server layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BNRG_GATT_SERVER_H__ +#define __BNRG_GATT_SERVER_H__ + +#include "ble_compiler.h" +#include "ble_status.h" + +/** + *@addtogroup GATT GATT + *@{ + */ + +/** + * @anchor Well-Known_UUIDs + * @name Well-Known UUIDs + * @{ + */ +#define PRIMARY_SERVICE_UUID (0x2800) +#define SECONDARY_SERVICE_UUID (0x2801) +#define INCLUDE_SERVICE_UUID (0x2802) +#define CHARACTERISTIC_UUID (0x2803) +#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) +#define CHAR_USER_DESC_UUID (0x2901) +#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) +#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) +#define CHAR_FORMAT_DESC_UUID (0x2904) +#define CHAR_AGGR_FMT_DESC_UUID (0x2905) +#define GATT_SERVICE_UUID (0x1801) +#define GAP_SERVICE_UUID (0x1800) +#define SERVICE_CHANGED_UUID (0x2A05) +/** + * @} + */ + +/** + * @anchor Access_permissions + * @name Access permissions + * Access permissions for an attribute + * @{ + */ +#define ATTR_NO_ACCESS (0x00) +#define ATTR_ACCESS_READ_ONLY (0x01) +#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) +#define ATTR_ACCESS_READ_WRITE (0x03) +#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) +#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) +/** + * Allows all write procedures + */ +#define ATTR_ACCESS_WRITE_ANY (0x0E) +/** + * @} + */ + +/** + * @anchor Char_properties + * @name Characteristic properties. + * @{ + */ +#define CHAR_PROP_BROADCAST (0x01) +#define CHAR_PROP_READ (0x02) +#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) +#define CHAR_PROP_WRITE (0x08) +#define CHAR_PROP_NOTIFY (0x10) +#define CHAR_PROP_INDICATE (0x20) +#define CHAR_PROP_SIGNED_WRITE (0x40) +#define CHAR_PROP_EXT (0x80) +/** + * @} + */ + + +/** + * @anchor Security_permissions + * @name Security permissions for an attribute. + * @{ + */ +#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ +#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ +#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ +#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ +/** + * @} + */ + +/** + * @anchor UUID_Types + * @name Type of UUID (16 bit or 128 bit). + * @{ + */ +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) +/** + * @} + */ + +/** + * @anchor Service_type + * @name Type of service (primary or secondary) + * @{ + */ +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) +/** + * @} + */ + +/** + * @anchor Gatt_Event_Mask + * @name Gatt Event Mask + * Type of event generated by GATT server + * @{ + */ +#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ +#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. + An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ +#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd + or a signed write cmd are received by the server for this attribute. + An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ +#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is + received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ +/** + * @} + */ + +/** + * @name Type of characteristic length + * See aci_gatt_add_char() + * @{ + */ +#define CHAR_VALUE_LEN_CONSTANT (0x00) +#define CHAR_VALUE_LEN_VARIABLE (0x01) +/** + * @} + */ + + +/** + * @name Encryption key size + * @{ + */ +/** + * Minimum encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Maximum encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) +/** + * @} + */ + +/** + * @name Characteristic Presentation Format + * @{ + */ +typedef __packed struct _charactFormat { + uint8_t format; + int8_t exp; + uint16_t unit; + uint8_t name_space; + uint16_t desc; +} PACKED charactFormat; + +/** + * @} + */ + +/** + * @name Format + * @{ + */ +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F +/** + * @} + */ + +/** + * @name Unit + * @{ + */ +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 +/** + * @} + */ + + +/** + * ATT MTU size + */ +#define ATT_MTU (23) + +/** + * @} + */ + + /** + * @name Update type of aci_gatt_upd_char_val_ext(). + * @{ + */ + +#define NOTIFICATION 1 +#define INDICATION 2 + +#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,385 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hal_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with HCI commands for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_HAL_ACI_H__ +#define __BLUENRG_HAL_ACI_H__ + +/** + *@addtogroup HAL HAL + *@brief Hardware Abstraction Layer. + *@{ + */ + +/** + * @defgroup HAL_Functions HAL functions + * @brief API for BlueNRG HAL layer. + * @{ + */ + +/** + * @brief This command retrieves the buid number of the firmware. + * @param[out] build_number Build number identifying the firmware release. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number); + +/** + * @brief This command writes a value to a low level configure data structure. + * @note It is useful to setup directly some low level parameters for the system at runtime. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * + * @param len Length of data to be written + * @param[out] val Data to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val); + +/** + * @brief This command requests the value in the low level configure data structure. + * The number of read bytes changes for different Offset. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * @param data_len Length of the data buffer + * @param[out] data_len_out_p length of the data returned by the read. + * @param[out] data Read data + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data); + +/** + * @brief This command sets the TX power level of the BlueNRG. + * @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines + * the output power level (dBm). + * When the system starts up or reboots, the default TX power level will be used, which is + * the maximum value of 8dBm. Once this command is given, the output power will be changed + * instantly, regardless if there is Bluetooth communication going on or not. For example, + * for debugging purpose, the BlueNRG can be set to advertise all the time and use this + * command to observe the signal strength changing. The system will keep the last received + * TX power level from the command, i.e. the 2nd command overwrites the previous TX power + * level. The new TX power level remains until another Set TX Power command, or the system + * reboots.\n + * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the + * right value, depending on the selected hardware configuration for the RF network: + * normal mode or high power mode. + * @param pa_level Can be from 0 to 7. Set the PA level value. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +/** + * @brief This command returns the number of packets sent in Direct Test Mode. + * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets + * have been transmitted. This command can be used to check how many packets have been sent + * during the Direct TX test.\n + * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again. + * The counter is not cleared until the next Direct TX test starts. + * @param[out] number_of_packets Number of packets sent during the last Direct TX test. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets); + +/** + * @brief Put the device in standby mode. + * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the + * device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode, + * the device can still wake up itself with the internal timer. But in standby mode, this timer is + * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command + * sent via SPI bus. + * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code + * ERR_COMMAND_DISALLOWED will be returned. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_device_standby(void); + +/** + * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. + * @note The frequency sine wave at the specific channel may be used for test purpose only. + * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. + * This command shouldn't be used when normal Bluetooth activities are ongoing. + * The tone should be stopped by aci_hal_tone_stop() command. + * + * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the + * channel central frequency minus 250 kHz. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +/** + * This command is used to stop the previously started aci_hal_tone_start() command. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_stop(void); + +/** + * @brief This command returns the status of all the connections. + * @note This command returns the status of the 8 Bluetooth low energy links managed by the device. + * @param[out] link_status Array of link status (8 links). See @ref Link_Status. + * @param[out] conn_handle Array of connection handles for each link. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]); + +/** + * @brief This command returns the anchor period and the largest available slot. + * @note This command returns information about the anchor period to help application in selecting + * slot timings when operating in multi-link scenarios. + * @param anchor_period Current anchor period (multiple of 0.625 ms). + * @param max_free_slot Maximum available time (multiple of 0.625 ms) that can be allocated for a new slot. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot); + +/** + * @} + */ + +/** + * @defgroup HAL_Events HAL events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_HAL_INITIALIZED (0x0001) +typedef __packed struct _evt_hal_initialized{ + uint8_t reason_code; /**< Reset reason. See @ref Reset_Reasons */ +} PACKED evt_hal_initialized; + +/** + * This event is generated when an overflow occurs in the event queue read by the external microcontroller. + * This is normally caused when the external microcontroller does not read pending events. + * The returned bitmap indicates which event has been lost. Please note that one bit set to 1 indicates one or + * more occurrences of the particular events. The event EVT_BLUE_HAL_EVENTS_LOST cannot be lost and it will + * be inserted in the event queue as soon as a position is freed in the event queue. This event should not + * happen under normal operating condition where external microcontroller promptly reads events signaled by + * IRQ pin. It is provided to detected unexpected behavior of the external microcontroller or to allow + * application to recover situations where critical events are lost. + */ +#define EVT_BLUE_HAL_EVENTS_LOST_IDB05A1 (0x0002) +typedef __packed struct _evt_hal_events_lost{ + uint8_t lost_events[8]; /**< Bitmap of lost events. Each bit indicates one or more occurrences of the specific event. See @ref Lost_Events */ +} PACKED evt_hal_events_lost_IDB05A1; + + +/** + * This event is given to the application after the @ref ACI_BLUE_INITIALIZED_EVENT + * when a system crash is detected. This events returns system crash information for debugging purposes. + * Information reported are useful to understand the root cause of the crash. + */ +#define EVT_BLUE_HAL_CRASH_INFO_IDB05A1 (0x0003) +typedef __packed struct _evt_hal_crash_info{ + uint8_t crash_type; /**< Type of crash: Assert failed (0), NMI Fault (1), Hard Fault (2) */ + uint32_t sp; /**< SP register */ + uint32_t r0; /**< R0 register */ + uint32_t r1; /**< R1 register */ + uint32_t r2; /**< R2 register */ + uint32_t r3; /**< R3 register */ + uint32_t r12; /**< R12 register */ + uint32_t lr; /**< LR register */ + uint32_t pc; /**< PC register */ + uint32_t xpsr; /**< xPSR register */ + uint8_t debug_data_len; /**< length of debug_data field */ + uint8_t debug_data[VARIABLE_SIZE]; /**< Debug data */ +} PACKED evt_hal_crash_info_IDB05A1; + + +/** + * @} + */ + + +/** + * @anchor Reset_Reasons + * @name Reset Reasons + * See @ref EVT_BLUE_HAL_INITIALIZED. + * @{ + */ +#define RESET_NORMAL 1 /**< Normal startup. */ +#define RESET_UPDATER_ACI 2 /**< Updater mode entered with ACI command */ +#define RESET_UPDATER_BAD_FLAG 3 /**< Updater mode entered due to a bad BLUE flag */ +#define RESET_UPDATER_PIN 4 /**< Updater mode entered with IRQ pin */ +#define RESET_WATCHDOG 5 /**< Reset caused by watchdog */ +#define RESET_LOCKUP 6 /**< Reset due to lockup */ +#define RESET_BROWNOUT 7 /**< Brownout reset */ +#define RESET_CRASH 8 /**< Reset caused by a crash (NMI or Hard Fault) */ +#define RESET_ECC_ERR 9 /**< Reset caused by an ECC error */ +/** + * @} + */ + + +/** + * @defgroup Config_vals Offsets and lengths for configuration values. + * @brief Offsets and lengths for configuration values. + * See aci_hal_write_config_data(). + * @{ + */ + +/** + * @name Configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ +#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ +#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ +#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ +#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. + It can be written only if aci_hal_write_config_data() is the first command after reset. */ +#define CONFIG_DATA_RANDOM_ADDRESS (0x80) /**< Stored static random address. Read-only. */ + +/** + * Select the BlueNRG mode configurations.\n + * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) + * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) + * @li Mode 3: master/slave, 8 connections, RAM1 and RAM2. + * @li Mode 4: master/slave, 4 connections, RAM1 and RAM2 simultaneous scanning and advertising. + */ +#define CONFIG_DATA_MODE_OFFSET (0x2D) + +#define CONFIG_DATA_WATCHDOG_DISABLE (0x2F) /**< Set to 1 to disable watchdog. It is enabled by default. */ +/** + * @} + */ + +/** + * @name Length for configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_LEN (6) +#define CONFIG_DATA_DIV_LEN (2) +#define CONFIG_DATA_ER_LEN (16) +#define CONFIG_DATA_IR_LEN (16) +#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) +#define CONFIG_DATA_MODE_LEN (1) +#define CONFIG_DATA_WATCHDOG_DISABLE_LEN (1) +/** + * @} + */ + +/** + * @anchor Link_Status + * @name Status of the link + * See @ref aci_hal_get_link_status(). + * @{ + */ +#define STATUS_IDLE 0 +#define STATUS_ADVERTISING 1 +#define STATUS_CONNECTED_AS_SLAVE 2 +#define STATUS_SCANNING 3 +#define STATUS_CONNECTED_AS_MASTER 5 +#define STATUS_TX_TEST 6 +#define STATUS_RX_TEST 7 +/** + * @} + */ + +/** + * @} + */ + + /** + * @anchor Lost_Events + * @name Lost events bitmap + * See @ref EVT_BLUE_HAL_EVENTS_LOST. + * @{ + */ +#define EVT_DISCONN_COMPLETE_BIT 0 +#define EVT_ENCRYPT_CHANGE_BIT 1 +#define EVT_READ_REMOTE_VERSION_COMPLETE_BIT 2 +#define EVT_CMD_COMPLETE_BIT 3 +#define EVT_CMD_STATUS_BIT 4 +#define EVT_HARDWARE_ERROR_BIT 5 +#define EVT_NUM_COMP_PKTS_BIT 6 +#define EVT_ENCRYPTION_KEY_REFRESH_BIT 7 +#define EVT_BLUE_HAL_INITIALIZED_BIT 8 +#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE_BIT 9 +#define EVT_BLUE_GAP_PAIRING_CMPLT_BIT 10 +#define EVT_BLUE_GAP_PASS_KEY_REQUEST_BIT 11 +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST_BIT 12 +#define EVT_BLUE_GAP_SECURITY_REQ_INITIATED_BIT 13 +#define EVT_BLUE_GAP_BOND_LOST_BIT 14 +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE_BIT 15 +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_BIT 16 +#define EVT_BLUE_L2CAP_CONN_UPDATE_RESP_BIT 17 +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT_BIT 18 +#define EVT_BLUE_L2CAP_CONN_UPDATE_REQ_BIT 19 +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_BIT 20 +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT_BIT 21 +#define EVT_BLUE_EXCHANGE_MTU_RESP_BIT 22 +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP_BIT 23 +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP_BIT 24 +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP_BIT 25 +#define EVT_BLUE_ATT_READ_RESP_BIT 26 +#define EVT_BLUE_ATT_READ_BLOB_RESP_BIT 27 +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP_BIT 28 +#define EVT_BLUE_ATT_READ_BY_GROUP_RESP_BIT 29 +#define EVT_BLUE_ATT_WRITE_RESP_BIT 30 +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP_BIT 31 +#define EVT_BLUE_ATT_EXEC_WRITE_RESP_BIT 32 +#define EVT_BLUE_GATT_INDICATION_BIT 33 +#define EVT_BLUE_GATT_NOTIFICATION_BIT 34 +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE_BIT 35 +#define EVT_BLUE_GATT_ERROR_RESP_BIT 36 +#define EVT_BLUE_GATT_DISC_READ_CHARAC_BY_UUID_RESP_BIT 37 +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ_BIT 38 +#define EVT_BLUE_GATT_READ_PERMIT_REQ_BIT 39 +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ_BIT 40 +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_BIT 41 +#define EVT_BLUE_GATT_SERVER_RX_CONFIRMATION_BIT 42 +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ_BIT 43 +#define EVT_LL_CONNECTION_COMPLETE_BIT 44 +#define EVT_LL_ADVERTISING_REPORT_BIT 45 +#define EVT_LL_CONNECTION_UPDATE_COMPLETE_BIT 46 +#define EVT_LL_READ_REMOTE_USED_FEATURES_BIT 47 +#define EVT_LL_LTK_REQUEST_BIT 48 +/** + * @} + */ + +/** + * @name Hardware error event codes + * See @ref EVT_HARDWARE_ERROR. + * @{ + */ +/** + * Error on the SPI bus has been detected, most likely caused by incorrect SPI configuration on the external micro-controller. + */ +#define SPI_FRAMING_ERROR 0 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define RADIO_STATE_ERROR 1 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define TIMER_OVERRUN_ERROR 2 + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,166 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_l2cap_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with L2CAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_L2CAP_ACI_H__ +#define __BLUENRG_L2CAP_ACI_H__ + +/** + *@addtogroup L2CAP L2CAP + *@brief L2CAP layer. + *@{ + */ + +/** + *@defgroup L2CAP_Functions L2CAP functions + *@brief API for L2CAP layer. + *@{ + */ + +/** + * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. + * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request + * (accepts or rejects). + * @param conn_handle Connection handle on which the connection parameter update request has to be sent. + * @param interval_min Defines minimum value for the connection event interval in the following manner: + * connIntervalMin = interval_min x 1.25ms + * @param interval_max Defines maximum value for the connection event interval in the following manner: + * connIntervalMax = interval_max x 1.25ms + * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). + * @param timeout_multiplier Defines connection timeout parameter in the following manner: + * timeout_multiplier x 10ms. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier); +/** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param min_ce_length Minimum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_ce_length Maximum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept); + /** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept); + +/** + * @} + */ + +/** + * @defgroup L2CAP_Events L2CAP events + * @{ + */ + +/** + * This event is generated when the master responds to the L2CAP connection update request packet. + * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. + */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef __packed struct _evt_l2cap_conn_upd_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ +/** + * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. + * @li 0x01 in case of Command Reject. + */ + uint8_t code; + uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ + uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ +/** + * Result code (parameters accepted or rejected) in case of Connection Parameter Update + * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). + */ + uint16_t result; +} PACKED evt_l2cap_conn_upd_resp; + +/** + * This event is generated when the master does not respond to the connection update request + * within 30 seconds. + */ +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) +typedef __packed struct _evt_l2cap_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */ +} PACKED evt_l2cap_procedure_timeout; + +/** + * The event is given by the L2CAP layer when a connection update request is received from the slave. + * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). + */ +#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) +typedef __packed struct _evt_l2cap_conn_upd_req{ +/** + * Handle of the connection for which the connection update request has been received. + * The same handle has to be returned while responding to the event with the command + * aci_l2cap_connection_parameter_update_response(). + */ + uint16_t conn_handle; + uint8_t event_data_length; /**< Length of following data. */ +/** + * This is the identifier which associates the request to the + * response. The same identifier has to be returned by the upper + * layer in the command aci_l2cap_connection_parameter_update_response(). + */ + uint8_t identifier; + uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ + uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ +} PACKED evt_l2cap_conn_upd_req; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_updater_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with updater commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_UPDATER_ACI_H__ +#define __BLUENRG_UPDATER_ACI_H__ + +#include <ble_compiler.h> + +/** + * @defgroup Updater Updater + * @brief Updater. + * @{ + */ + +/** + * @defgroup Updater_Functions Updater functions + * @brief API for BlueNRG Updater. + * @{ + */ + +tBleStatus aci_updater_start(void); + +tBleStatus aci_updater_reboot(void); + +tBleStatus aci_get_updater_version(uint8_t *version); + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); + +tBleStatus aci_erase_blue_flag(void); + +tBleStatus aci_reset_blue_flag(void); + +tBleStatus aci_updater_erase_sector(uint32_t address); + +tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); + +tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); + +tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); + +tBleStatus aci_updater_hw_version(uint8_t *version); + +/** + * @} + */ + +/** + * @defgroup Updater_Events Updater events + * @{ + */ +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_INITIALIZED (0x0001) +typedef __packed struct _evt_blue_initialized{ + uint8_t reason_code; +} PACKED evt_blue_initialized; +/** + * @} + */ + +/** + * @} + */ + + + +#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,204 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_utils.h +* Author : AMS - VMA, RF Application Team +* Version : V1.0.1 +* Date : 03-October-2014 +* Description : Header file for BlueNRG utility functions +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + * @file bluenrg_utils.h + * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description + * + * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> +**/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLUENRG_UTILS_H +#define __BLUENRG_UTILS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ble_hal_types.h" +#include "ble_compiler.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct{ + uint8_t stack_mode; + uint8_t day; + uint8_t month; + uint8_t year; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint16_t hs_startup_time; /* In system time units*/ +} IFR_config2_TypeDef; + +/** + * Structure inside IFR for configuration options. + */ +typedef __packed struct{ + uint8_t cold_ana_act_config_table[64]; + uint8_t hot_ana_config_table[64]; + uint8_t stack_mode; + uint8_t gpio_config; + uint8_t rsrvd1[2]; + uint32_t rsrvd2[3]; + uint32_t max_conn_event_time; + uint32_t ls_crystal_period; + uint32_t ls_crystal_freq; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint8_t rsrvd3; + uint16_t hs_startup_time; /* In system time units*/ + uint8_t rsrvd4[2]; + uint32_t uid; + uint8_t rsrvd5; + uint8_t year; + uint8_t month; + uint8_t day; + uint32_t unused[5]; +} PACKED IFR_config_TypeDef; + +/* Exported constants --------------------------------------------------------*/ +extern const IFR_config_TypeDef IFR_config; + +/* Exported macros -----------------------------------------------------------*/ +#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)+1) +#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) + +/* Convert 2 digit BCD number to an integer */ +#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) + +/* Convert 2 digit number to a BCD number */ +#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) + +/** + * Return values + */ +#define BLE_UTIL_SUCCESS 0 +#define BLE_UTIL_UNSUPPORTED_VERSION 1 +#define BLE_UTIL_WRONG_IMAGE_SIZE 2 +#define BLE_UTIL_ACI_ERROR 3 +#define BLE_UTIL_CRC_ERROR 4 +#define BLE_UTIL_PARSE_ERROR 5 +#define BLE_UTIL_WRONG_VERIFY 6 + +/* Exported functions ------------------------------------------------------- */ +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int program_device(const uint8_t *fw_image, uint32_t fw_size); + +/** + * @brief Read raw data from IFR (3 64-bytes blocks). + * @param data Pointer to the buffer that will contain the read data. + * Its size must be 192 bytes. This data can be parsed by + * parse_IFR_data_config(). + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION) + */ +int read_IFR(uint8_t data[192]); + +/** + * @brief Verify raw data from IFR (3 64-bytes blocks). + * @param ifr_data Pointer to the buffer that will contain the data to verify. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) + */ +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); + +/** + * @brief Program raw data to IFR (3 64-bytes blocks). + * @param ifr_image Pointer to the buffer that will contain the data to program. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful + */ +int program_IFR(const IFR_config_TypeDef *ifr_image); + +/** + * @brief Parse IFR raw data. + * @param data Pointer to the raw data: last 64 bytes read from IFR sector. + * @param IFR_config Data structure that will be filled with parsed data. + * @retval None + */ +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); + +/** + * @brief Check for the correctness of parsed data. + * @param IFR_config Data structure filled with parsed data. + * @retval int It returns 0 if successful, or PARSE_ERROR in case data is + * not correct. + */ +int IFR_validate(IFR_config2_TypeDef *IFR_config); + +/** + * @brief Modify IFR data. (Last 64-bytes block). + * @param IFR_config Structure that contains the new parameters inside the + * IFR configuration data. + * @note It is highly recommended to parse the IFR configuration from + * a working IFR block (this should be done with parse_IFR_data_config()). + * Then it is possible to write the new parameters inside the IFR_config + * structure. + * @param data Pointer to the buffer that contains the original data. It + * will be modified according to the new data in the IFR_config + * structure. Then this data must be written in the last + * 64-byte block in the IFR. + * Its size must be 64 bytes. + * @retval None + */ +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); + +/** + * @brief Get BlueNRG hardware and firmware version + * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). + * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN + * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. + * @retval Status of the call + */ +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); + +/** + * @brief Get BlueNRG updater version + * @param version This parameter returns the updater version. If the updadter version is 0x03 + * the chip has the updater old, needs to update the bootloader. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterVersion(uint8_t *version); + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version); + +/** + * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on + * the HW bootloader related to the 32 MHz external crystal oscillator. + * @retval TRUE if the HW bootloader is already patched, FALSE otherwise + */ +uint8_t isHWBootloader_Patched(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__BLUENRG_UTILS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file bluenrg_targets.h + * @author AST / EST + * @version V0.0.1 + * @date 24-July-2015 + * @brief This header file is intended to manage the differences between + * the different supported base-boards which might mount the + * X_NUCLEO_IDB0XA1 BlueNRG BLE Expansion Board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent from recursive inclusion --------------------------------*/ +#ifndef _BLUENRG_TARGETS_H_ +#define _BLUENRG_TARGETS_H_ + +#if !defined(BLUENRG_PIN_SPI_MOSI) +#define BLUENRG_PIN_SPI_MOSI (D11) +#endif +#if !defined(BLUENRG_PIN_SPI_MISO) +#define BLUENRG_PIN_SPI_MISO (D12) +#endif +#if !defined(BLUENRG_PIN_SPI_nCS) +#define BLUENRG_PIN_SPI_nCS (A1) +#endif +#if !defined(BLUENRG_PIN_SPI_RESET) +#define BLUENRG_PIN_SPI_RESET (D7) +#endif +#if !defined(BLUENRG_PIN_SPI_IRQ) +#define BLUENRG_PIN_SPI_IRQ (A0) +#endif + +/* NOTE: Refer to README for further details regarding BLUENRG_PIN_SPI_SCK */ +#if !defined(BLUENRG_PIN_SPI_SCK) +#define BLUENRG_PIN_SPI_SCK (D3) +#endif + +/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv) + * Mode 0x01: slave or master, 1 connection + * Mode 0x02: slave or master, 1 connection + * Mode 0x03: master/slave, 8 connections + * Mode 0x04: master/slave, 4 connections (simultaneous scanning and advertising) + * Check Table 285 of + * BlueNRG-MS Bluetooth LE stack application command interface (ACI) User Manual (UM1865) at st.com + */ +#if !defined(BLUENRG_STACK_MODE) +#define BLUENRG_STACK_MODE (0x04) +#endif + +#endif // _BLUENRG_TARGTES_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef _BTLE_H_ +#define _BTLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "bluenrg_aci.h" +#include "ble_hci_const.h" +#include "bluenrg_hal_aci.h" +#include "stm32_bluenrg_ble.h" +#include "bluenrg_gap.h" +#include "bluenrg_gatt_server.h" + +extern uint16_t g_gap_service_handle; +extern uint16_t g_appearance_char_handle; +extern uint16_t g_device_name_char_handle; +extern uint16_t g_preferred_connection_parameters_char_handle; + +void btleInit(void); +void SPI_Poll(void); +void User_Process(void); +void setConnectable(void); +void setVersionString(uint8_t hwVersion, uint16_t fwVersion); +const char* getVersionString(void); +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type); + + +extern int btle_handler_pending; +extern void btle_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.h + * @author CL + * @version V1.0.1 + * @date 15-June-2014 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_BLUENRG_BLE_H +#define __STM32_BLUENRG_BLE_H + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdint.h> +#include "ble_gp_timer.h" +#include "ble_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup X-NUCLEO-IDB04A1 + * @{ + */ + +/** @addtogroup STM32_BLUENRG_BLE + * @{ + */ + +/** @defgroup STM32_BLUENRG_BLE_Exported_Functions + * @{ + */ + +// FIXME: add prototypes for BlueNRG here +void BlueNRG_RST(void); +uint8_t BlueNRG_DataPresent(void); +void BlueNRG_HW_Bootloader(void); +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size); +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, + uint8_t Nb_bytes1, + uint8_t Nb_bytes2); +void Clear_SPI_EXTI_Flag(void); + +void print_csv_time(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_BLUENRG_BLE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_debug.h" + +#ifndef __PAYLOAD_H__ +#define __PAYLOAD_H__ + +class UnitPayload +{ +public: + uint8_t length; + uint8_t id; + uint8_t *data; + uint8_t *idptr; + + + + void set_length(uint8_t l) { + length=l; + } + + void set_id(uint8_t i) { + id=i; + } + + void set_data(uint8_t* data1) { + for(int j=0;j<length;j++) + { + data[j]=data1[j]; + } + } + + uint8_t get_length() { + return length; + } + + uint8_t get_id() { + return id; + } + + uint8_t* get_data() { + return data; + } + +}; + +class Payload { + UnitPayload *payload; + int stringLength; + int payloadUnitCount; + +public: + Payload(const uint8_t *tokenString, uint8_t string_ength); + Payload(); + ~Payload(); + uint8_t getPayloadUnitCount(); + + uint8_t getIDAtIndex(int index); + uint8_t getLengthAtIndex(int index); + uint8_t* getDataAtIndex(int index); + int8_t getInt8AtIndex(int index); + uint16_t getUint16AtIndex(int index); + uint8_t* getSerializedAdDataAtIndex(int index); +}; + + +class PayloadUnit { +private: + uint8_t* lenPtr; + uint8_t* adTypePtr; + uint8_t* dataPtr; + +public: + PayloadUnit() { + lenPtr = NULL; + adTypePtr = NULL; + dataPtr = NULL; + } + + PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { + lenPtr = len; + adTypePtr = adType; + dataPtr = data; + } + + void setLenPtr(uint8_t *len) { + lenPtr = len; + } + + void setAdTypePtr(uint8_t *adType) { + adTypePtr = adType; + } + + void setDataPtr(uint8_t *data) { + dataPtr = data; + } + + uint8_t* getLenPtr() { + return lenPtr; + } + + uint8_t* getAdTypePtr() { + return adTypePtr; + } + + uint8_t* getDataPtr() { + return dataPtr; + } + + void printDataAsHex() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("0x%x ", dataPtr[i]); + } + PRINTF("\n"); + } + + void printDataAsString() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("%c", dataPtr[i]); + } + PRINTF("\n"); + } + +}; + +class PayloadPtr { +private: + PayloadUnit *unit; + int payloadUnitCount; +public: + PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + int stringLength = string_ength; + payloadUnitCount = 0; + + int index = 0; + while(index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + // allocate memory to unit + unit = new PayloadUnit[payloadUnitCount]; + int i = 0; + int nextUnitOffset = 0; + + while(i<payloadUnitCount) { + unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); + unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); + unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); + + nextUnitOffset += *unit[i].getLenPtr()+1; + i++; + + } + } + + PayloadUnit getUnitAtIndex(int index) { + return unit[index]; + } + + int getPayloadUnitCount() { return payloadUnitCount; } + + ~PayloadPtr() { + if(unit) delete[] unit; + + unit = NULL; + } +}; + +#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include "ble_status.h" +#include "ble_hal_types.h" + +#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do {\ + uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ + }while(0) + + +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); + +#endif // __UTIL_H__ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/mbed_lib.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "bluenrg", + "target_overrides": { + "K64F": { + "target.macros_add": ["BLUENRG_PIN_SPI_SCK=D13"] + }, + "DISCO_L475VG_IOT01A": { + "target.macros_add": ["BLUENRG_PIN_SPI_MOSI=PC_12", + "BLUENRG_PIN_SPI_MISO=PC_11", + "BLUENRG_PIN_SPI_nCS=PD_13", + "BLUENRG_PIN_SPI_RESET=PA_8", + "BLUENRG_PIN_SPI_IRQ=PE_6", + "BLUENRG_PIN_SPI_SCK=PC_10"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,37 @@ +{ + "name": "x-nucleo-idb0xa1", + "version": "2.2.0", + "description": "ST driver for the mbed BLE API.", + "keywords": [ + "expansion", + "board", + "x-nucleo", + "nucleo", + "ST", + "STM", + "Bluetooth", + "BLE" + ], + "author": "Andrea Palmieri", + "repository": { + "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git", + "type": "git" + }, + "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "extraIncludes": [ + "x-nucleo-idb0xa1", + "x-nucleo-idb0xa1/utils", + "x-nucleo-idb0xa1/platform", + "x-nucleo-idb0xa1/bluenrg-hci" + ], + "dependencies": { + "mbed-drivers": ">=0.11.3", + "ble": "^2.7.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,474 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.cpp + * @author STMicroelectronics + * @brief Implementation of BLEDeviceInstanceBase + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGDevice + * @brief BlueNRG BLE_API Device Adaptation + * @{ + */ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGDevice.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" + +#include "btle.h" +#include "ble_utils.h" +#include "ble_osal.h" + +#include "ble_debug.h" +#include "stm32_bluenrg_ble.h" + +extern "C" { + #include "ble_hci.h" + #include "bluenrg_utils.h" +} + +#define HEADER_SIZE 5 +#define MAX_BUFFER_SIZE 255 + +/** + * The singleton which represents the BlueNRG transport for the BLEDevice. + * + * See file 'bluenrg_targets.h' for details regarding the peripheral pins used! + */ +#include "bluenrg_targets.h" + +BlueNRGDevice bluenrgDeviceInstance(BLUENRG_PIN_SPI_MOSI, + BLUENRG_PIN_SPI_MISO, + BLUENRG_PIN_SPI_SCK, + BLUENRG_PIN_SPI_nCS, + BLUENRG_PIN_SPI_RESET, + BLUENRG_PIN_SPI_IRQ); + +/** +* BLE-API requires an implementation of the following function in order to +* obtain its transport handle. +*/ +BLEInstanceBase * +createBLEInstance(void) +{ + return (&bluenrgDeviceInstance); +} + +/**************************************************************************/ +/** + @brief Constructor + * @param mosi mbed pin to use for MOSI line of SPI interface + * @param miso mbed pin to use for MISO line of SPI interface + * @param sck mbed pin to use for SCK line of SPI interface + * @param cs mbed pin to use for not chip select line of SPI interface + * @param rst mbed pin to use for BlueNRG reset + * @param irq mbed pin for BlueNRG IRQ +*/ +/**************************************************************************/ +BlueNRGDevice::BlueNRGDevice(PinName mosi, + PinName miso, + PinName sck, + PinName cs, + PinName rst, + PinName irq) : + isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq) +{ + // Setup the spi for 8 bit data, low clock polarity, + // 1-edge phase, with an 8MHz clock rate + spi_.format(8, 0); + spi_.frequency(8000000); + + // Deselect the BlueNRG chip by keeping its nCS signal high + nCS_ = 1; + + wait_us(500); + + // Prepare communication between the host and the BlueNRG SPI interface + HCI_Init(); + + // Set the interrupt handler for the device + irq_.mode(PullDown); // set irq mode + irq_.rise(&HCI_Isr); +} + +/**************************************************************************/ +/** + @brief Destructor +*/ +/**************************************************************************/ +BlueNRGDevice::~BlueNRGDevice(void) +{ +} + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param hw_version The HW version is written to this parameter + * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise + */ +uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version) +{ + uint8_t status; + + status = getBlueNRGUpdaterHWVersion(hw_version); + + return (status); +} + +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns BLE_STATUS_SUCCESS on success, or a number + * not equal to 0 in case of error + * (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size) +{ + int status = program_device(fw_image, fw_size); + + return (status); +} + + +/** + * @brief Initialises anything required to start using BLE + * @param[in] instanceID + * The ID of the instance to initialize. + * @param[in] callback + * A callback for when initialization completes for a BLE + * instance. This is an optional parameter set to NULL when not + * supplied. + * + * @return BLE_ERROR_NONE if the initialization procedure was started + * successfully. + */ +ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback) +{ + if (isInitialized) { + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_ALREADY_INITIALIZED + }; + callback.call(&context); + return BLE_ERROR_ALREADY_INITIALIZED; + } + + // Init the BlueNRG/BlueNRG-MS stack + btleInit(); + + isInitialized = true; + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_NONE + }; + callback.call(&context); + + return BLE_ERROR_NONE; +} + + +/** + @brief Resets the BLE HW, removing any existing services and + characteristics + @param[in] void + @returns void +*/ +void BlueNRGDevice::reset(void) +{ + /* Reset BlueNRG SPI interface. Hold reset line to 0 for 1500us */ + rst_ = 0; + wait_us(1500); + rst_ = 1; + + /* Wait for the radio to come back up */ + wait_us(5000); +} + +/*! + @brief Wait for any BLE Event like BLE Connection, Read Request etc. + @param[in] void + @returns char * +*/ +void BlueNRGDevice::waitForEvent(void) +{ + bool must_return = false; + + do { + bluenrgDeviceInstance.processEvents(); + + if(must_return) return; + + __WFE(); /* it is recommended that SEVONPEND in the + System Control Register is NOT set */ + must_return = true; /* after returning from WFE we must guarantee + that conrol is given back to main loop before next WFE */ + } while(true); + +} + +/*! + @brief get GAP version + @brief Get the BLE stack version information + @param[in] void + @returns char * + @returns char * +*/ +const char *BlueNRGDevice::getVersion(void) +{ + return getVersionString(); +} + +/**************************************************************************/ +/*! + @brief get reference to GAP object + @param[in] void + @returns Gap& +*/ +/**************************************************************************/ +Gap &BlueNRGDevice::getGap() +{ + return BlueNRGGap::getInstance(); +} + +const Gap &BlueNRGDevice::getGap() const +{ + return BlueNRGGap::getInstance(); +} + +/**************************************************************************/ +/*! + @brief get reference to GATT server object + @param[in] void + @returns GattServer& +*/ +/**************************************************************************/ +GattServer &BlueNRGDevice::getGattServer() +{ + return BlueNRGGattServer::getInstance(); +} + +const GattServer &BlueNRGDevice::getGattServer() const +{ + return BlueNRGGattServer::getInstance(); +} + +/**************************************************************************/ +/*! + @brief shut down the BLE device + @param[out] error if any +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::shutdown(void) { + PRINTF("BlueNRGDevice::reset\n"); + + if (!isInitialized) { + return BLE_ERROR_INITIALIZATION_INCOMPLETE; + } + + /* Reset the BlueNRG device first */ + reset(); + + /* Shutdown the BLE API and BlueNRG glue code */ + ble_error_t error; + + /* GattServer instance */ + error = BlueNRGGattServer::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* GattClient instance */ + error = BlueNRGGattClient::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* Gap instance */ + error = BlueNRGGap::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + isInitialized = false; + + PRINTF("BlueNRGDevice::reset complete\n"); + return BLE_ERROR_NONE; + +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size) +{ + uint16_t byte_count; + uint8_t len = 0; + uint8_t char_ff = 0xff; + volatile uint8_t read_char; + + uint8_t i = 0; + volatile uint8_t tmpreg; + + uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00}; + uint8_t header_slave[HEADER_SIZE]; + + /* Select the chip */ + nCS_ = 0; + + /* Read the header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = (uint8_t)(tmpreg); + } + + if (header_slave[0] == 0x02) { + /* device is ready */ + byte_count = (header_slave[4]<<8)|header_slave[3]; + + if (byte_count > 0) { + + /* avoid to read more data that size of the buffer */ + if (byte_count > buff_size){ + byte_count = buff_size; + } + + for (len = 0; len < byte_count; len++){ + read_char = spi_.write(char_ff); + buffer[len] = read_char; + } + } + } + /* Release CS line to deselect the chip */ + nCS_ = 1; + + // Add a small delay to give time to the BlueNRG to set the IRQ pin low + // to avoid a useless SPI read at the end of the transaction + for(volatile int i = 0; i < 2; i++)__NOP(); + +#ifdef PRINT_CSV_FORMAT + if (len > 0) { + print_csv_time(); + for (int i=0; i<len; i++) { + PRINT_CSV(" %02x", buffer[i]); + } + PRINT_CSV("\n"); + } +#endif + + return len; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRGDevice::spiWrite(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t result = 0; + uint32_t i; + volatile uint8_t tmpreg; + + unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00}; + + disable_irq(); + + /* CS reset */ + nCS_ = 0; + + /* Exchange header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = tmpreg; + } + + if (header_slave[0] == 0x02) { + /* SPI is ready */ + if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { + + /* Buffer is big enough */ + for (i = 0; i < Nb_bytes1; i++) { + spi_.write(*(data1 + i)); + } + for (i = 0; i < Nb_bytes2; i++) { + spi_.write(*(data2 + i)); + } + } else { + /* Buffer is too small */ + result = -2; + } + } else { + /* SPI is not ready */ + result = -1; + } + + /* Release CS line */ + //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); + nCS_ = 1; + + enable_irq(); + + return result; +} + +bool BlueNRGDevice::dataPresent() +{ + return (irq_ == 1); +} + +void BlueNRGDevice::disable_irq() +{ + irq_.disable_irq(); +} + +void BlueNRGDevice::enable_irq() +{ + irq_.enable_irq(); +} + +void BlueNRGDevice::processEvents() { + btle_handler(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,68 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattClient.h" + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + uuid = uuidIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + + void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) { + lastHandle = lastHandleIn; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1477 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file BlueNRGGap.cpp + * @author STMicroelectronics + * @brief Implementation of BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGap + * @brief BlueNRG BLE_API GAP Adaptation + * @{ + */ + +#include "BlueNRGDevice.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_payload.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/* + * Utility to process GAP specific events (e.g., Advertising timeout) + */ +void BlueNRGGap::Process(void) +{ + if(AdvToFlag) { + AdvToFlag = false; + stopAdvertising(); + } + + if(ScanToFlag) { + ScanToFlag = false; + stopScan(); + } +} + +/**************************************************************************/ +/*! + @brief Sets the advertising parameters and payload for the device. + Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API + + @params[in] advData + The primary advertising data payload + @params[in] scanResponse + The optional Scan Response payload if the advertising + type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED + in \ref GapAdveritinngParams + + @returns \ref ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @retval BLE_ERROR_BUFFER_OVERFLOW + The proposed action would cause a buffer overflow. All + advertising payloads must be <= 31 bytes, for example. + + @retval BLE_ERROR_NOT_IMPLEMENTED + A feature was requested that is not yet supported in the + nRF51 firmware or hardware. + + @retval BLE_ERROR_PARAM_OUT_OF_RANGE + One of the proposed values is outside the valid range. + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) +{ + PRINTF("BlueNRGGap::setAdvertisingData\n\r"); + /* Make sure we don't exceed the advertising payload length */ + if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + PRINTF("Exceeded the advertising payload length\n\r"); + return BLE_ERROR_BUFFER_OVERFLOW; + } + + /* Make sure we have a payload! */ + if (advData.getPayloadLen() != 0) { + PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); + + /* Align the GAP Service Appearance Char value coherently + This setting is duplicate (see below GapAdvertisingData::APPEARANCE) + since BLE API has an overloaded function for appearance + */ + STORE_LE_16(deviceAppearance, advData.getAppearance()); + setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0])); + + + for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { + loadPtr.getUnitAtIndex(index); + + PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); + PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); + + switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { + /**< TX Power Level (in dBm) */ + case GapAdvertisingData::TX_POWER_LEVEL: + { + PRINTF("Advertising type: TX_POWER_LEVEL\n\r"); + int8_t enHighPower = 0; + int8_t paLevel = 0; + + int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); + tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); +#ifdef DEBUG + PRINTF("dbm=%d, ret=%d\n\r", dbm, ret); + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); +#endif + if(ret == BLE_STATUS_SUCCESS) { + aci_hal_set_tx_power_level(enHighPower, paLevel); + } + break; + } + /**< Appearance */ + case GapAdvertisingData::APPEARANCE: + { + PRINTF("Advertising type: APPEARANCE\n\r"); + + GapAdvertisingData::Appearance appearanceP; + memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2); + + PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]); + /* Align the GAP Service Appearance Char value coherently */ + setAppearance(appearanceP); + break; + } + + } // end switch + + } //end for + + } + + // update the advertising data in the shield if advertising is running + if (state.advertising == 1) { + tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS != ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload()); + if (ret) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + } + + _advData = advData; + _scanResponse = scanResponse; + + return BLE_ERROR_NONE; +} + +/* + * Utility to set ADV timeout flag + */ +void BlueNRGGap::setAdvToFlag(void) { + AdvToFlag = true; + signalEventsToProcess(); +} + +/* + * ADV timeout callback + */ +#ifdef AST_FOR_MBED_OS +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().stopAdvertising(); +} +#else +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().setAdvToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getAdvTimeout(); + t.detach(); /* disable the callback from the timeout */ +} +#endif /* AST_FOR_MBED_OS */ + +/* + * Utility to set SCAN timeout flag + */ +void BlueNRGGap::setScanToFlag(void) { + ScanToFlag = true; + signalEventsToProcess(); +} + +static void scanTimeoutCB(void) +{ + BlueNRGGap::getInstance().setScanToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getScanTimeout(); + t.detach(); /* disable the callback from the timeout */ +} + +/**************************************************************************/ +/*! + @brief Starts the BLE HW, initialising any services that were + added before this function was called. + + @param[in] params + Basic advertising details, including the advertising + delay, timeout and how the device should be advertised + + @note All services must be added before calling this function! + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ + +ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) +{ + tBleStatus ret; + int err; + + /* Make sure we support the advertising type */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { + /* ToDo: This requires a proper security implementation, etc. */ + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /* Check interval range */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { + /* Min delay is slightly longer for unconnectable devices */ + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } else { + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } + + /* Check timeout is zero for Connectable Directed */ + if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { + /* Timeout must be 0 with this type, although we'll never get here */ + /* since this isn't implemented yet anyway */ + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* Check timeout for other advertising types */ + if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && + (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* + * Advertising filter policy setting + * FIXME: the Security Manager should be implemented + */ + AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode(); + if(mode != ADV_POLICY_IGNORE_WHITELIST) { + ret = aci_gap_configure_whitelist(); + if(ret != BLE_STATUS_SUCCESS) { + PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret); + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } + + uint8_t advFilterPolicy = NO_WHITE_LIST_USE; + switch(mode) { + case ADV_POLICY_FILTER_SCAN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN; + break; + case ADV_POLICY_FILTER_CONN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN; + break; + case ADV_POLICY_FILTER_ALL_REQS: + advFilterPolicy = WHITE_LIST_FOR_ALL; + break; + default: + advFilterPolicy = NO_WHITE_LIST_USE; + break; + } + + /* Check the ADV type before setting scan response data */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED || + params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) { + + /* set scan response data */ + PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen()); + ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS!=ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + } else { + hci_le_set_scan_resp_data(0, NULL); + } + + setAdvParameters(); + PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType()); + + err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload()); + + if (err) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + + tBDAddr dummy_addr = { 0 }; + uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval; + uint16_t advIntervalMax = advIntervalMin + 1; + + err = hci_le_set_advertising_parameters( + advIntervalMin, + advIntervalMax, + params.getAdvertisingType(), + addr_type, + 0x00, + dummy_addr, + /* all channels */ 7, + advFilterPolicy + ); + + if (err) { + PRINTF("impossible to set advertising parameters\n\r"); + PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1); + PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy); + return BLE_ERROR_INVALID_PARAM; + } + + err = hci_le_set_advertise_enable(0x01); + if (err) { + PRINTF("impossible to start advertising\n\r"); + return BLE_ERROR_UNSPECIFIED; + } + + if(params.getTimeout() != 0) { + PRINTF("!!! attaching adv to!!!\n"); +#ifdef AST_FOR_MBED_OS + minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000)); +#else + advTimeout.attach(advTimeoutCB, params.getTimeout()); +#endif + } + + return BLE_ERROR_NONE; + +} + + +/**************************************************************************/ +/*! + @brief Stops the BLE HW and disconnects from any devices + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::stopAdvertising(void) +{ + if(state.advertising == 1) { + + int err = hci_le_set_advertise_enable(0); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + PRINTF("Advertisement stopped!!\n\r") ; + //Set GapState_t::advertising state + state.advertising = 0; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason) +{ + tBleStatus ret; + + ret = aci_gap_terminate(connectionHandle, reason); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_COMMAND_DISALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason) +{ + return disconnect(m_connectionHandle, reason); +} + +/**************************************************************************/ +/*! + @brief Sets the 16-bit connection handle + + @param[in] conn_handle + Connection Handle which is set in the Gap Instance + + @returns void +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionHandle(uint16_t conn_handle) +{ + m_connectionHandle = conn_handle; +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit connection handle + + @param[in] void + + @returns uint16_t + Connection Handle of the Gap Instance +*/ +/**************************************************************************/ +uint16_t BlueNRGGap::getConnectionHandle(void) +{ + return m_connectionHandle; +} + +/**************************************************************************/ +/*! + @brief Sets the BLE device address. SetAddress will reset the BLE + device and re-initialize BTLE. Will not start advertising. + + @param[in] type + Type of Address + + @param[in] address[6] + Value of the Address to be set + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address) +{ + if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if(type == BLEProtocol::AddressType::PUBLIC){ + tBleStatus ret = aci_hal_write_config_data( + CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + address + ); + if(ret != BLE_STATUS_SUCCESS) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } else if (type == BLEProtocol::AddressType::RANDOM_STATIC) { + // ensure that the random static address is well formed + if ((address[5] & 0xC0) != 0xC0) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // thanks to const correctness of the API ... + tBDAddr random_address = { 0 }; + memcpy(random_address, address, sizeof(random_address)); + int err = hci_le_set_random_address(random_address); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // It is not possible to get the bluetooth address when it is set + // store it locally in class data member + memcpy(bdaddr, address, sizeof(bdaddr)); + } else { + // FIXME random addresses are not supported yet + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + // if we're here then the address was correctly set + // commit it inside the addr_type + addr_type = type; + isSetAddress = true; + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Returns boolean if the address of the device has been set + or not + + @returns bool + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +bool BlueNRGGap::getIsSetAddress() +{ + return isSetAddress; +} + +/**************************************************************************/ +/*! + @brief Returns the address of the device if set + + @returns Pointer to the address if Address is set else NULL + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) +{ + uint8_t bdaddr[BDADDR_SIZE]; + uint8_t data_len_out; + + // precondition, check that pointers in input are valid + if (typeP == NULL || address == NULL) { + return BLE_ERROR_INVALID_PARAM; + } + + if (addr_type == BLEProtocol::AddressType::PUBLIC) { + tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr); + if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) { + return BLE_ERROR_UNSPECIFIED; + } + } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) { + // FIXME hci_read_bd_addr and + // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1 + // does not work, use the address stored in class data member + memcpy(bdaddr, this->bdaddr, sizeof(bdaddr)); + } else { + // FIXME: should be implemented with privacy features + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + *typeP = addr_type; + memcpy(address, bdaddr, BDADDR_SIZE); + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief obtains preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + + if (!g_preferred_connection_parameters_char_handle) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // Peripheral preferred connection parameters are an array of 4 uint16_t + uint8_t parameters_packed[parameter_size * 4]; + uint16_t bytes_read = 0; + + tBleStatus err = aci_gatt_read_handle_value( + g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE, + sizeof(parameters_packed), + &bytes_read, + parameters_packed + ); + + PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read); + + // check that the read succeed and the result have the expected length + if (err || bytes_read != sizeof(parameters_packed)) { + return BLE_ERROR_UNSPECIFIED; + } + + // memcpy field by field + memcpy(¶ms->minConnectionInterval, parameters_packed, parameter_size); + memcpy(¶ms->maxConnectionInterval, ¶meters_packed[parameter_size], parameter_size); + memcpy(¶ms->slaveLatency, ¶meters_packed[2 * parameter_size], parameter_size); + memcpy(¶ms->connectionSupervisionTimeout, ¶meters_packed[3 * parameter_size], parameter_size); + + return BLE_ERROR_NONE; +} + + +/**************************************************************************/ +/*! + @brief sets preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + uint8_t parameters_packed[parameter_size * 4]; + + // ensure that parameters are correct + // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC + if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) && + params->minConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) && + params->maxConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (params->slaveLatency > 0x01F3) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) && + params->connectionSupervisionTimeout != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // copy the parameters inside the byte array + memcpy(parameters_packed, ¶ms->minConnectionInterval, parameter_size); + memcpy(¶meters_packed[parameter_size], ¶ms->maxConnectionInterval, parameter_size); + memcpy(¶meters_packed[2 * parameter_size], ¶ms->slaveLatency, parameter_size); + memcpy(¶meters_packed[3 * parameter_size], ¶ms->connectionSupervisionTimeout, parameter_size); + + tBleStatus err = aci_gatt_update_char_value( + g_gap_service_handle, + g_preferred_connection_parameters_char_handle, + /* offset */ 0, + sizeof(parameters_packed), + parameters_packed + ); + + if (err) { + PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ; + switch (err) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief updates preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) +{ + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(gapRole == Gap::CENTRAL) { + ret = aci_gap_start_connection_update(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout, + CONN_L1, CONN_L2); + } else { + ret = aci_l2cap_connection_parameter_update_request(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout); + } + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case ERR_COMMAND_DISALLOWED: + case BLE_STATUS_NOT_ALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sets the Device Name Characteristic + + @param[in] deviceName + pointer to device name to be set + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) +{ + tBleStatus ret; + uint8_t nameLen = 0; + + nameLen = strlen((const char*)deviceName); + PRINTF("DeviceName Size=%d\n\r", nameLen); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_device_name_char_handle, + 0, + nameLen, + deviceName); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Gets the Device Name Characteristic + + @param[in] deviceName + pointer to device name + + @param[in] lengthP + pointer to device name length + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) +{ + tBleStatus ret; + + ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + *lengthP, + (uint16_t *)lengthP, + deviceName); + PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } +} + +/**************************************************************************/ +/*! + @brief Sets the Device Appearance Characteristic + + @param[in] appearance + device appearance + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance) +{ + tBleStatus ret; + uint8_t deviceAppearance[2]; + + STORE_LE_16(deviceAppearance, appearance); + PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_appearance_char_handle, + 0, 2, (uint8_t *)deviceAppearance); + if (BLE_STATUS_SUCCESS == ret){ + return BLE_ERROR_NONE; + } + + PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Gets the Device Appearance Characteristic + + @param[in] appearance + pointer to device appearance value + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) +{ + tBleStatus ret; + uint16_t lengthP = 2; + + ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + lengthP, + &lengthP, + (uint8_t*)appearanceP); + PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + +} + +GapScanningParams* BlueNRGGap::getScanningParams(void) +{ + return &_scanningParams; +} + +static void makeConnection(void) +{ + BlueNRGGap::getInstance().createConnection(); +} + +void BlueNRGGap::Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI) +{ + switch (reason) { + case DEVICE_FOUND: + { + GapAdvertisingParams::AdvertisingType_t type; + bool isScanResponse = false; + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * Private Random Address + * => scan_results = FALSE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type); + if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV || + (addr_type == RESOLVABLE_PRIVATE_ADDR || + addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) { + return; + } + + switch(adv_type) { + case ADV_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + break; + case ADV_DIRECT_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED; + break; + case ADV_SCAN_IND: + case SCAN_RSP: + type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED; + isScanResponse = true; + break; + case ADV_NONCONN_IND: + type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED; + break; + default: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + } + + PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n", + *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + if(!_connecting) { + processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data); + } + PRINTF("!!!After processAdvertisementReport\n\r"); + } + break; + + case DISCOVERY_COMPLETE: + // The discovery is complete. If this is due to a stop scanning (i.e., the device + // we are interested in has been found) and a connection has been requested + // then we start the device connection. + PRINTF("DISCOVERY_COMPLETE\n\r"); + _scanning = false; + + // Since the DISCOVERY_COMPLETE event can be received during the scanning interval, + // we need to delay the starting of connection + uint16_t delay = (_scanningParams.getInterval()*0.625); + +#ifdef AST_FOR_MBED_OS + if(_connecting) { + minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay)); + } +#else + Clock_Wait(delay); + if(_connecting) { + makeConnection(); + } +#endif /* AST_FOR_MBED_OS */ + + break; + } +} + +ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) +{ + + tBleStatus ret = BLE_STATUS_SUCCESS; + + // Stop ADV before scanning + /* + if (state.advertising == 1) { + stopAdvertising(); + } + */ + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * White List is empty + * => scan operation = FAILURE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + uint8_t whiteListSize = whitelistAddresses.size; + if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + ret = btleStartRadioScan(scanningParams.getActiveScanning(), + scanningParams.getInterval(), + scanningParams.getWindow(), + addr_type); + + PRINTF("Scanning...\n\r"); + PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000); + PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000); + //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval()); + //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1); + //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2); + if (BLE_STATUS_SUCCESS == ret){ + PRINTF("Observation Procedure Started\n"); + _scanning = true; + + if(scanningParams.getTimeout() != 0) { + PRINTF("!!! attaching scan to!!!\n"); + scanTimeout.attach(scanTimeoutCB, scanningParams.getTimeout()); + } + + return BLE_ERROR_NONE; + } + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + switch (ret) { + case BLE_STATUS_INVALID_CID: + PRINTF("Observation Procedure not implemented!!!\n\r"); + return BLE_ERROR_NOT_IMPLEMENTED; + default: + PRINTF("Observation Procedure failed (0x%02X)\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } + +} + +ble_error_t BlueNRGGap::stopScan() { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(_scanning) { + ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC); + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Discovery Procedure Terminated\n"); + return BLE_ERROR_NONE; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief set Tx power level + @param[in] txPower Transmission Power level + @returns ble_error_t +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setTxPower(int8_t txPower) +{ + tBleStatus ret; + + int8_t enHighPower = 0; + int8_t paLevel = 0; + + ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + ret = aci_hal_set_tx_power_level(enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief get permitted Tx power values + @param[in] values pointer to pointer to permitted power values + @param[in] num number of values +*/ +/**************************************************************************/ +void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { + static const int8_t permittedTxValues[] = { + -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8 + }; + + *valueArrayPP = permittedTxValues; + *countP = sizeof(permittedTxValues) / sizeof(int8_t); +} + +/**************************************************************************/ +/*! + @brief Set advertising parameters according to the current state + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setAdvParameters(void) +{ + uint32_t advIntMS; + + if(state.connected == 1) { + advIntMS = (conn_min_interval*1.25)-GUARD_INT; + advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS); + + PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval); + } else { + advInterval = _advParams.getIntervalInADVUnits(); + } +} + +/**************************************************************************/ +/*! + @brief Set connection parameters according to the current state (ADV and/or SCAN) + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionParameters(void) +{ + if (state.connected == 1) { + + PRINTF("state.connected=1\r\n"); + scanInterval = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(conn_min_interval*1.25); + scanWindow = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(((conn_min_interval*1.25)/100)*60); // scanWin ~= 60%(scanInt) + + } else if (state.advertising == 1) { + + if (_scanningParams.getInterval() < advInterval) { + PRINTF("state.adv=1 scanInterval<advInterval\r\n"); + scanInterval = advInterval; + scanWindow = advInterval; + } else { + PRINTF("state.adv=1 scanInterval>=advInterval\r\n"); + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + } + + if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms + conn_min_interval = MAX_INT_CONN; + conn_max_interval = MAX_INT_CONN; + } else { + conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + } + + } else { + + PRINTF("state.adv = 0\r\n"); + + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) || + SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms + conn_min_interval = DEF_INT_CONN; + conn_max_interval = DEF_INT_CONN; + } else { + conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + } + } + PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval)); + PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow)); + PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25)); + PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25)); + +} + +ble_error_t BlueNRGGap::createConnection () +{ + tBleStatus ret; + + /* + Before creating connection, set parameters according + to previous or current procedure (ADV and/or SCAN) + */ + setConnectionParameters(); + + /* + Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, + Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max + */ + ret = aci_gap_create_connection(scanInterval, + scanWindow, + _peerAddrType, + (unsigned char*)_peerAddr, + addr_type, + conn_min_interval, conn_max_interval, 0, + SUPERV_TIMEOUT, CONN_L1, CONN_L1); + + //_connecting = false; + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Connection started.\n"); + _connecting = false; + return BLE_ERROR_NONE; + } +} + +ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) +{ + /* avoid compiler warnings about unused variables */ + (void)connectionParams; + + setScanParams(scanParams->getInterval(), + scanParams->getWindow(), + scanParams->getTimeout(), + scanParams->getActiveScanning() + ); + + // Save the peer address + for(int i=0; i<BDADDR_SIZE; i++) { + _peerAddr[i] = peerAddr[i]; + } + _peerAddrType = peerAddrType; + + _connecting = true; + + if(_scanning) { + stopScan(); + } else { + PRINTF("Calling createConnection from connect()\n\r"); + return createConnection(); + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the advertising policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode) +{ + advertisingPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the scanning policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode) +{ + scanningPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Get the current advertising policy filter mode. + + @returns The advertising policy filter mode. +*/ +/**************************************************************************/ +Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const +{ + return advertisingPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Get the current scanning policy filter mode. + + @returns The scanning policy filter mode. + +*/ +/**************************************************************************/ +Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const +{ + return scanningPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGap's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::reset(void) +{ + PRINTF("BlueNRGGap::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (Gap::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + AdvToFlag = false; + ScanToFlag = false; + + /* Clear derived class members */ + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + return BLE_ERROR_NONE; +} + +void BlueNRGGap::setConnectionInterval(uint16_t interval) { + conn_min_interval = interval; + conn_max_interval = interval; +} + +Gap::Role_t BlueNRGGap::getGapRole(void) +{ + return (gapRole); +} + +void BlueNRGGap::setGapRole(Gap::Role_t role) +{ + gapRole = role; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,403 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTClient + * @brief BlueNRG BLE_API GattClient Adaptation + * @{ + */ + +#include "BlueNRGGattClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +#include <new> +#include <assert.h> + +ble_error_t BlueNRGGattClient::createGattConnectionClient(Gap::Handle_t connectionHandle) +{ + if(MAX_ACTIVE_CONNECTIONS <= _numConnections) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + for(uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + + if(_connectionPool[i] == NULL) { + BlueNRGGattConnectionClient *gattConnectionClient = new(std::nothrow) BlueNRGGattConnectionClient(this, connectionHandle); + + if (gattConnectionClient == NULL) { + return BLE_ERROR_NO_MEM; + } + + _connectionPool[i] = gattConnectionClient; + _connectionPool[i]->onServiceDiscoveryTermination(terminationCallback); + _numConnections++; + + PRINTF("createGattConnectionClient: _connectionPool index=%d\r\n", i); + PRINTF("createGattConnectionClient: succesfully added new gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + break; + } + } + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattClient::removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason) +{ + + PRINTF("removeGattConnectionClient: connectionHandle=%d reason=0x%x\r\n", connectionHandle, reason); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("removeGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("removeGattConnectionClient: Found gattConnectionClient\r\n"); + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + PRINTF("removeGattConnectionClient: succesfully removed gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + + break; + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + + return BLE_ERROR_NONE; +} + +BlueNRGGattConnectionClient * BlueNRGGattClient::getGattConnectionClient(Gap::Handle_t connectionHandle) { + PRINTF("getGattConnectionClient\r\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("getGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("getGattConnectionClient: Found gattConnectionClient\r\n"); + return _connectionPool[i]; + } + } + + return NULL; +} + +void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code) { + + if(error_code != BLE_STATUS_SUCCESS) { + return; + } + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->gattProcedureCompleteCB(error_code); +} + +void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServicesCB(event_data_length, + attribute_data_length, + attribute_data_list); +} + +void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServiceCB(event_data_length, + handles_info_list); +} + +ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->findServiceChars(); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharsCB(event_data_length, + handle_value_pair_length, + handle_value_pair); +} + +void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharByUUIDCB(event_data_length, + attr_handle, + attr_value); +} + +void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->discAllCharacDescCB(event_data_length, + format, + handle_uuid_pair); +} + +void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charReadCB(event_data_length, + attribute_value); +} + +void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWritePrepareCB(event_data_length, + attribute_handle, + offset, + part_attr_value); +} + +void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWriteExecCB(event_data_length); +} + +ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattClient launchServiceDiscovery\n\r"); + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->launchServiceDiscovery(sc, cc, matchingServiceUUID, matchingCharacteristicUUIDIn); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, matchingServiceUUID); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, startHandle, endHandle); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +bool BlueNRGGattClient::isServiceDiscoveryActive(void) const +{ + bool isSDActive = false; + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + isSDActive |= _connectionPool[i]->isServiceDiscoveryActive(); + } + } + + return isSDActive; +} + +void BlueNRGGattClient::terminateServiceDiscovery(void) +{ + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + _connectionPool[i]->terminateServiceDiscovery(); + } + } +} + +void BlueNRGGattClient::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; ++i) { + if (_connectionPool[i]) { + _connectionPool[i]->onServiceDiscoveryTermination(callback); + } + } +} + +ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->read(attributeHandle, offset); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->write(cmd, attributeHandle, length, value); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(characteristic.getConnectionHandle()); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverCharacteristicDescriptors(characteristic, discoveryCallback, terminationCallback); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattClient's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattClient::reset(void) +{ + PRINTF("BlueNRGGattClient::reset\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if(_connectionPool[i] != NULL) { + _connectionPool[i]->reset(); + + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + } + } + + return BLE_ERROR_NONE; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,816 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGattConnectionClient + * @brief BlueNRG GattConnectionClient Adaptation + * @{ + */ + +#include "BlueNRGGattConnectionClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" +#include "ble_debug.h" + +// #define PRINTF printf + +static uint8_t props_mask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 + }; + +void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code) +{ + if(error_code != BLE_STATUS_SUCCESS) { + _currentState = GATT_IDLE; + return; + } + + // Service Discovery complete +/* + if(_currentState != GATT_IDLE && + _currentState != GATT_DISCOVERY_TERMINATED && + _currentState != GATT_WRITE_CHAR && + _currentState != GATT_READ_CHAR) { +*/ + if(_currentState == GATT_SERVICE_DISCOVERY) { + findServiceChars(); + return; + } + + if(_currentState == GATT_CHAR_DESC_DISCOVERY) { + _currentState = GATT_IDLE; + if(charDescTerminationCallback != NULL) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { + _characteristic, + BLE_ERROR_NONE + }; + charDescTerminationCallback(¶ms); + } + return; + } + + // Read complete + if(_currentState == GATT_READ_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processReadResponse(&readCBParams); + free((void*)(readCBParams.data)); + readCBParams.data = NULL; + return; + } + + // Write complete + if(_currentState == GATT_WRITE_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); + return; + } +} + +void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numAttr; + + numAttr = (event_data_length - 1) / attribute_data_length; + + offset = 0; + for (i=0; i<numAttr; i++) { + startHandle = attribute_data_list[offset]; + endHandle = attribute_data_list[offset+2]; + + // UUID Type + if (attribute_data_length == 6) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4]; + PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(attribute_data_list+offset+4, UUID::LSB); + +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + + } + + PRINTF("Setup serviceIndex = %d\n\r", _numServices); + discoveredService[_numServices].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += attribute_data_length; + } + + PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr); + +} + +void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numHandlePairs; + + numHandlePairs = (event_data_length - 1) / 2; + + offset = 0; + for (i=0; i<numHandlePairs; i++) { + startHandle = handles_info_list[offset]; + endHandle = handles_info_list[offset+2]; + + PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle); + + + if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle); + uuid = _matchingServiceUUID.getShortUUID(); + } else { +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02x", longUUIDBytes[i]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB); + } + + discoveredService[i].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += 4; + } +} + +void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) +{ + // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + uint8_t i, numChar, offset; + + numChar = (event_data_length - 1) / handle_value_pair_length; + + PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar); + + offset = 0; + for (i=0; i<numChar; i++) { + // UUID Type + if (handle_value_pair_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(handle_value_pair+offset+5, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & handle_value_pair[offset+2]); + p._read = (props_mask[1] & handle_value_pair[offset+2])>>1; + p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2; + p._write = (props_mask[3] & handle_value_pair[offset+2])>>3; + p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4; + p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5; + p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = handle_value_pair[offset+2]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = handle_value_pair[offset]; + valueHandle = handle_value_pair[offset+3]; + lastHandle = valueHandle+1; + PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle); + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; + + offset += handle_value_pair_length; + } +} + +void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) +{ + // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + + PRINTF("serviceCharByUUIDCB\n\r"); + + // UUID Type + if (event_data_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = attr_value[4]<<8|attr_value[3]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(attr_value+3, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & attr_value[0]); + p._read = (props_mask[1] & attr_value[0])>>1; + p._writeWoResp = (props_mask[2] & attr_value[0])>>2; + p._write = (props_mask[3] & attr_value[0])>>3; + p._notify = (props_mask[4] & attr_value[0])>>4; + p._indicate = (props_mask[5] & attr_value[0])>>5; + p._authSignedWrite = (props_mask[6] & attr_value[0])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = attr_value[0]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = attr_handle; + valueHandle = attr_value[1]; + lastHandle = valueHandle+1; + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + // update the last handle and call the characteristic discovery callback for previous char + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; +} + +ble_error_t BlueNRGGattConnectionClient::findServiceChars(void) +{ + PRINTF("findServiceChars\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + + DiscoveredService *service; + + // complete the discovery of the last characteristic of the previous service. + // Its last handle wasn't known before this point + // update the handle and call the characteristic discovery callback. + if (_servIndex != 0 && _numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle()); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars = 0; + + // We finished chars discovery for all services + if(_servIndex >= _numServices) { + PRINTF("!!!We finished chars discovery for all services!!!\n\r"); + //_currentState = GATT_CHARS_DISCOVERY_COMPLETE; + + terminateServiceDiscovery(); + + return BLE_ERROR_NONE; + } + + service = &discoveredService[_servIndex]; + /* + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID()); + } else { + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); + } + */ + + if(serviceDiscoveryCallback) { + serviceDiscoveryCallback(service); + } + + PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex); + //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle()); + + if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) { + PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r"); + ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle()); + } else { + + uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID()); + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; +#ifdef DEBUG + PRINTF("findServiceChars C UUID-"); + for(unsigned i = 0; i < 2; i++) { + PRINTF("%02X", short_uuid[i]); + } + PRINTF("\n\r"); +#endif + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID(); +#ifdef DEBUG + PRINTF("(findServiceChars) C UUID-"); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", uuid[i]); + } + PRINTF("\r\n"); +#endif + } + + ret = aci_gatt_disc_charac_by_uuid(_connectionHandle, + service->getStartHandle(), + service->getEndHandle(), + uuid_type, + uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _servIndex++; + } + + PRINTF("findServiceChars ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + unsigned j; + + if(isServiceDiscoveryActive()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if(!sc && !cc) { + // nothing to do + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r"); + return BLE_ERROR_NONE; + } + + serviceDiscoveryCallback = sc; + characteristicDiscoveryCallback = cc; + _matchingServiceUUID = matchingServiceUUID; + _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn; + + //reset services + _numServices = 0; + _numChars = 0; + _servIndex = 0; + for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) { + discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE); + } + + if(matchingServiceUUID == BLE_UUID_UNKNOWN) { + + // Wildcard: search for all services + PRINTF("Wildcard: search for all services\r\n"); + ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle); + + } else { + PRINTF("search for specific services\r\n"); + + uint8_t type = matchingServiceUUID.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID()); +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x"); + for(j = 0; j < 2; j++) { + PRINTF("%02X", short_uuid[j]); + } + PRINTF("\n\r"); +#endif + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; + + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)matchingServiceUUID.getBaseUUID(); + +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x"); + for(j = 0; j < 16; j++) { + PRINTF("%02X", uuid[j]); + } + PRINTF("\n\r"); +#endif + } + + // search for specific service by UUID + ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_SERVICE_DISCOVERY; + } + + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)matchingServiceUUID; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)startHandle; + (void)endHandle; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const +{ + if(_currentState == GATT_SERVICE_DISCOVERY) { + return true; + } + + return false; +} + +void BlueNRGGattConnectionClient::terminateServiceDiscovery(void) +{ + _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED; + + if (terminationCallback) { + terminationCallback(_connectionHandle); + } +} + +void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value) +{ + // copy the data read, they will be forwarded to the user once the procedure + // has completed + readCBParams.connHandle = _connectionHandle; + readCBParams.offset = 0; + readCBParams.len = event_data_length; + readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length)); + memcpy((void*)(readCBParams.data), attribute_value, event_data_length); +} + +ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + /* avoid compiler warnings about unused variables */ + (void)offset; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // Save the attribute_handle not provided by evt_att_read_resp + gattc->readCBParams.handle = attributeHandle; + + ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle); + + if(ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_READ_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } +} + +void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) +{ + // Update the write response params + writeCBParams.handle = attribute_handle; + writeCBParams.offset = offset; + writeCBParams.len = event_data_length-4; //(?) + writeCBParams.data = part_attr_value; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length) +{ + /* avoid compiler warnings about unused variables */ + (void)event_data_length; + + writeCBParams.connHandle = _connectionHandle; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + /* avoid compiler warnings about unused variables */ + (void)cmd; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // We save the write response params (used by the callback) because + // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE + gattc->writeCBParams.connHandle = _connectionHandle; + gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD; + gattc->writeCBParams.handle = attributeHandle; + gattc->writeCBParams.offset = 0; + gattc->writeCBParams.len = length; + gattc->writeCBParams.data = value; + + ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); + + if (ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_WRITE_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } + +} + +void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + GattAttribute::Handle_t attHandle; + UUID uuid; + uint8_t i, numCharacDesc, offset, handle_uuid_length; + + handle_uuid_length = 4; //Handle + UUID_16 + if (format == 2) + handle_uuid_length = 18; //Handle + UUID_128 + + numCharacDesc = (event_data_length - 1) / handle_uuid_length; + + offset = 0; + + PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n", + event_data_length, format); + + + for (i=0; i<numCharacDesc; i++) { + memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle)); + + // UUID Type + if (handle_uuid_length == 4) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2]; + PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB); +#ifdef DEBUG + PRINTF("D UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + } + + if(charDescDiscoveryCallback != NULL) { + CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { + _characteristic, + DiscoveredCharacteristicDescriptor( + _characteristic.getGattClient(), + _connectionHandle, + attHandle, + uuid + ) + }; + charDescDiscoveryCallback(¶ms); + } + + _numCharDesc++; + + offset += handle_uuid_length; + } +} + +ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { + + tBleStatus ret; + + if(_currentState != GATT_IDLE) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + charDescDiscoveryCallback = discoveryCallback; + charDescTerminationCallback = terminationCallback; + + GattAttribute::Handle_t valueHandle = characteristic.getValueHandle(); + GattAttribute::Handle_t lastHandle = characteristic.getLastHandle(); + + PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle); + ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle); + + if (ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_CHAR_DESC_DISCOVERY; + _characteristic = characteristic; + return BLE_ERROR_NONE; + } + switch (ret) { + case BLE_STATUS_INVALID_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattConnectionClient::reset(void) { + PRINTF("BlueNRGGattConnectionClient::reset\n"); + + /* Clear all state, including private members */ + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + _numServices = 0; + _servIndex = 0; + _numChars = 0; + _numCharDesc = 0; + + /* Clear class members */ + memset(discoveredService, 0, sizeof(discoveredService)); + memset(discoveredChar, 0, sizeof(discoveredChar)); + + // free response if allocated + if(readCBParams.data) { + free((void*)(readCBParams.data)); + } + + return BLE_ERROR_NONE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,755 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTSERVER + * @brief BlueNRG BLE_API GattServer Adaptation + * @{ + */ + +#include "BlueNRGGattServer.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/**************************************************************************/ +/*! + @brief Adds a new service to the GATT table on the peripheral + + @params[in] service + Pointer to instance of the Gatt Server to add + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::addService(GattService &service) +{ + /* ToDo: Make sure we don't overflow the array, etc. */ + /* ToDo: Make sure this service UUID doesn't already exist (?) */ + /* ToDo: Basic validation */ + + tBleStatus ret; + uint8_t type; + uint16_t short_uuid; + uint8_t primary_short_uuid[2]; + uint8_t primary_base_uuid[16]; + uint8_t char_base_uuid[16]; + const uint8_t *base_uuid; + const uint8_t *base_char_uuid; + + uint8_t charsCount = service.getCharacteristicCount(); + const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount; + + // check that there is enough characteristics left in the + // characteristic array. + if (charsCount > available_characteristics) { + PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics); + return BLE_ERROR_NO_MEM; + } + + const uint16_t maxAttrRecords = computeAttributesRecord(service); + + type = (service.getUUID()).shortOrLong(); + PRINTF("AddService(): Type:%d\n\r", type); + + /* Add the service to the BlueNRG */ + short_uuid = (service.getUUID()).getShortUUID(); + STORE_LE_16(primary_short_uuid, short_uuid); + + if(type==UUID::UUID_TYPE_LONG) { + base_uuid = (service.getUUID()).getBaseUUID(); + + COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]); + } + + ret = BLE_STATUS_SUCCESS; + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_serv(UUID_TYPE_16, + primary_short_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_serv(UUID_TYPE_128, + primary_base_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_OUT_OF_HANDLE: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case ERR_UNSPECIFIED_ERROR: + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_ERROR: + default: + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + + + service.setHandle(servHandle); + //serviceHandleVector.push_back(servHandle); + PRINTF("added servHandle handle =%u\n\r", servHandle); + uint16_t bleCharacteristic; + + //iterate to include all characteristics + for (uint8_t i = 0; i < charsCount; i++) { + GattCharacteristic *p_char = service.getCharacteristic(i); + uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); + + uint8_t int_8_uuid[2]; + STORE_LE_16(int_8_uuid, char_uuid); + + type = (p_char->getValueAttribute().getUUID()).shortOrLong(); + + if(type==UUID::UUID_TYPE_LONG) { + base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); +#ifdef DEBUG + for(uint8_t j=0; j<16; j++) { + PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]); + } + PRINTF("\n\r"); +#endif + COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]); + } + + PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); + /* + * Gatt_Evt_Mask -> HardCoded (0) + * Encryption_Key_Size -> Hardcoded (16) + * isVariable (variable length value field) -> Hardcoded (1) + */ + uint8_t Gatt_Evt_Mask = 0x0; + + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP; + } + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; + } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_16, + int_8_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_128, + char_base_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + case BLE_STATUS_CHARAC_ALREADY_EXISTS: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); + + p_characteristics[characteristicCount++] = p_char; + /* Set the characteristic value handle */ + p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE); + PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle()); + + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + ble_error_t err = write(p_char->getValueAttribute().getHandle(), + p_char->getValueAttribute().getValuePtr(), + p_char->getValueAttribute().getLength(), false /* localOnly */); + if (err) { + PRINTF("ERROR HERE !!!!\r\n"); + return err; + } + } + + // add descriptors now + uint16_t descHandle = 0; + PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); + + for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { + GattAttribute *descriptor = p_char->getDescriptor(descIndex); + uint8_t desc_uuid[16] = { 0 }; + + + uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT; + STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID()); + + if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) { + desc_uuid_type = CHAR_DESC_TYPE_128_BIT; + const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID(); + + COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]); + } + + ret = aci_gatt_add_char_desc(service.getHandle(), + bleCharacteristic, + desc_uuid_type, + desc_uuid, + descriptor->getMaxLength(), + descriptor->getLength(), + descriptor->getValuePtr(), + CHAR_DESC_SECURITY_PERMISSION, + CHAR_DESC_ACCESS_PERMISSION, + GATT_NOTIFY_ATTRIBUTE_WRITE, + MIN_ENCRY_KEY_SIZE, + CHAR_ATTRIBUTE_LEN_IS_FIXED, + &descHandle); + PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); + + switch (ret) { + case BLE_STATUS_SUCCESS: + PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); + descriptor->setHandle(descHandle); + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_INVALID_OPERATION: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + } + + serviceCount++; + + //FIXME: There is no GattService pointer array in GattServer. + // There should be one? (Only the user is aware of GattServices!) Report to forum. + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on char handle + + @param[in] attributeHandle + The handle of the GattCharacteristic to read from + @param[in] buffer + Buffer to hold the the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes read into the buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) +{ + tBleStatus ret; + uint16_t charHandle = attributeHandle; + + ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer); + + if(ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on the connection + and char handle + + @param[in] connectionHandle + The handle of the connection + @param[in] attributeHandle + The handle of the GattCharacteristic to write to + @param[in] buffer + Data to use when updating the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes in buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + uint8_t buffer[], + uint16_t *lengthP) { + + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)attributeHandle; + (void)buffer; + (void)lengthP; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t, + const uint8_t[], + uint16_t, bool localOnly) { + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)localOnly; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly) +{ + /* avoid compiler warnings about unused variables */ + (void)localOnly; + + // check that the len of the data to write are compatible with the characteristic + GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle); + if (!characteristic) { + PRINTF("characteristic not found\r\n"); + return BLE_ERROR_INVALID_PARAM; + } + + // if the attribute handle is the attribute handle of the characteristic value then + // write the value + if (attributeHandle == characteristic->getValueHandle()) { + // assert the len in input is correct for this characteristic + const GattAttribute& value_attribute = characteristic->getValueAttribute(); + + // reject write if the lenght exceed the maximum lenght of this attribute + if (value_attribute.getMaxLength() < len) { + PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + // reject write if the attribute size is fixed and the lenght in input is different than the + // length of the attribute. + if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) { + PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + tBleStatus ret; + + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + + PRINTF("updating bleCharacteristic valueHandle=%u,\ + corresponding serviceHandle=%u len=%d\n\r", + attributeHandle, bleCharHandleMap.find(charHandle)->second, len); + + /* + * If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. + */ + ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } else { + // write this handle has a descriptor handle + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + uint16_t service_handle = bleCharHandleMap.find(charHandle)->second; + + tBleStatus ret = aci_gatt_set_desc_value( + service_handle, + charHandle, + attributeHandle, + 0, + len, + buffer + ); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } +} + +/**************************************************************************/ +/*! + @brief Reads a value according to the handle provided + + @param[in] attributeHandle + The handle of the attribute to read from + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle) +{ + uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); + + GattReadCallbackParams readParams; + readParams.handle = attributeHandle; + + //PRINTF("readParams.handle = %d\n\r", readParams.handle); + HCIDataReadEvent(&readParams); + + //EXIT: + if(gapConnectionHandle != 0){ + //PRINTF("Calling aci_gatt_allow_read\n\r"); + aci_gatt_allow_read(gapConnectionHandle); + } + + return BLE_ERROR_NONE; +} + +// ask if the write request should be accepted of rejected +// return 0 in case of success or an ATT error response in +// case of faillure +uint8_t BlueNRGGattServer::Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length, + const uint8_t* data) { + + GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle); + if(!characteristic) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF; + } + + // check if the data length is in range + if (characteristic->getValueAttribute().getMaxLength() < data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + // if the length of the characteristic value is fixed + // then the data in input should be of that length + if (characteristic->getValueAttribute().hasVariableLength() == false && + characteristic->getValueAttribute().getMaxLength() != data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + GattWriteAuthCallbackParams params = { + connection_handle, + attr_handle, + /* offset */ 0, + data_length, + data, + /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED + }; + + return characteristic->authorizeWrite(¶ms) & 0xFF; +} + +/**************************************************************************/ +/*! + @brief Returns the GattCharacteristic according to the handle provided + + @param[in] attrHandle + The handle of the attribute + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) +{ + GattCharacteristic *p_char = NULL; + int i; + uint16_t handle, handle_1; + + PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle); + for(i=0; i<characteristicCount; i++) + { + handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + PRINTF("handle(%d)=%d\n\r", i, handle); + if(i==characteristicCount-1)//Last Characteristic check + { + if(attrHandle>=handle) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); + break; + } + } + else { + handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + //Testing if attribute handle is between two Characteristic Handles + if(attrHandle>=handle && attrHandle<handle_1) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); + break; + } else continue; + } + } + + return p_char; +} + +void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { + this->handleDataWrittenEvent(params); +} + +void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { + PRINTF("Called HCIDataReadEvent\n\r"); + this->handleDataReadEvent(params); +} + +void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { + this->handleEvent(type, charHandle); +} + +void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { + this->handleDataSentEvent(count); +} + + +ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { + // <TODO> + return (ble_error_t)0; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::reset(void) +{ + PRINTF("BlueNRGGattServer::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (GattServer::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + /* Clear class members */ + memset(p_characteristics, 0, sizeof(p_characteristics)); + memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles)); + serviceCount = 0; + characteristicCount = 0; + + return BLE_ERROR_NONE; +} + + +/// compute the number of attributes needed by this service. +uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) { + uint16_t attribute_records = 1; + + for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) { + // add two attributes, one for the characteristic declaration + // and the other for the characteristic value. + attribute_records += 2; + + const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index); + const uint8_t properties = characteristic->getProperties(); + // if notify or indicate are present, two attributes are + // needed + if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) || + (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { + attribute_records += 2; + } + + // if broadcast is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) { + attribute_records += 2; + } + + // if extended properties flag is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) { + attribute_records += 2; + } + + attribute_records += characteristic->getDescriptorCount(); + } + + // for some reason, if there is just a service, this value should + // be equal to 5 + if (attribute_records == 1) { + attribute_records = 5; + } + + return attribute_records; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,421 @@ +/** + ****************************************************************************** + * @file ble_hci.c + * @author AMS/HESA Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "ble_gp_timer.h" +#include "ble_debug.h" + +#include "stm32_bluenrg_ble.h" + +#if BLE_CONFIG_DBG_ENABLE +#undef PRINTF +#endif + +#define HCI_LOG_ON 0 + +#define HCI_READ_PACKET_NUM_MAX (0x40) + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tListNode hciReadPktPool; +tListNode hciReadPktRxQueue; + +// betzw - DEBUG: +//#define POOL_CNT +#ifdef POOL_CNT +#include <stdio.h> +static unsigned int nr_hciReadPktPool; +static unsigned int lowest_nr_hciReadPktPool; +#endif // POOL_CNT + +/* pool of hci read packets */ +static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; + +static volatile uint8_t hci_timer_id; +static volatile uint8_t hci_timeout; + +void hci_timeout_callback(void) +{ + hci_timeout = 1; + return; +} + +void HCI_Init(void) +{ + uint8_t index; + +#ifdef POOL_CNT + nr_hciReadPktPool = 0; +#endif // POOL_CNT + + /* Initialize list heads of ready and free hci data packet queues */ + list_init_head (&hciReadPktPool); + list_init_head (&hciReadPktRxQueue); + + /* Initialize the queue of free hci data packets */ + for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) + { + list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif // POOL_CNT + } + +#ifdef POOL_CNT + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif // POOL_CNT +} + +#define HCI_PCK_TYPE_OFFSET 0 +#define EVENT_PARAMETER_TOT_LEN_OFFSET 2 + +/** + * Verify if HCI packet is correctly formatted. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * @return 0 if HCI packet is as expected + */ +int HCI_verify(const tHciDataPacket * hciReadPacket) +{ + const uint8_t *hci_pckt = hciReadPacket->dataBuff; + + if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) + return 1; /* Incorrect type. */ + + if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) + return 2; /* Wrong length (packet truncated or too long). */ + + return 0; +} + +void HCI_Process(void) +{ + tHciDataPacket * hciReadPacket = NULL; + +#ifdef POOL_CNT + printf("betzw(%s, %d): nr_hciReadPktPool = %u (lowest = %u)\r\n", __func__, __LINE__, + nr_hciReadPktPool, lowest_nr_hciReadPktPool); +#endif // POOL_CNT + + Disable_SPI_IRQ(); + uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); + /* process any pending events read */ + while(list_empty == FALSE) + { + list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + Enable_SPI_IRQ(); + HCI_Event_CB(hciReadPacket->dataBuff); + Disable_SPI_IRQ(); + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + list_empty = list_is_empty(&hciReadPktRxQueue); + } + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG. */ + HCI_HandleSPI(); + Enable_SPI_IRQ(); +} + +BOOL HCI_Queue_Empty(void) +{ + return list_is_empty(&hciReadPktRxQueue); +} + +/** + * When an interrupt is raised by BlueNRG, + * just signal that a new event (availability of SPI data to be read) + * needs to be processed. + */ +void HCI_Isr(void) +{ + signalEventsToProcess(); +} + +/** + * Now, SPI Data are handled in user space. + * In case it has to be called in ISR, take care to + * call Disable_SPI_IRQ/Enable_SPI_IRQ in a proper way. + * The calls Disable_SPI_IRQ/Enable_SPI_IRQ have not been removed + * from this code for backward compatibility. + */ +void HCI_HandleSPI(void) +{ + tHciDataPacket * hciReadPacket = NULL; + uint8_t data_len; + + Clear_SPI_EXTI_Flag(); + while(BlueNRG_DataPresent()){ + if (list_is_empty (&hciReadPktPool) == FALSE){ + + /* enqueueing a packet for read */ + list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool--; + if(nr_hciReadPktPool < lowest_nr_hciReadPktPool) + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif + + data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); + if(data_len > 0){ + hciReadPacket->data_len = data_len; + if(HCI_verify(hciReadPacket) == 0) { + list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); + } else { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else { + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else{ + // HCI Read Packet Pool is empty, wait for a free packet. + Clear_SPI_EXTI_Flag(); + return; + } + + Clear_SPI_EXTI_Flag(); + } +} + +void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){ +#if HCI_LOG_ON + PRINTF("HCI <- "); + for(int i=0; i < n_bytes1; i++) + PRINTF("%02X ", *((uint8_t*)data1 + i)); + for(int i=0; i < n_bytes2; i++) + PRINTF("%02X ", *((uint8_t*)data2 + i)); + PRINTF("\n"); +#endif + + Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); +} + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) +{ + hci_command_hdr hc; + + hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); + hc.plen= plen; + + uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; + header[0] = HCI_COMMAND_PKT; + Osal_MemCpy(header+1, &hc, sizeof(hc)); + + hci_write(header, param, sizeof(header), plen); +} + +static void move_list(tListNode * dest_list, tListNode * src_list) +{ + pListNode tmp_node; + + while(!list_is_empty(src_list)){ + list_remove_tail(src_list, &tmp_node); + list_insert_head(dest_list, tmp_node); + } +} + + /* It ensures that we have at least half of the free buffers in the pool. */ +static void free_event_list(void) +{ + tHciDataPacket * pckt; + + Disable_SPI_IRQ(); + + while(list_get_size(&hciReadPktPool) < HCI_READ_PACKET_NUM_MAX/2){ + list_remove_head(&hciReadPktRxQueue, (tListNode **)&pckt); + list_insert_tail(&hciReadPktPool, (tListNode *)pckt); + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG */ + HCI_HandleSPI(); + } + + Enable_SPI_IRQ(); +} + +int hci_send_req(struct hci_request *r, BOOL async) +{ + uint8_t *ptr; + uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + hci_event_pckt *event_pckt; + hci_uart_pckt *hci_hdr; + int to = DEFAULT_TIMEOUT; + struct timer t; + tHciDataPacket * hciReadPacket = NULL; + tListNode hciTempQueue; + + list_init_head(&hciTempQueue); + + free_event_list(); + + hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); + + if(async){ + return 0; + } + + /* Minimum timeout is 1. */ + if(to == 0) + to = 1; + + Timer_Set(&t, to); + + while(1) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + evt_le_meta_event *me; + int len; + + while(1){ + + Disable_SPI_IRQ(); + HCI_HandleSPI(); + Enable_SPI_IRQ(); + + if(Timer_Expired(&t)){ + goto failed; + } + if(!HCI_Queue_Empty()){ + break; + } + } + + /* Extract packet from HCI event queue. */ + Disable_SPI_IRQ(); + list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + + hci_hdr = (void *)hciReadPacket->dataBuff; + + if(hci_hdr->type == HCI_EVENT_PKT){ + + event_pckt = (void *) (hci_hdr->data); + + ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); + len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); + + switch (event_pckt->evt) { + + case EVT_CMD_STATUS: + cs = (void *) ptr; + + if (cs->opcode != opcode) + goto failed; + + if (r->event != EVT_CMD_STATUS) { + if (cs->status) { + goto failed; + } + break; + } + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_CMD_COMPLETE: + cc = (void *) ptr; + + if (cc->opcode != opcode) + goto failed; + + ptr += EVT_CMD_COMPLETE_SIZE; + len -= EVT_CMD_COMPLETE_SIZE; + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_LE_META_EVENT: + me = (void *) ptr; + + if (me->subevent != r->event) + break; + + len -= 1; + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, me->data, r->rlen); + goto done; + + case EVT_HARDWARE_ERROR: + goto failed; + + default: + break; + } + } + + /* If there are no more packets to be processed, be sure there is at list one + packet in the pool to process the expected event. + If no free packets are available, discard the processed event and insert it + into the pool. */ + if(list_is_empty(&hciReadPktPool) && list_is_empty(&hciReadPktRxQueue)){ + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); + hciReadPacket=NULL; + } + else { + /* Insert the packet in a different queue. These packets will be + inserted back in the main queue just before exiting from send_req(), so that + these events can be processed by the application. + */ + list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); + hciReadPacket = NULL; + } + + HCI_HandleSPI(); + + Enable_SPI_IRQ(); + + } + +failed: + if(hciReadPacket != NULL) { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + move_list(&hciReadPktRxQueue, &hciTempQueue); + Enable_SPI_IRQ(); + return -1; + +done: + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + move_list(&hciReadPktRxQueue, &hciTempQueue); + + Enable_SPI_IRQ(); + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,837 @@ +/** + ****************************************************************************** + * @file ble_hci_le.c + * @author AMG RF Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +int hci_reset(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_RESET; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_disconnect(uint16_t handle, uint8_t reason) +{ + struct hci_request rq; + disconnect_cp cp; + uint8_t status; + + cp.handle = handle; + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) +{ + struct hci_request rq; + read_local_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + + *hci_version = resp.hci_version; + *hci_revision = btohs(resp.hci_revision); + *lmp_pal_version = resp.lmp_pal_version; + *manufacturer_name = btohs(resp.manufacturer_name); + *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); + + return 0; +} + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) +{ + struct hci_request rq; + le_read_buffer_size_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_BUFFER_SIZE; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *pkt_len = resp.pkt_len; + *max_pkt = resp.max_pkt; + + return 0; +} + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter) +{ + struct hci_request rq; + le_set_adv_parameters_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.min_interval = min_interval; + adv_cp.max_interval = max_interval; + adv_cp.advtype = advtype; + adv_cp.own_bdaddr_type = own_bdaddr_type; + adv_cp.direct_bdaddr_type = direct_bdaddr_type; + if(direct_bdaddr != NULL) + Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); + adv_cp.chan_map = chan_map; + adv_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_PARAMETERS; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_adv_data_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.length = length; + Osal_MemCpy(adv_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_DATA; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertise_enable(uint8_t enable) +{ + struct hci_request rq; + le_set_advertise_enable_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.enable = enable?1:0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter) +{ + struct hci_request rq; + le_set_scan_parameters_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.type = type; + scan_cp.interval = interval; + scan_cp.window = window; + scan_cp.own_bdaddr_type = own_bdaddr_type; + scan_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) +{ + struct hci_request rq; + le_set_scan_enable_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.enable = enable?1:0; + scan_cp.filter_dup = filter_dup; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_ENABLE; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_rand(uint8_t random_number[8]) +{ + struct hci_request rq; + le_rand_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_RAND; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + Osal_MemCpy(random_number, resp.random, 8); + + return 0; +} + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_scan_response_data_cp scan_resp_cp; + uint8_t status; + + Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); + scan_resp_cp.length = length; + Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; + rq.cparam = &scan_resp_cp; + rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) +{ + struct hci_request rq; + le_read_adv_channel_tx_power_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *tx_power_level = resp.level; + + return 0; +} + +int hci_le_set_random_address(tBDAddr bdaddr) +{ + struct hci_request rq; + le_set_random_address_cp set_rand_addr_cp; + uint8_t status; + + Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); + Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; + rq.cparam = &set_rand_addr_cp; + rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_read_bd_addr(tBDAddr bdaddr) +{ + struct hci_request rq; + read_bd_addr_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_BD_ADDR; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_BD_ADDR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); + + return 0; +} + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) +{ + struct hci_request rq; + le_create_connection_cp create_cp; + uint8_t status; + + Osal_MemSet(&create_cp, 0, sizeof(create_cp)); + create_cp.interval = interval; + create_cp.window = window; + create_cp.initiator_filter = initiator_filter; + create_cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); + create_cp.own_bdaddr_type = own_bdaddr_type; + create_cp.min_interval=min_interval; + create_cp.max_interval=max_interval; + create_cp.latency = latency; + create_cp.supervision_timeout=supervision_timeout; + create_cp.min_ce_length=min_ce_length; + create_cp.max_ce_length=max_ce_length; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN; + rq.cparam = &create_cp; + rq.clen = LE_CREATE_CONN_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_create_connection_cancel(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN_CANCEL; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) +{ + struct hci_request rq; + le_encrypt_cp params; + le_encrypt_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemCpy(params.key, key, 16); + Osal_MemCpy(params.plaintext, plaintextData, 16); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ENCRYPT; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + le_ltk_neg_reply_cp params; + le_ltk_neg_reply_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + params.handle = 1; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_LTK_NEG_REPLY; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CLEAR_WHITE_LIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0){ + return BLE_STATUS_TIMEOUT; + } + + return status; +} + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) +{ + struct hci_request rq; + le_add_device_to_white_list_cp params; + uint8_t status; + + params.bdaddr_type = bdaddr_type; + Osal_MemCpy(params.bdaddr, bdaddr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; + rq.cparam = ¶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/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1309 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB05A1 cp; + gap_init_rp resp; + + cp.role = role; + cp.privacy_enabled = privacy_enabled; + cp.device_name_char_len = device_name_char_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} +tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB04A1 cp; + gap_init_rp resp; + + cp.role = role; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + SlaveConnIntervMin = htobs(SlaveConnIntervMin); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + SlaveConnIntervMax = htobs(SlaveConnIntervMax); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB05A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.directed_adv_type = directed_adv_type; + cp.adv_interv_min = adv_interv_min; + cp.adv_interv_max = adv_interv_max; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB04A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_io_capability(uint8_t io_capability) +{ + struct hci_request rq; + uint8_t status; + gap_set_io_capability_cp cp; + + cp.io_capability = io_capability; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_IO_CAPABILITY; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode) +{ + struct hci_request rq; + gap_set_auth_requirement_cp cp; + uint8_t status; + + cp.mitm_mode = mitm_mode; + cp.oob_enable = oob_enable; + Osal_MemCpy(cp.oob_data, oob_data, 16); + cp.min_encryption_key_size = min_encryption_key_size; + cp.max_encryption_key_size = max_encryption_key_size; + cp.use_fixed_pin = use_fixed_pin; + cp.fixed_pin = htobl(fixed_pin); + cp.bonding_mode = bonding_mode; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) +{ + struct hci_request rq; + gap_set_author_requirement_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorization_enable = authorization_enable; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) +{ + struct hci_request rq; + gap_passkey_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.passkey = htobl(passkey); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_PASSKEY_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) +{ + struct hci_request rq; + gap_authorization_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorize = authorize; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB05A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + cp.own_address_type = own_address_type; + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB04A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) +{ + struct hci_request rq; + gap_set_undirected_connectable_cp cp; + uint8_t status; + + cp.own_addr_type = own_addr_type; + cp.adv_filter_policy = adv_filter_policy; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) +{ + struct hci_request rq; + gap_slave_security_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.bonding = bonding; + cp.mitm_protection = mitm_protection; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[32]; + uint8_t indx = 0; + + if (AdvLen > (sizeof(buffer)-1)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvLen; + indx++; + + Osal_MemCpy(buffer + indx, AdvData, AdvLen); + indx += AdvLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_UPDATE_ADV_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) +{ + struct hci_request rq; + gap_delete_ad_type_cp cp; + uint8_t status; + + cp.ad_type = ad_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_DELETE_AD_TYPE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required) +{ + struct hci_request rq; + gap_get_security_level_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; + rq.rparam = &resp; + rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *mitm_protection = resp.mitm_protection; + *bonding = resp.bonding; + *oob_data = resp.oob_data; + *passkey_required = resp.passkey_required; + + return resp.status; +} + +tBleStatus aci_gap_configure_whitelist(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) +{ + struct hci_request rq; + gap_terminate_cp cp; + uint8_t status; + + cp.handle = htobs(conn_handle); + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_clear_security_database(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) +{ + struct hci_request rq; + gap_allow_rebond_cp_IDB05A1 cp; + uint8_t status; + + cp.conn_handle = conn_handle; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_allow_rebond_IDB04A1(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_limited_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_general_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_name_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = use_reconn_addr; + indx++; + + Osal_MemCpy(buffer + indx, reconn_addr, 6); + indx += 6; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB05A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB04A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.use_reconn_addr = use_reconn_addr; + Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_start_selective_conn_establish_proc_cp cp; + uint8_t status; + + if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.num_whitelist_entries = num_whitelist_entries; + + Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_create_connection_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CREATE_CONNECTION; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; + rq.cparam = &procedure_code; + rq.clen = 1; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_connection_update_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) +{ + struct hci_request rq; + gap_send_pairing_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.force_rebond = force_rebond; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + gap_resolve_private_address_rp rp; + + Osal_MemCpy(cp.address, private_address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); + + return 0; +} +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + uint8_t status; + + Osal_MemCpy(cp.address, address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_set_broadcast_mode_cp cp; + uint8_t status; + uint8_t indx = 0; + uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; + + if (variable_size > sizeof(cp.var_len_data) ) + return BLE_STATUS_INVALID_PARAMS; + + cp.adv_interv_min = htobs(adv_interv_min); + cp.adv_interv_max = htobs(adv_interv_max); + cp.adv_type = adv_type; + cp.own_addr_type = own_addr_type; + + cp.var_len_data[indx] = adv_data_length; + indx++; + Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); + indx += adv_data_length; + cp.var_len_data[indx] = num_whitelist_entries; + indx ++; + Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_BROADCAST_MODE; + rq.cparam = &cp; + rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_observation_proc_cp cp; + uint8_t status; + + cp.scan_interval = scan_interval; + cp.scan_window = scan_window; + cp.scan_type = scan_type; + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_OBSERVATION_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) +{ + struct hci_request rq; + gap_is_device_bonded_cp cp; + uint8_t status; + + cp.peer_address_type = peer_address_type; + Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_IS_DEVICE_BONDED; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) +{ + struct hci_request rq; + gap_get_bonded_devices_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_BONDED_DEVICES; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (rp.status) { + return rp.status; + } + + *num_devices = rp.num_addr; + if(device_list != NULL) + Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1505 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.c +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : File with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_gatt_init(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INIT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[19]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, service_uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = service_type; + indx++; + + buffer[indx] = max_attr_records; + indx++; + + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle) +{ + struct hci_request rq; + gatt_include_serv_rp resp; + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + service_handle = htobs(service_handle); + Osal_MemCpy(buffer, &service_handle, 2); + indx += 2; + + included_start_handle = htobs(included_start_handle); + Osal_MemCpy(buffer+indx, &included_start_handle, 2); + indx += 2; + + included_end_handle = htobs(included_end_handle); + Osal_MemCpy(buffer+indx, &included_end_handle, 2); + indx += 2; + + if(included_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } else { + uuid_len = 16; + } + + buffer[indx] = included_uuid_type; + indx++; + + Osal_MemCpy(buffer + indx, included_uuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INCLUDE_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *included_handle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[25]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + buffer[indx] = charValueLen; + indx++; + + buffer[indx] = charProperties; + indx++; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *charHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle) +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = descValueMaxLen; + indx++; + + buffer[indx] = descValueLen; + indx++; + + if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + Osal_MemCpy(buffer + indx, descValue, descValueLen); + indx += descValueLen; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = accPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR_DESC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *descHandle = btohs(resp.handle); + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = charValOffset; + indx++; + + buffer[indx] = charValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charValue, charValueLen); + indx += charValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_char_cp cp; + + cp.service_handle = htobs(servHandle); + cp.char_handle = htobs(charHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_CHAR; + rq.cparam = &cp; + rq.clen = GATT_DEL_CHAR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_service(uint16_t servHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_serv_cp cp; + + cp.service_handle = htobs(servHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_inc_serv_cp cp; + + cp.service_handle = htobs(servHandle); + cp.inc_serv_handle = htobs(includeServHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_INC_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_INC_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) +{ + struct hci_request rq; + uint8_t status; + gatt_set_evt_mask_cp cp; + + cp.evt_mask = htobs(event_mask); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_EVT_MASK; + rq.cparam = &cp; + rq.clen = GATT_SET_EVT_MASK_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_exchange_config_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_EXCHANGE_CONFIG; + rq.cparam = &cp; + rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) +{ + struct hci_request rq; + uint8_t status; + att_find_info_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_INFO_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_find_by_type_value_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + Osal_MemCpy(cp.uuid, uuid, 2); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_group_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_prepare_write_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.value_offset = htobs(value_offset); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) +{ + struct hci_request rq; + uint8_t status; + att_execute_write_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.execute = execute; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_prim_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_prim_service_by_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; + rq.cparam = &cp; + rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, + uint16_t end_service_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_find_included_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_service_handle); + cp.end_handle = htobs(end_service_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_of_serv_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_attr_handle = htobs(start_attr_handle); + cp.end_attr_handle = htobs(end_attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t charUuidType, + const uint8_t* charUuid) +{ + struct hci_request rq; + uint8_t status; + + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + start_handle = htobs(start_handle); + Osal_MemCpy(buffer + indx, &start_handle, 2); + indx += 2; + + end_handle = htobs(end_handle); + Osal_MemCpy(buffer + indx, &end_handle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == 0x01){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_descriptors_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.char_val_handle = htobs(char_val_handle); + cp.char_end_handle = htobs(char_end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_read_using_charac_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; + rq.cparam = &cp; + rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles) +{ + struct hci_request rq; + uint8_t status; + gatt_read_multiple_charac_val_cp cp; + + if(num_handles*2 > sizeof(cp.set_of_handles)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.num_handles = htobs(num_handles); + Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_long_charac_val_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; + rq.cparam = &cp; + rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_signed_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_confirm_indication_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_CONFIRM_INDICATION; + rq.cparam = &cp; + rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = write_status; + indx += 1; + + buffer[indx] = err_code; + indx += 1; + + buffer[indx] = att_val_len; + indx += 1; + + Osal_MemCpy(buffer + indx, att_val, att_val_len); + indx += att_val_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(uint16_t conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ALLOW_READ; + rq.cparam = &cp; + rq.clen = GATT_ALLOW_READ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission) +{ + struct hci_request rq; + gatt_set_security_permission_cp cp; + uint8_t status; + + cp.service_handle = htobs(service_handle); + cp.attr_handle = htobs(attr_handle); + cp.security_permission = security_permission; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; + rq.cparam = &cp; + rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + charDescHandle = htobs(charDescHandle); + Osal_MemCpy(buffer + indx, &charDescHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charDescValOffset, 2); + indx += 2; + + buffer[indx] = charDescValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); + indx += charDescValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_DESC_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_cp cp; + gatt_read_handle_val_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = btohs(rp.value_len); + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_offset_cp cp; + gatt_read_handle_val_offset_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rp.value_len; + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value) +{ + struct hci_request rq; + uint8_t status; + gatt_upd_char_val_ext_cp cp; + + if(value_length > sizeof(cp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.service_handle = htobs(service_handle); + cp.char_handle = htobs(char_handle); + cp.update_type = update_type; + cp.char_length = htobs(char_length); + cp.value_offset = htobs(value_offset); + cp.value_length = value_length; + Osal_MemCpy(cp.value, value, value_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL_EXT; + rq.cparam = &cp; + rq.clen = GATT_UPD_CHAR_VAL_EXT_CP_SIZE + value_length; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,266 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number) +{ + struct hci_request rq; + hal_get_fw_build_number_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_FW_BUILD_NUMBER; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *build_number = rp.build_number; + + return 0; +} + +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((len+2) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = offset; + indx++; + + buffer[indx] = len; + indx++; + + Osal_MemCpy(buffer + indx, val, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + hal_read_config_data_cp cp; + hal_read_config_data_rp rp; + + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_READ_CONFIG_DATA; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rq.rlen-1; + + Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) +{ + struct hci_request rq; + hal_set_tx_power_level_cp cp; + uint8_t status; + + cp.en_high_power = en_high_power; + cp.pa_level = pa_level; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets) +{ + struct hci_request rq; + hal_le_tx_test_packet_number_rp resp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_LE_TX_TEST_PACKET_NUMBER; + rq.rparam = &resp; + rq.rlen = sizeof(resp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *number_of_packets = btohl(resp.number_of_packets); + + return 0; +} + +tBleStatus aci_hal_device_standby(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_DEVICE_STANDBY; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_start(uint8_t rf_channel) +{ + struct hci_request rq; + hal_tone_start_cp cp; + uint8_t status; + + cp.rf_channel = rf_channel; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_START; + rq.cparam = &cp; + rq.clen = HAL_TONE_START_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_stop(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_STOP; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]) +{ + struct hci_request rq; + hal_get_link_status_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_LINK_STATUS; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(link_status,rp.link_status,sizeof(link_status)); + for(int i = 0; i < 8; i++) + conn_handle[i] = btohs(rp.conn_handle[i]); + + return 0; +} + +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot) +{ + struct hci_request rq; + hal_get_anchor_period_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_ANCHOR_PERIOD; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *anchor_period = btohl(rp.anchor_period); + *max_free_slot = btohl(rp.max_free_slot); + + return 0; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,117 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB05A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.min_ce_length = htobs(min_ce_length); + cp.max_ce_length = htobs(max_ce_length); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB04A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,269 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_updater_aci.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_updater_reboot(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_get_updater_version(uint8_t *version) +{ + struct hci_request rq; + get_updater_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_VERSION; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) +{ + struct hci_request rq; + get_updater_bufsize_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_BUFSIZE; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_reset_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = htobl(address); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_SECTOR; + rq.cparam = &cp; + rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_program_data_block(uint32_t address, + uint16_t len, + const uint8_t *data) +{ + struct hci_request rq; + uint8_t status; + updater_prog_data_block_cp cp; + + if( len > sizeof(cp.data)) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(len); + Osal_MemCpy(cp.data, data, len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_read_data_block(uint32_t address, + uint16_t data_len, + uint8_t *data) +{ + struct hci_request rq; + updater_read_data_block_cp cp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + + if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(data_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; + rq.rparam = buffer; + rq.rlen = data_len + 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + // First byte is status + Osal_MemCpy(data, buffer+1, data_len); + + return buffer[0]; +} + +tBleStatus aci_updater_calc_crc(uint32_t address, + uint8_t num_sectors, + uint32_t *crc) +{ + struct hci_request rq; + updater_calc_crc_cp cp; + updater_calc_crc_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + cp.address = htobl(address); + cp.num_sectors = num_sectors; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_CALC_CRC; + rq.cparam = &cp; + rq.clen = UPDATER_CALC_CRC_CP_SIZE; + rq.rparam = &resp; + rq.rlen = UPDATER_CALC_CRC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *crc = btohl(resp.crc); + + return resp.status; +} + +tBleStatus aci_updater_hw_version(uint8_t *version) +{ + struct hci_request rq; + updater_hw_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_HW_VERSION; + rq.rparam = &resp; + rq.rlen = UPDATER_HW_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,423 @@ + +#include "ble_hal.h" +#include "ble_hal_types.h" +#include "ble_status.h" +#include "bluenrg_aci.h" +#include "bluenrg_utils.h" +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "ble_osal.h" +#include "string.h" +#include "stm32_bluenrg_ble.h" + +#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 +#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 + +#define BASE_ADDRESS 0x10010000 + +#define FW_OFFSET (2*1024) // 2 KB +#define FW_OFFSET_MS 0 +#define FULL_STACK_SIZE (66*1024) // 66 KB +#define BOOTLOADER_SIZE (2*1024) // 2 kB +#define SECTOR_SIZE (2*1024) // 2 KB + +// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + +// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 +#define CRC_POLY 0x04C11DB7 // the poly without the x**32 + +#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC + +#define IFR_SIZE 192 +#define IFR_BASE_ADDRESS 0x10020000 +#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data + +#if BLUENRG_MS +#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET +#else +#define IFR_WRITE_OFFSET_BEGIN 0 +#endif + + +#define BLUE_FLAG_OFFSET 0x8C0 +#define MAX_ERASE_RETRIES 2 +#define MAX_WRITE_RETRIES 2 +#define MIN_WRITE_BLOCK_SIZE 4 +#define MAX_WRITE_BLOCK_SIZE 64 // 64 bytes +#define READ_BLOCK_SIZE 64 // 64 bytes + +#define RETRY_COMMAND(func, num_ret, error) \ +{ \ + uint8_t num_retries; \ + num_retries = 0; \ + error = 0; \ + while (num_retries++ < num_ret) { \ + if (func == BLE_STATUS_SUCCESS) \ + break; \ + if (num_retries == num_ret) \ + error = BLE_UTIL_ACI_ERROR; \ + } \ +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, + they are extended with 0xFF until sector size is reached +*/ +static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) +{ + uint32_t i, j, a1; + uint32_t crc, value; + + crc = 0; + for (i = 0; i < SECTOR_SIZE; i += 4) { + uint8_t *dataw = (uint8_t *) &value; + + dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; + dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; + dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; + dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; + + crc = crc ^ value; + for (j = 0; j < 32; j ++) { + a1 = (crc >> 31) & 0x1; + crc = (crc << 1) ^ (a1 * CRC_POLY); + } + } + + return crc; +} + +int program_device(const uint8_t *fw_image, uint32_t fw_size) +{ + uint8_t version, num_erase_retries, status, write_block_size; + uint32_t address; + uint32_t crc, crc2, crc_size; + uint32_t fw_offset = FW_OFFSET; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + if(aci_updater_hw_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version==0x31){ + // It does not contain bootloader inside first sector. It may contain code. + fw_offset = FW_OFFSET_MS; + } + + if (fw_size != FULL_STACK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + if (fw_size % MIN_WRITE_BLOCK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + + /*********************************************************************** + * Erase BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + /*********************************************************************** + * Erase and Program sectors + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE) { + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(BASE_ADDRESS + i); + for (int j=i; ((j<i+SECTOR_SIZE)&&(j<fw_size)); j += write_block_size) { + + write_block_size = MIN(fw_size-j, MAX_WRITE_BLOCK_SIZE); + + RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, write_block_size, fw_image+j), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + break; + } + if (status == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + } + + /*********************************************************************** + * Verify firmware + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE){ + address = BASE_ADDRESS + i; + if(aci_updater_calc_crc(address, 1, &crc)) + return BLE_UTIL_ACI_ERROR; + + crc_size = MIN(fw_size-i,SECTOR_SIZE); + + crc2 = updater_calc_crc(fw_image+i,crc_size); + if(crc!=crc2) + return BLE_UTIL_CRC_ERROR; + } + + /*********************************************************************** + * Write BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +int read_IFR(uint8_t *data) +{ + uint8_t version, offset; + tBleStatus ret; + + offset = 0; + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + /*********************************************************************** + * Reading last 3 IFR 64-byte blocks + ************************************************************************/ + for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(BASE_ADDRESS+i, READ_BLOCK_SIZE, (data+offset)); + offset += READ_BLOCK_SIZE; + if(ret) return BLE_UTIL_ACI_ERROR; + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; + +} + +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) +{ + IFR_config->stack_mode = data[0]; + IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); + IFR_config->master_sca = data[30]; + IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); + IFR_config->year = BCD_TO_INT(data[41]); + IFR_config->month = BCD_TO_INT(data[42]); + IFR_config->day = BCD_TO_INT(data[43]); +} + +int IFR_validate(IFR_config2_TypeDef *IFR_config) +{ +#if BLUENRG_MS + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) +#else + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) +#endif + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode + if(IFR_config->master_sca > 7) + return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->day > 31 || IFR_config->day < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + + return BLE_STATUS_SUCCESS; +} + +/* TODO: Function to generate data from given options. */ + +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) +{ + data[0] = IFR_config->stack_mode; + HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); + data[30] = IFR_config->master_sca; + HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); + data[41] = INT_TO_BCD(IFR_config->year); + data[42] = INT_TO_BCD(IFR_config->month); + data[43] = INT_TO_BCD(IFR_config->day); +} + + +int program_IFR(const IFR_config_TypeDef *ifr_image) +{ + uint8_t version, num_erase_retries; + tBleStatus ret; +#if BLUENRG_MS + const uint8_t *ifr_data = (uint8_t *)ifr_image; +#else + uint8_t ifr_data[SECTOR_SIZE]; +#endif + uint8_t hwVersion; + uint16_t fwVersion; + + if(getBlueNRGVersion(&hwVersion, &fwVersion)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + +#ifndef BLUENRG_MS + /*********************************************************************** + * READ IFR data + ************************************************************************/ + for(int i = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_data+i); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + } +#endif + + /*********************************************************************** + * Erase & Flashing IFR sectors + ************************************************************************/ +#ifndef BLUENRG_MS + Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); +#endif + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(IFR_BASE_ADDRESS); + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += MAX_WRITE_BLOCK_SIZE, j += MAX_WRITE_BLOCK_SIZE) { + RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, MAX_WRITE_BLOCK_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); + if (ret != BLE_STATUS_SUCCESS) + break; + } + if (ret == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + + /*********************************************************************** + * Verify IFR + ************************************************************************/ + { + uint8_t ifr_updated[READ_BLOCK_SIZE]; + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE, j += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ifr_data+j, READ_BLOCK_SIZE) != 0) + return BLE_UTIL_WRONG_VERIFY; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) +{ + uint8_t ifr_updated[READ_BLOCK_SIZE]; + uint8_t version, ret = BLE_STATUS_SUCCESS; + + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + for(int i = 0; i < IFR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, READ_BLOCK_SIZE) != 0) + { + ret = BLE_UTIL_WRONG_VERIFY; + break; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return ret; +} + +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) +{ + uint8_t status; + uint8_t hci_version, lmp_pal_version; + uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; + + status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, + &manufacturer_name, &lmp_pal_subversion); + + if (status == BLE_STATUS_SUCCESS) { + *hwVersion = hci_revision >> 8; + *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number + *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number + *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number + } + + return status; +} + +uint8_t getBlueNRGUpdaterVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(version)) + return BLE_UTIL_ACI_ERROR; + + if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_updater_hw_version(version)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t isHWBootloader_Patched(void) +{ + uint8_t status, version; + uint32_t crc, address = 0x10010000; + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); + if (status != BLE_STATUS_SUCCESS) + return 0; + + if (crc == BOOTLOADER_CRC_NOT_PATCHED) + return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +#include "ble_gp_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function sets a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * @param[in] t A pointer to the timer + * @param[in] interval The interval before the timer expires. + * + */ +void +Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +Timer_Expired(struct timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + tClockTime diff = (Clock_Time() - t->start) + 1; + return t->interval < diff; + +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +tClockTime +Timer_Remaining(struct timer *t) +{ + return t->start + t->interval - Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +#ifdef __DMA_LP__ + +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID) +{ + TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, + (pf_TIMER_TimerCallBack_t) timercb); + TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); + + return (BLE_STATUS_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) +{ + TIMER_Delete(timerID); + + return (BLE_STATUS_SUCCESS); +} + +#endif /* __DMA_LP__ */ +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,119 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Circular Linked List Implementation. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/****************************************************************************** + * Include Files +******************************************************************************/ +#include <ble_hal_types.h> +#include "ble_list.h" + +/****************************************************************************** + * Function Definitions +******************************************************************************/ +void list_init_head (tListNode * listHead) +{ + listHead->next = listHead; + listHead->prev = listHead; +} + +uint8_t list_is_empty (tListNode * listHead) +{ + return ((listHead->next == listHead)? TRUE:FALSE); +} + +void list_insert_head (tListNode * listHead, tListNode * node) +{ + node->next = listHead->next; + node->prev = listHead; + listHead->next = node; + (node->next)->prev = node; +} + + +void list_insert_tail (tListNode * listHead, tListNode * node) +{ + node->next = listHead; + node->prev = listHead->prev; + listHead->prev = node; + (node->prev)->next = node; +} + + +void list_remove_node (tListNode * node) +{ + (node->prev)->next = node->next; + (node->next)->prev = node->prev; +} + + +void list_remove_head (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->next; + list_remove_node (listHead->next); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_remove_tail (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->prev; + list_remove_node (listHead->prev); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_insert_node_after (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node->next; + node->prev = ref_node; + ref_node->next = node; + (node->next)->prev = node; +} + + +void list_insert_node_before (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node; + node->prev = ref_node->prev; + ref_node->prev = node; + (node->prev)->next = node; +} + + +int list_get_size (tListNode * listHead) +{ + int size = 0; + tListNode * temp = listHead->next; + while (temp != listHead) + { + size++; + temp = temp->next; + } + return (size); +} + +void list_get_next_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->next; +} + + +void list_get_prev_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->prev; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,72 @@ +/** +****************************************************************************** +* @file ble_osal.c +* @author AMS - HEA&RF BU / CL +* @version V1.0.0 +* @date 04-July-2014 +* @brief Implementation of OS abstraction layer functions used by the +* library. +****************************************************************************** +* @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> +#include <ble_osal.h> + + /** + * @brief Osal_MemCpy + * @param dest: Pointer to the destination buffer + * @param src : Pointer to the source buffer + * @param size: Number of bytes to copy from the source to the destination + * buffer + * @retval Pointer to the destination buffer + */ +void* Osal_MemCpy(void *dest, const void *src, unsigned int size) +{ + return(memcpy(dest,src,size)); +} + +/** + * @brief Osal_MemSet + * @param ptr : Pointer to block of memory to fill + * @param value: Value to assign to each byte of the memory block + * @param size : Number of bytes to be set to "value" + * @retval Pointer to the filled block of memory + */ +void* Osal_MemSet(void *ptr, int value, unsigned int size) +{ + return(memset(ptr,value,size)); +} + +/****************************************************************************** + * local Functions + *****************************************************************************/ + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ + +#include "ble_clock.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/wait_api.h" + #include "mbed-drivers/rtc_time.h" +#else + #include "wait_api.h" + #include "rtc_time.h" +#endif + +const uint32_t CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + //Not Used +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return clock(); +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,715 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file btle.cpp + * @author STMicroelectronics + * @brief Implementation BlueNRG Init and helper functions. + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + + +#include "btle.h" +#include "ble/Gap.h" +#include "ble/GapEvents.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" + +#include "bluenrg_targets.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* C File Includes ------------------------------------------------------------------*/ +#include <stdio.h> +#include <string.h> +#include "ble_hci.h" +#include "ble_hci_const.h" +#include "bluenrg_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" +#include "bluenrg_utils.h" + +#include "ble_hal_types.h" +#include "ble_hal.h" +#include "ble_gp_timer.h" +#include "ble_osal.h" +#include "ble_sm.h" +#include "ble_debug.h" + +#ifdef __cplusplus +} +#endif + +#define IDB04A1 0 +#define IDB05A1 1 + +/* See file 'bluenrg_targets.h' for details regarding the BLUENRG_STACK_MODE */ +#define STACK_MODE BLUENRG_STACK_MODE + +void HCI_Input(tHciDataPacket * hciReadPacket); + +uint16_t g_gap_service_handle = 0; +uint16_t g_appearance_char_handle = 0; +uint16_t g_device_name_char_handle = 0; +uint16_t g_preferred_connection_parameters_char_handle = 0; + +/* Private variables ---------------------------------------------------------*/ +volatile uint8_t set_connectable = 1; + +static char versionString[32]; +uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ + +/**************************************************************************/ +/*! + @brief Init the BTLE stack with the specified role + @returns void +*/ +/**************************************************************************/ +void btleInit(void) +{ + PRINTF("btleInit>>\n\r"); + + int ret; + uint8_t hwVersion; + uint16_t fwVersion; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* get the BlueNRG HW and FW versions */ + getBlueNRGVersion(&hwVersion, &fwVersion); + + /* + * Reset BlueNRG again otherwise we won't + * be able to change its MAC address. + * aci_hal_write_config_data() must be the first + * command after reset otherwise it will fail. + */ + BlueNRG_RST(); + + if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ + bnrg_expansion_board = IDB05A1; + } + + /* set BLE version string */ + setVersionString(hwVersion, fwVersion); + + if (bnrg_expansion_board == IDB05A1) { + uint8_t stackMode = STACK_MODE; + ret = aci_hal_write_config_data(CONFIG_DATA_MODE_OFFSET, + CONFIG_DATA_MODE_LEN, + &stackMode); + } + + ret = aci_gatt_init(); + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GATT_Init failed.\n"); + } + if (bnrg_expansion_board == IDB05A1) { + ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1, + 0, + 0x18, + &service_handle, + &dev_name_char_handle, + &appearance_char_handle); + } else { + // IDB04A1 is configured as peripheral by default + ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + } + + // read the default static address and inject it into the GAP object + { + Gap::Address_t BLE_address_BE = { 0 }; + uint8_t data_len_out; + aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS, BDADDR_SIZE, &data_len_out, BLE_address_BE); + // FIXME error handling of this function + BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE); + } + + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GAP_Init failed.\n"); + } + + //FIXME: Security and passkey set by default + ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, + OOB_AUTH_DATA_ABSENT, + NULL, + 7, + 16, + USE_FIXED_PIN_FOR_PAIRING, + 123456, + BONDING); + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Auth Req set failed.\n"); + } + + aci_hal_set_tx_power_level(1,4); + + g_gap_service_handle = service_handle; + g_appearance_char_handle = appearance_char_handle; + g_device_name_char_handle = dev_name_char_handle; + //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API + /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, + strlen(name), (tHalUint8 *)name);*/ + + signalEventsToProcess(); + // update the peripheral preferred conenction parameters handle + // This value is hardcoded at the moment. + g_preferred_connection_parameters_char_handle = 10; + + return; +} + +/**************************************************************************/ +/*! + @brief mbedOS + + @param[in] void + + @returns +*/ +/**************************************************************************/ +int btle_handler_pending = 0; + +void btle_handler(void) +{ + btle_handler_pending = 0; + BlueNRGGap::getInstance().Process(); + HCI_HandleSPI(); + HCI_Process(); +} + +/* set BLE Version string */ +void setVersionString(uint8_t hwVersion, uint16_t fwVersion) +{ + if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) { + snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u", + hwVersion>>4, (hwVersion&0x0F), + fwVersion>>8, (fwVersion&0x00F0)>>4); + } else { + snprintf(versionString, sizeof(versionString), "ST (unknown spec)"); + } +} + +/* get BLE Version string */ +const char* getVersionString(void) +{ + return versionString; +} + +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type) +{ + tBleStatus ret; + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + if(bnrg_expansion_board == IDB05A1) { + PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window); + PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type); + ret = aci_gap_start_observation_procedure(scan_interval, + scan_window, + scan_type, + own_address_type, + 0); // 1 to filter duplicates + } else { + ret = BLE_STATUS_INVALID_CID; + } + + return ret; + +} + +/*! + @brief Not Used + + @param[in] void + + @returns +*/ +void SPI_Poll(void) +{ + //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); + return; +} + +void Attribute_Modified_CB(evt_blue_aci *blue_evt) +{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t *att_data; + uint8_t offset; + + if (bnrg_expansion_board == IDB05A1) { + evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = evt->offset; + } else { + evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = 0; + } + + //Extract the GattCharacteristic from p_characteristics[] and find the properties mask + GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle); + if(p_char!=NULL) { + GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE; + PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]); + PRINTF("getProperties 0x%x\n\r",p_char->getProperties()); + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; + } + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; + } + PRINTF("currentHandle %d\n\r", currentHandle); + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && + currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { + + GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1; + + PRINTF("*****NOTIFICATION CASE\n\r"); + //Now Check if data written in Enable or Disable + if((uint16_t)att_data[0]==1) { + //PRINTF("Notify ENABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle); + } else { + //PRINTF("Notify DISABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle); + } + return; + } + + //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) && + currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) { + + PRINTF("*****WRITE CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = p_char->getValueAttribute().getHandle(); + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle); + //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + BlueNRGGattServer::getInstance().write( + p_char->getValueAttribute().getHandle(), + (uint8_t*)att_data, + data_length, + false + ); + } + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } else { + PRINTF("*****WRITE DESCRIPTOR CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = attr_handle; + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } + } + +} + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************************/ + /*! + @brief Handle HCI Stack Event + + @param[in] pckt + Event Packet sent by the stack to be decoded + + @returns + */ + /**************************************************************************/ + extern void HCI_Event_CB(void *pckt) { + hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; + hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; + + if(hci_pckt->type != HCI_EVENT_PKT) + return; + + switch(event_pckt->evt){ + + case EVT_DISCONN_COMPLETE: + { + PRINTF("EVT_DISCONN_COMPLETE\n"); + + evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data; + + if(BlueNRGGap::getInstance().getGapRole() == Gap::CENTRAL) { + BlueNRGGattClient::getInstance().removeGattConnectionClient(evt->handle, evt->reason); + } + + BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason); + } + break; + + case EVT_LE_META_EVENT: + { + PRINTF("EVT_LE_META_EVENT\n"); + + evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; + + switch(evt->subevent){ + + case EVT_LE_CONN_COMPLETE: + { + PRINTF("EVT_LE_CONN_COMPLETE\n"); + Gap::Address_t ownAddr; + Gap::AddressType_t ownAddrType; + BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr); + + Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + Gap::Role_t role; + + evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; + + BlueNRGGap::getInstance().setConnectionHandle(cc->handle); + BlueNRGGap::ConnectionParams_t connectionParams = { + /* minConnectionInterval = */ cc->interval, + /* maxConnectionInterval = */ cc->interval, + /* slaveLatency = */ cc->latency, + /* connectionSupervisionTimeout = */ cc->supervision_timeout + }; + + BlueNRGGap::getInstance().setConnectionInterval(cc->interval); + + switch (cc->peer_bdaddr_type) { + case PUBLIC_ADDR: + peerAddrType = BLEProtocol::AddressType::PUBLIC; + break; + case STATIC_RANDOM_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + break; + case RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE; + break; + case NON_RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE; + break; + } + //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role); + switch (cc->role) { + case 0: //master + role = Gap::CENTRAL; + BlueNRGGattClient::getInstance().createGattConnectionClient(cc->handle); + break; + case 1: + role = Gap::PERIPHERAL; + break; + default: + role = Gap::PERIPHERAL; + break; + } + + BlueNRGGap::getInstance().setGapRole(role); + + BlueNRGGap::getInstance().processConnectionEvent(cc->handle, + role, + peerAddrType, + cc->peer_bdaddr, + ownAddrType, + ownAddr, + &connectionParams); + } + break; + + case EVT_LE_ADVERTISING_REPORT: + PRINTF("EVT_LE_ADVERTISING_REPORT\n\r"); + /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */ + // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT) + // Formally the structure related to both events are identical except that for the ADV REPORT + // there is one more field (number of reports) which is not forwarded to upper layer. + // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT. + le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1); + PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + break; + } + } + break; + + case EVT_VENDOR: + { + evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; + //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode); + + switch(blue_evt->ecode){ + + case EVT_BLUE_GATT_WRITE_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_WRITE_PERMIT_REQ\r\n"); + evt_gatt_write_permit_req* write_req = (evt_gatt_write_permit_req*)blue_evt->data; + + // ask the local server if the write operation is authorized + uint8_t err_code = BlueNRGGattServer::getInstance().Write_Request_CB( + write_req->conn_handle, + write_req->attr_handle, + write_req->data_length, + write_req->data + ); + uint8_t write_status = err_code == 0 ? 0 : 1; + + // reply to the shield + aci_gatt_write_response( + write_req->conn_handle, + write_req->attr_handle, + write_status, + err_code, + write_req->data_length, + write_req->data + ); + } + break; + + case EVT_BLUE_GATT_READ_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r"); + evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle); + BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle); + } + break; + + case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: + { + PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r"); + /* this callback is invoked when a GATT attribute is modified + extract callback data and pass to suitable handler function */ + Attribute_Modified_CB(blue_evt); + } + break; + + //Any cases for Data Sent Notifications? + case EVT_BLUE_GATT_NOTIFICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_NOTIFICATION"); + break; + case EVT_BLUE_GATT_INDICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_INDICATION"); + break; + + case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r"); + evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_data_length, + pr->attribute_data_list); + } + break; + case EVT_BLUE_ATT_READ_BY_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r"); + evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle, + pr->event_data_length, + pr->handle_value_pair_length, + pr->handle_value_pair); + } + break; + case EVT_BLUE_ATT_READ_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_RESP\n\r"); + evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_value); + } + break; + case EVT_BLUE_ATT_EXEC_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle, + pr->event_data_length); + } + break; + case EVT_BLUE_ATT_PREPARE_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_handle, + pr->offset, + pr->part_attr_value); + } + break; + case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP: + { + PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r"); + evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle, + pr->event_data_length, + pr->attr_handle, + pr->attr_value); + } + break; + case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r"); + evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle, + pr->event_data_length, + pr->handles_info_list); + } + break; + case EVT_BLUE_ATT_FIND_INFORMATION_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r"); + evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle, + pr->event_data_length, + pr->format, + pr->handle_uuid_pair); + } + break; + case EVT_BLUE_GATT_PROCEDURE_COMPLETE: + { + evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code); + BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code); + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_REQ: + { + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_REQ\r\n"); + evt_l2cap_conn_upd_req *evt = (evt_l2cap_conn_upd_req*)blue_evt->data; + if(bnrg_expansion_board == IDB05A1) { + // we assume the application accepts the request from the slave + aci_l2cap_connection_parameter_update_response_IDB05A1(evt->conn_handle, + evt->interval_min, + evt->interval_max, + evt->slave_latency, + evt->timeout_mult, + CONN_L1, CONN_L2, + evt->identifier, + 0x0000); + } + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_RESP: + { + evt_l2cap_conn_upd_resp *evt = (evt_l2cap_conn_upd_resp*)blue_evt->data; + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_RESP code=0x%x, result=0x%x\r\n", evt->code, evt->result); + } + break; + + case EVT_LE_CONN_UPDATE_COMPLETE: + { + evt_le_connection_update_complete *evt = (evt_le_connection_update_complete*)blue_evt->data; + PRINTF("EVT_LE_CONN_UPDATE_COMPLETE status=0x%x\r\n", evt->status); + } + break; + + case EVT_BLUE_GAP_DEVICE_FOUND: + { + evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data; + PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + } + break; + + case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + { + evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data; + //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code); + + switch(pr->procedure_code) { + case GAP_OBSERVATION_PROC_IDB05A1: + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL); + break; + } + } + break; + } + } + break; + } + return ; + } + + +#ifdef __cplusplus +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,217 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.cpp + * @author CL + * @version V1.0.0 + * @date 15-June-2015 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRGGap.h" +#include "BlueNRGDevice.h" +#include "btle.h" + +// FIXME: find a better way to get the instance of the BlueNRG device +extern BlueNRGDevice bluenrgDeviceInstance; + + +//////////////////////////////////////// +// Start of C function wrappers +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32_bluenrg_ble.h" +#include "ble_debug.h" + + +void BlueNRG_RST(void) +{ + bluenrgDeviceInstance.reset(); +} + +uint8_t BlueNRG_DataPresent(void) +{ + return (bluenrgDeviceInstance.dataPresent()); +} + + +/** + * @brief This function is a utility to print the log time +* in the format HH:MM:SS:MSS (DK GUI time format) + * @param None + * @retval None + */ +void print_csv_time(void){ +#ifdef PRINT_CSV_FORMAT + uint32_t ms = 0;//ms_counter; + PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000); +#endif +} + +/** + * @brief Writes data to a serial interface. + * @param data1 : 1st buffer + * @param data2 : 2nd buffer + * @param n_bytes1: number of bytes in 1st buffer + * @param n_bytes2: number of bytes in 2nd buffer + * @retval None + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, + int32_t n_bytes2) +{ + struct timer t; + + Timer_Set(&t, CLOCK_SECOND/10); + +#ifdef PRINT_CSV_FORMAT + print_csv_time(); + for (int i=0; i<n_bytes1; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data1)[i]); + } + for (int i=0; i<n_bytes2; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data2)[i]); + } + PRINT_CSV("\n"); +#endif + + while(1){ + if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; + if(Timer_Expired(&t)){ + break; + } + } +} + + +/** + * @brief Activate internal bootloader using pin. + * @param None + * @retval None + */ +void BlueNRG_HW_Bootloader(void) +{ + // Reset BlueNRG SPI interface + BlueNRG_RST(); + + // Send an ACI command to reboot BlueNRG in bootloader mode + // The safest way to get in bootloader mode is keeping high + // the interrupt pin during reset, but this would require many + // changes to the current mbed driver + aci_updater_start(); +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size) +{ + int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size); + + return ret; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2); + + return ret; +} + +/** + * @brief Enable SPI IRQ. + * @param None + * @retval None + */ +void Enable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.enable_irq(); +} + +void signalEventsToProcess(void) { + if(btle_handler_pending == 0) { + btle_handler_pending = 1; + bluenrgDeviceInstance.signalEventsToProcess(BLE::DEFAULT_INSTANCE); + } +} + +/** + * @brief Disable SPI IRQ. + * @param None + * @retval None + */ +void Disable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.disable_irq(); +} + +/** + * @brief Clear Pending SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_IRQ(void) +{ +} + +/** + * @brief Clear EXTI (External Interrupt) line for SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_EXTI_Flag(void) +{ +} + + + + +#ifdef __cplusplus +} +#endif +// End of C function wrappers +//////////////////////////////////////// + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <ble_payload.h> + +Payload::Payload() { + stringLength = 0; + payloadUnitCount = 0; + payload = NULL; +} + +Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + stringLength = string_ength; + payloadUnitCount = 0; + payload = NULL; + + int index = 0; + while( index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + UnitPayload *obj = new UnitPayload[payloadUnitCount]; + int i=0; + int c=0; + int j,k; + + while(i<payloadUnitCount) + { + obj[i].length=tokenString[c]; + obj[i].id=tokenString[c+1]; + + obj[i].data = new uint8_t[obj[i].length]; + for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) + { + obj[i].data[k]=tokenString[j]; + + } + + c=c+obj[i].length+1; + i++; + + } + payload = obj; +} + +uint8_t Payload::getPayloadUnitCount() { + return payloadUnitCount; +} + +uint8_t Payload::getIDAtIndex(int index) { + return payload[index].get_id(); +} + +uint8_t Payload::getLengthAtIndex(int index) { + return payload[index].get_length(); +} + +uint8_t* Payload::getDataAtIndex(int index) { + return payload[index].get_data(); +} + +int8_t Payload::getInt8AtIndex(int index) { + uint8_t* str = payload[index].get_data(); + int8_t value = (int8_t)str[0]; + return value; +} + +uint16_t Payload::getUint16AtIndex(int index) { + uint16_t* str = (uint16_t*)payload[index].get_data(); + uint16_t value = str[0]; + return value; +} + +uint8_t* Payload::getSerializedAdDataAtIndex(int index) { + uint8_t length = payload[index].get_length(); + uint8_t* data = payload[index].get_data(); + uint8_t id = payload[index].get_id(); + uint8_t *serializedAdData = new uint8_t[length]; + + serializedAdData[0] = id; + for(int i=0; i<length-1; i++) { + serializedAdData[i+1] = data[i]; + } + return serializedAdData; +} + +Payload::~Payload() { + int i = 0; + + if(payload) { + while(i<payloadUnitCount) { + if(payload->data) { + delete[] payload->data; + payload->data = NULL; + } + } + delete[] payload; + payload = NULL; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,93 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ble_utils.h" + +/**************************************************************************/ +/*! + @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power + +*/ +/**************************************************************************/ +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(dBMLevel==-18) { + EN_HIGH_POWER = 0; + PA_LEVEL = 0; + } + else if(dBMLevel==-15) { + EN_HIGH_POWER = 0; + PA_LEVEL = 1; + } + else if(dBMLevel==-14) { + EN_HIGH_POWER = 1; + PA_LEVEL = 0; + } + else if(dBMLevel==-12) { + EN_HIGH_POWER = 0; + PA_LEVEL = 2; + } + else if(dBMLevel==-11) { + EN_HIGH_POWER = 1; + PA_LEVEL = 1; + } + else if(dBMLevel==-9) { + EN_HIGH_POWER = 0; + PA_LEVEL = 3; + } + else if(dBMLevel==-8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 2; + } + else if(dBMLevel==-6) { + EN_HIGH_POWER = 0; + PA_LEVEL = 4; + } + else if(dBMLevel==-5) { + EN_HIGH_POWER = 1; + PA_LEVEL = 3; + } + else if(dBMLevel==-2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 4; + } + else if(dBMLevel==0) { + EN_HIGH_POWER = 0; + PA_LEVEL = 6; + } + else if(dBMLevel==2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 5; + } + else if(dBMLevel==4) { + EN_HIGH_POWER = 1; + PA_LEVEL = 6; + } + else if(dBMLevel==5) { + EN_HIGH_POWER = 0; + PA_LEVEL = 7; + } + else if(dBMLevel==8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + else { + ret = ERR_INVALID_HCI_CMD_PARAMS; + } + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/source/ButtonService.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,42 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLE_BUTTON_SERVICE_H__ +#define __BLE_BUTTON_SERVICE_H__ + +class ButtonService { +public: + const static uint16_t BUTTON_SERVICE_UUID = 0xA000; + const static uint16_t BUTTON_STATE_CHARACTERISTIC_UUID = 0xA001; + + ButtonService(BLE &_ble, bool buttonPressedInitial) : + ble(_ble), buttonState(BUTTON_STATE_CHARACTERISTIC_UUID, &buttonPressedInitial, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) + { + GattCharacteristic *charTable[] = {&buttonState}; + GattService buttonService(ButtonService::BUTTON_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + ble.gattServer().addService(buttonService); + } + + void updateButtonState(bool newState) { + ble.gattServer().write(buttonState.getValueHandle(), (uint8_t *)&newState, sizeof(bool)); + } + +private: + BLE &ble; + ReadOnlyGattCharacteristic<bool> buttonState; +}; + +#endif /* #ifndef __BLE_BUTTON_SERVICE_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Button/source/main.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,122 @@ +/* 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 <events/mbed_events.h> + +#include <mbed.h> +#include "ble/BLE.h" +#include "ble/Gap.h" +#include "ButtonService.h" + +DigitalOut led1(LED1, 1); +InterruptIn button(BLE_BUTTON_PIN_NAME); + +static EventQueue eventQueue(/* event count */ 10 * EVENTS_EVENT_SIZE); + +const static char DEVICE_NAME[] = "Button"; +static const uint16_t uuid16_list[] = {ButtonService::BUTTON_SERVICE_UUID}; + +ButtonService *buttonServicePtr; + +void buttonPressedCallback(void) +{ + eventQueue.call(Callback<void(bool)>(buttonServicePtr, &ButtonService::updateButtonState), true); +} + +void buttonReleasedCallback(void) +{ + eventQueue.call(Callback<void(bool)>(buttonServicePtr, &ButtonService::updateButtonState), false); +} + +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) +{ + BLE::Instance().gap().startAdvertising(); // restart advertising +} + +void blinkCallback(void) +{ + led1 = !led1; /* Do blinky on LED1 to indicate system aliveness. */ +} + +void onBleInitError(BLE &ble, ble_error_t error) +{ + /* Initialization error handling should go here */ +} + +void printMacAddress() +{ + /* Print out device MAC address to the console*/ + Gap::AddressType_t addr_type; + Gap::Address_t address; + BLE::Instance().gap().getAddress(&addr_type, address); + printf("DEVICE MAC ADDRESS: "); + for (int i = 5; i >= 1; i--){ + printf("%02x:", address[i]); + } + printf("%02x\r\n", address[0]); +} + +void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) +{ + BLE& ble = params->ble; + ble_error_t error = params->error; + + if (error != BLE_ERROR_NONE) { + /* In case of error, forward the error handling to onBleInitError */ + onBleInitError(ble, error); + return; + } + + /* Ensure that it is the default instance of BLE */ + if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { + return; + } + + ble.gap().onDisconnection(disconnectionCallback); + + button.fall(buttonPressedCallback); + button.rise(buttonReleasedCallback); + + /* Setup primary service. */ + buttonServicePtr = new ButtonService(ble, false /* initial value for button pressed */); + + /* setup advertising */ + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.gap().setAdvertisingInterval(1000); /* 1000ms. */ + ble.gap().startAdvertising(); + + printMacAddress(); +} + +void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { + BLE &ble = BLE::Instance(); + eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); +} + +int main() +{ + eventQueue.call_every(500, blinkCallback); + + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(scheduleBleEventsProcessing); + ble.init(bleInitComplete); + + eventQueue.dispatch_forever(); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/.mbed Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +ROOT=.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,24 @@ +# GAP - Advertising, Scanning, Connecting + +Demo of the GAP profile. It shows advertising, scanning and connecting. The demo will cycle through several modes +and print over the serial connection information about current activity. + +# Running the application + +## Requirements + +The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : + +- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. + +- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. + +Information about activity is printed over the serial connection - please have a client open. You may use: + +- [Tera Term](https://ttssh2.osdn.jp/index.html.en) + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/mbed-os.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/mbed_app.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "target_overrides": { + "K64F": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "NUCLEO_F401RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "DISCO_L475VG_IOT01A": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/#b630517008bbe47592927cc8e5dfcd2e5b9de968
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/.gitignore Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,9 @@ +# vim temporary files +*.sw* + +# yotta files +build +yotta_modules +yotta_targets +.yotta.json +upload.tar.gz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,34 @@ +# BLE-X-NUCLEO-IDB0XA1 + +BLE_API wrapper Library for X-NUCLEO-IDB05A1 BlueNRG (Bluetooth Low Energy) Expansion Board + +## Introduction + +This firmware package implements the port of BLE_API to STMicroelectronics' [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) Bluetooth Low Energy Nucleo Expansion Board. + +### Arduino Connector Compatibility Warning + +X-NUCLEO-IDB05A1 is Arduino compatible with an exception: instead of using pin **D13** for the SPI clock, pin **D3** is used. +The default configuration for this library is having the SPI clock on pin **D3**. + +To be fully Arduino compatible, X-NUCLEO-IDB05A1 needs a small HW patch. + +For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor **R4** and instead soldering zero resistor **R6**. + +In case you patch your board, then you also have to configure this library to use pin **D13** to drive the SPI clock. To this aim you need to compile this driver with macro `BLUENRG_PIN_SPI_SCK=D13` defined. + +If you use pin **D13** for the SPI clock, please be aware that on STM32 Nucleo boards you may **not** drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin **D13**. + +Referring to the current list of tested platforms (see [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) page), the patch is required by [ST-Nucleo-F103RB](https://developer.mbed.org/platforms/ST-Nucleo-F103RB/); [ST-Nucleo-F302R8](https://developer.mbed.org/platforms/ST-Nucleo-F302R8/); [ST-Nucleo-F411RE](https://developer.mbed.org/platforms/ST-Nucleo-F411RE/); [ST-Nucleo-F446RE](https://developer.mbed.org/platforms/ST-Nucleo-F446RE/); and [FRDM-K64F](https://developer.mbed.org/platforms/FRDM-K64F/). + +### Firmware update + +For better performance and compatibility with latest mbed API, you should update firmware of X-NUCLEO-IDB05A1 component by using this simple [application](https://developer.mbed.org/teams/ST/code/BlueNRG-MS-Stack-Updater). + +### Driver configuration + +In order to use the BlueNRG-MS module together with other targets, you need to set the macros defined in file [bluenrg_targets.h](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/bluenrg/bluenrg_targets.h). Please, update the [mbed_lib.json](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/mbed_lib.json) to include the list of extra macros that configure the driver for your target. + +## Example Applications + +To run BLE example applications using X-NUCLEO-IDB05A1 Expansion Board based on mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli), please refer to section [Using ST shield on other targets](https://github.com/ARMmbed/mbed-os-example-ble#using-st-nucleo-shield-on-other-targets) in the official [mbed-os-example-ble](https://github.com/ARMmbed/mbed-os-example-ble) page.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.h + * @author STMicroelectronics + * @brief Header file for BLEDeviceInstanceBase based BlueNRGDevice + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_DEVICE_H__ +#define __BLUENRG_DEVICE_H__ + +#define BLUENRG +#define DEBUG_BLUENRG_USER + +#include "btle.h" + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "ble/BLEInstanceBase.h" +#include "ble/BLE.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" + + +class BlueNRGDevice : public BLEInstanceBase +{ + +public: + BlueNRGDevice(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, PinName irq); + virtual ~BlueNRGDevice(void); + + virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback); + virtual ble_error_t shutdown(void); + virtual const char *getVersion(void); + virtual Gap& getGap(); + virtual const Gap& getGap() const; + virtual GattServer& getGattServer(); + virtual const GattServer& getGattServer() const; + virtual void waitForEvent(void); + + virtual GattClient& getGattClient() { + return BlueNRGGattClient::getInstance(); + } + + virtual SecurityManager& getSecurityManager() { + return *sm; + } + + virtual const SecurityManager& getSecurityManager() const { + return *sm; + } + void reset(void); + virtual bool hasInitialized(void) const { + return isInitialized; + } + + uint8_t getUpdaterHardwareVersion(uint8_t *hw_version); + int updateFirmware(const uint8_t *fw_image, uint32_t fw_size); + bool dataPresent(); + int32_t spiRead(uint8_t *buffer, uint8_t buff_size); + int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2); + void disable_irq(); + void enable_irq(); + + virtual void processEvents(); + +private: + bool isInitialized; + + SPI spi_; + DigitalOut nCS_; + DigitalOut rst_; + InterruptIn irq_; + + //FIXME: TBI (by now just placeholders to let build + /*** betzw: placeholders ***/ + SecurityManager *sm; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ +#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ + +#include "ble/DiscoveredCharacteristic.h" + +class BlueNRGGattClient; /* forward declaration */ + +class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic { +public: + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + + void setLastHandle(GattAttribute::Handle_t lastHandleIn); +}; + +#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGGap.h + * @author STMicroelectronics + * @brief Header file for BlueNRG BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GAP_H__ +#define __BLUENRG_GAP_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/Gap.h" + +#define BLE_CONN_HANDLE_INVALID 0x0 +#define BDADDR_SIZE 6 + +#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020) +#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000) +#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0) + +// Scanning and Connection Params used by Central for creating connection +#define GAP_OBSERVATION_PROC (0x80) + +#define SCAN_P (0x0010) +#define SCAN_L (0x0010) +#define SUPERV_TIMEOUT (0xC80) +#define CONN_P(x) ((int)((x)/1.25f)) +#define CONN_L(x) ((int)((x)/0.625f)) +#define CONN_P1 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_P2 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_L1 (0x0008) +#define CONN_L2 (0x0008) +#define GUARD_INT 5 //msec +#define MIN_INT_CONN 0x0006 //=>7.5msec +#define MAX_INT_CONN 0x0C80 //=>4000msec +#define DEF_INT_CONN 0x0140 //=>400msec (default value for connection interval) + +/**************************************************************************/ +/*! + \brief + +*/ +/**************************************************************************/ +class BlueNRGGap : public Gap +{ +public: + static BlueNRGGap &getInstance() { + static BlueNRGGap m_instance; + return m_instance; + } + + enum Reason_t { + DEVICE_FOUND, + DISCOVERY_COMPLETE + }; + + /* Functions that must be implemented from Gap */ + virtual ble_error_t setAddress(addr_type_t type, const BLEProtocol::AddressBytes_t address); + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address); + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &); + virtual ble_error_t startAdvertising(const GapAdvertisingParams &); + virtual ble_error_t stopAdvertising(void); + virtual ble_error_t stopScan(); + virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);} + virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);} + virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);} + virtual ble_error_t disconnect(DisconnectionReason_t reason); + virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason); + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params); + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); + + virtual ble_error_t setDeviceName(const uint8_t *deviceName); + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); + virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance); + virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP); + + virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode); + virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode); + virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const; + virtual ScanningPolicyMode_t getScanningPolicyMode(void) const; + + virtual ble_error_t setTxPower(int8_t txPower); + virtual void getPermittedTxPowerValues(const int8_t **, size_t *); + + virtual ble_error_t connect(const Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams); + + virtual ble_error_t reset(void); + + void Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI); + ble_error_t createConnection(void); + + void setConnectionHandle(uint16_t con_handle); + uint16_t getConnectionHandle(void); + + bool getIsSetAddress(); + + // ADV timeout handling + Timeout& getAdvTimeout(void) { + return advTimeout; + } + uint8_t getAdvToFlag(void) { + return AdvToFlag; + } + void setAdvToFlag(void); + + // SCAN timeout handling + Timeout& getScanTimeout(void) { + return scanTimeout; + } + uint8_t getScanToFlag(void) { + return ScanToFlag; + } + void setScanToFlag(void); + + void Process(void); + + GapScanningParams* getScanningParams(void); + + virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams); + + void setConnectionInterval(uint16_t interval); + Gap::Role_t getGapRole(void); + void setGapRole(Gap::Role_t role); + +private: + uint16_t m_connectionHandle; + Role_t gapRole; + AddressType_t addr_type; + Address_t _peerAddr; + AddressType_t _peerAddrType; + uint8_t bdaddr[BDADDR_SIZE]; + bool _scanning; + bool _connecting; + bool isSetAddress; + uint8_t deviceAppearance[2]; + + // ADV timeout handling + Timeout advTimeout; + bool AdvToFlag; + + // SCAN timeout handling + Timeout scanTimeout; + bool ScanToFlag; + + static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) { + return (duration * 625) / 1000; + } + + uint16_t scanInterval; + uint16_t scanWindow; + uint16_t advInterval; + uint16_t slaveConnIntervMin; + uint16_t slaveConnIntervMax; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + void setAdvParameters(void); + void setConnectionParameters(void); + + Gap::AdvertisingPolicyMode_t advertisingPolicyMode; + Gap::ScanningPolicyMode_t scanningPolicyMode; + + Whitelist_t whitelistAddresses; + + ble_error_t updateAdvertisingData(void); + + BlueNRGGap() : AdvToFlag(false), ScanToFlag(false) { + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + addr_type = BLEProtocol::AddressType::RANDOM_STATIC; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + isSetAddress = false; + memset(deviceAppearance, 0, sizeof(deviceAppearance)); + } + + BlueNRGGap(BlueNRGGap const &); + void operator=(BlueNRGGap const &); + + GapAdvertisingData _advData; + GapAdvertisingData _scanResponse; +}; + +#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,157 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattClient.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CLIENT_H__ +#define __BLUENRG_GATT_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattConnectionClient.h" + +using namespace std; + +#define MAX_ACTIVE_CONNECTIONS 7 + +class BlueNRGGattClient : public GattClient +{ +public: + static BlueNRGGattClient &getInstance() { + static BlueNRGGattClient m_instance; + return m_instance; + } + + ble_error_t createGattConnectionClient(Gap::Handle_t connectionHandle); + ble_error_t removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason); + + /* Functions that must be implemented from GattClient */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + virtual bool isServiceDiscoveryActive(void) const; + virtual void terminateServiceDiscovery(void); + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback); + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + virtual ble_error_t write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + virtual ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + virtual ble_error_t reset(void); + + void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code); + + void primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(Gap::Handle_t connectionHandle); + + void serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length); + + +protected: + + BlueNRGGattClient(): _connectionPool() {}; + + ServiceDiscovery::TerminationCallback_t terminationCallback; + +private: + + BlueNRGGattClient(BlueNRGGattClient const &); + void operator=(BlueNRGGattClient const &); + + BlueNRGGattConnectionClient *_connectionPool[MAX_ACTIVE_CONNECTIONS]; + uint8_t _numConnections; + + BlueNRGGattConnectionClient * getGattConnectionClient(Gap::Handle_t connectionHandle); + +}; + +#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,185 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattConnectionClient.cpp + * @author STMicroelectronics + * @brief Header file for BlueNRGGattConnectionClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CONNECTION_CLIENT_H__ +#define __BLUENRG_GATT_CONNECTION_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" + +using namespace std; + +#define BLE_TOTAL_DISCOVERED_SERVICES 10 +#define BLE_TOTAL_DISCOVERED_CHARS 10 + +class BlueNRGGattConnectionClient +{ +public: + + enum { + GATT_IDLE, + GATT_SERVICE_DISCOVERY, + GATT_CHAR_DESC_DISCOVERY, + //GATT_CHARS_DISCOVERY_COMPLETE, + //GATT_DISCOVERY_TERMINATED, + GATT_READ_CHAR, + GATT_WRITE_CHAR + }; + + /* Functions that must be implemented from GattClient */ + ble_error_t launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + bool isServiceDiscoveryActive(void) const; + void terminateServiceDiscovery(void); + void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + } + ble_error_t read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + ble_error_t write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + ble_error_t reset(void); + + void gattProcedureCompleteCB(uint8_t error_code); + + void primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(void); + + void serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(uint8_t event_data_length); + +protected: + + BlueNRGGattConnectionClient(BlueNRGGattClient *gattClient, Gap::Handle_t connectionHandle): + discoveredService(), + discoveredChar(), + readCBParams(), + writeCBParams(), + _characteristic() { + + //PRINTF("BlueNRGGattConnectionClient construtor: connHandle=%d\n\r", connectionHandle); + + _gattClient = gattClient; + _connectionHandle = connectionHandle; + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + } + + ServiceDiscovery::ServiceCallback_t serviceDiscoveryCallback; + ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback; + ServiceDiscovery::TerminationCallback_t terminationCallback; + CharacteristicDescriptorDiscovery::DiscoveryCallback_t charDescDiscoveryCallback; + CharacteristicDescriptorDiscovery::TerminationCallback_t charDescTerminationCallback; + +private: + + BlueNRGGattConnectionClient(BlueNRGGattConnectionClient const &); + void operator=(BlueNRGGattConnectionClient const &); + ~BlueNRGGattConnectionClient() {}; + + BlueNRGGattClient *_gattClient; + + Gap::Handle_t _connectionHandle; + DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES]; + BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS]; + + GattReadCallbackParams readCBParams; + GattWriteCallbackParams writeCBParams; + + // The char for which the descriptor discovery has been launched + DiscoveredCharacteristic _characteristic; + + UUID _matchingServiceUUID; + UUID _matchingCharacteristicUUIDIn; + uint8_t _currentState; + uint8_t _numServices, _servIndex; + uint8_t _numChars; + uint8_t _numCharDesc; + + friend class BlueNRGGattClient; +}; + +#endif /* __BLUENRG_GATT_CONNECTION_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_SERVER_H__ +#define __BLUENRG_GATT_SERVER_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattService.h" +#include "ble/GattServer.h" +#include <vector> +#include <map> + +#define BLE_TOTAL_CHARACTERISTICS 10 + +using namespace std; + +class BlueNRGGattServer : public GattServer +{ +public: + static BlueNRGGattServer &getInstance() { + static BlueNRGGattServer m_instance; + return m_instance; + } + + enum HandleEnum_t { + CHAR_HANDLE = 0, + CHAR_VALUE_HANDLE, + CHAR_DESC_HANDLE + }; + + /* Functions that must be implemented from GattServer */ + virtual ble_error_t addService(GattService &); + virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t initializeGATTDatabase(void); + + virtual bool isOnDataReadAvailable() const { + return true; + } + + virtual ble_error_t reset(void); + + /* BlueNRG Functions */ + void eventCallback(void); + //void hwCallback(void *pckt); + ble_error_t Read_Request_CB(uint16_t attributeHandle); + uint8_t Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, + uint8_t data_length, const uint8_t* data + ); + GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle); + void HCIDataWrittenEvent(const GattWriteCallbackParams *params); + void HCIDataReadEvent(const GattReadCallbackParams *params); + void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle); + void HCIDataSentEvent(unsigned count); + +private: + + // compute the number of attribute record needed by a service + static uint16_t computeAttributesRecord(GattService& service); + + + static const int MAX_SERVICE_COUNT = 10; + uint8_t serviceCount; + uint8_t characteristicCount; + uint16_t servHandle, charHandle; + + std::map<uint16_t, uint16_t> bleCharHandleMap; // 1st argument is characteristic, 2nd argument is service + GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS]; + uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS]; + + BlueNRGGattServer() { + serviceCount = 0; + characteristicCount = 0; + }; + + BlueNRGGattServer(BlueNRGGattServer const &); + void operator=(BlueNRGGattServer const &); + + static const int CHAR_DESC_TYPE_16_BIT=0x01; + static const int CHAR_DESC_TYPE_128_BIT=0x02; + static const int CHAR_DESC_SECURITY_PERMISSION=0x00; + static const int CHAR_DESC_ACCESS_PERMISSION=0x03; + static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_CLOCK_H__ +#define __BLE_CLOCK_H__ + +#include <ble_hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __BLE_CLOCK_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file ble_debug.h + * @author CL + * @version V1.0.0 + * @date 04-July-2014 + * @brief This file defines print functions for debug purposes. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLE_DEBUG_H +#define __BLE_DEBUG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> + +/* Exported macro ------------------------------------------------------------*/ +//#define DEBUG +#ifdef DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Print the data travelling over the SPI in the .csv format for the GUI*/ +//#define PRINT_CSV_FORMAT +#ifdef PRINT_CSV_FORMAT +#include <stdio.h> +#define PRINT_CSV(...) printf(__VA_ARGS__) +#else +#define PRINT_CSV(...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __BLE_DEBUG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_gp_timer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : General purpose timer library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_GP_TIMER_H__ +#define __BLE_GP_TIMER_H__ + +#include "ble_clock.h" +#include "ble_status.h" +#ifdef __DMA_LP__ +#include "stm32xx_timerserver.h" +#endif /* __DMA_LP__ */ + +/** + * timer + * + * A structure that represents a timer. Use Timer_Set() to set the timer. + * + */ +struct timer { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + tClockTime start; + tClockTime interval; + +#endif +}; + +typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); + +/** + * Timer_Set + * + * @param[in] t Pointer to a timer structure + * @param[in] interval timeout value + * + * This function sets the timeout value of a timer. + * + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * Timer_Reset + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the time it previously expired. + * + */ +void Timer_Reset(struct timer *t); + +/** + * Timer_Restart + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the current time. + * + */ +void Timer_Restart(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns TRUE if timer is expired, FALSE otherwise. + * + */ +int Timer_Expired(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns the time needed for expiration. + * + * @return Time before timer's expiration. + */ +tClockTime Timer_Remaining(struct timer *t); + +#ifdef __DMA_LP__ +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID); + +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); +#endif /* __DMA_LP__ */ + +#endif /* __BLE_GP_TIMER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,108 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_H__ +#define __BLE_HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void signalEventsToProcess(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __BLE_HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_TYPES_H__ +#define __BLE_HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __BLE_HAL_TYPES_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,126 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.0, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_H_ +#define __BLE_HCI_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ble_hal_types.h" +#include "ble_link_layer.h" +#include <ble_list.h> + +#define HCI_READ_PACKET_SIZE 128 //71 + +/** + * Maximum payload of HCI commands that can be sent. Change this value if needed. + * This value can be up to 255. + */ +#define HCI_MAX_PAYLOAD_SIZE 128 + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_READ_PACKET_SIZE]; + uint8_t data_len; +} tHciDataPacket; + +struct hci_request { + uint16_t ogf; + uint16_t ocf; + int event; + void *cparam; + int clen; + void *rparam; + int rlen; +}; + +typedef enum +{ + BUSY, + AVAILABLE +} HCI_CMD_STATUS_t; + + +/** + * This function must be used to pass the packet received from the HCI + * interface to the BLE Stack HCI state machine. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * + */ +void HCI_Input(tHciDataPacket *hciReadPacket); + +/** + * Initialization function. Must be done before any data can be received from + * BLE controller. + */ +void HCI_Init(void); + +/** + * Callback used to pass events to application. + * + * @param[in] pckt The event. + * + */ +extern void HCI_Event_CB(void *pckt); + +/** + * Processing function that must be called after an event is received from + * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if + * necessary. +*/ +void HCI_Process(void); + +/** + * @brief Check if queue of HCI event is empty or not. + * @note This funtion can be used to check if the event queue from BlueNRG is empty. This + * is useful when checking if it is safe to go to sleep. + * @return TRUE if event queue is empty. FALSE otherwhise. + */ +BOOL HCI_Queue_Empty(void); +/** + * Iterrupt service routine that must be called when the BlueNRG + * reports a packet received or an event to the host through the + * BlueNRG interrupt line. + */ +#ifdef __DMA_LP__ +void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); +void HCI_Process_Notification_Request(void); +void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); +void HCI_Wait_For_Response(void); +#else +void HCI_Isr(void); +void HCI_HandleSPI(void); + +int hci_send_req(struct hci_request *r, BOOL async); +#endif /* __DMA_LP__ */ + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#ifdef __cplusplus +} +#endif + + +#endif /* __BLE_HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,548 @@ +/****************************************************************************** +* +* File Description +* --------------------- +* This file defines constants and functions for HCI layer. +* See Bluetooth Core v 4.0, Vol. 2, Part E. +* +*******************************************************************************/ + +#ifndef __HCI_INTERNAL_H_ +#define __HCI_INTERNAL_H_ + +#include "ble_compiler.h" +#include "ble_hal_types.h" +#include "ble_clock.h" +#include "ble_link_layer.h" +#include "ble_hci.h" + +#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) + + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +typedef __packed struct _hci_uart_pckt{ + uint8_t type; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef __packed struct _hci_command_hdr{ + uint16_t opcode; /* OCF & OGF */ + uint8_t plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef __packed struct _hci_event_pckt{ + uint8_t evt; + uint8_t plen; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef __packed struct _hci_acl_hdr{ + uint16_t handle; /* Handle & Flags(PB, BC) */ + uint16_t dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef __packed struct _disconnect_cp{ + uint16_t handle; + uint8_t reason; +} PACKED disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 + +#define OCF_SET_EVENT_MASK 0x0001 +#define OCF_RESET 0x0003 + +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D +typedef __packed struct _read_transmit_power_level_cp{ + uint16_t handle; + uint8_t type; +} PACKED read_transmit_power_level_cp; +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 +typedef __packed struct _read_transmit_power_level_rp{ + uint8_t status; + uint16_t handle; + int8_t level; +} PACKED read_transmit_power_level_rp; +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 + +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 +#define OCF_HOST_BUFFER_SIZE 0x0033 +#define OCF_HOST_NUM_COMP_PKTS 0x0035 + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef __packed struct _read_local_version_rp{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t manufacturer_name; + uint16_t lmp_pal_subversion; +} PACKED read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_COMMANDS 0x0002 +#define OCF_READ_LOCAL_FEATURES 0x0003 + +#define OCF_READ_BD_ADDR 0x0009 +typedef __packed struct _read_bd_addr_rp{ + uint8_t status; + tBDAddr bdaddr; +} PACKED read_bd_addr_rp; +#define READ_BD_ADDR_RP_SIZE 7 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +#define OCF_READ_RSSI 0x0005 +typedef __packed struct _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef __packed struct _read_rssi_rp{ + uint8_t status; + uint16_t handle; + int8_t rssi; +} PACKED read_rssi_rp; +#define READ_RSSI_RP_SIZE 4 + + +/* LE commands */ +#define OGF_LE_CTL 0x08 + +#define OCF_LE_SET_EVENT_MASK 0x0001 +typedef __packed struct _le_set_event_mask_cp{ + uint8_t mask[8]; +} PACKED le_set_event_mask_cp; +#define LE_SET_EVENT_MASK_CP_SIZE 8 + +#define OCF_LE_READ_BUFFER_SIZE 0x0002 +typedef __packed struct _le_read_buffer_size_rp{ + uint8_t status; + uint16_t pkt_len; + uint8_t max_pkt; +} PACKED le_read_buffer_size_rp; +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 + +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 +typedef __packed struct _le_read_local_supported_features_rp{ + uint8_t status; + uint8_t features[8]; +} PACKED le_read_local_supported_features_rp; +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 + +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 +typedef __packed struct _le_set_random_address_cp{ + tBDAddr bdaddr; +} PACKED le_set_random_address_cp; +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 + +#define OCF_LE_SET_ADV_PARAMETERS 0x0006 +typedef __packed struct _le_set_adv_parameters_cp{ + uint16_t min_interval; + uint16_t max_interval; + uint8_t advtype; + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint8_t chan_map; + uint8_t filter; +} PACKED le_set_adv_parameters_cp; +#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 + +#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 +typedef __packed struct _le_read_adv_channel_tx_power_rp{ + uint8_t status; + int8_t level; +} PACKED le_read_adv_channel_tx_power_rp; +#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 + +#define OCF_LE_SET_ADV_DATA 0x0008 +typedef __packed struct _le_set_adv_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_adv_data_cp; +#define LE_SET_ADV_DATA_CP_SIZE 32 + +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 +typedef __packed struct _le_set_scan_response_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_scan_response_data_cp; +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 + +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A +typedef __packed struct _le_set_advertise_enable_cp{ + uint8_t enable; +} PACKED le_set_advertise_enable_cp; +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 + +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B +typedef __packed struct _le_set_scan_parameters_cp{ + uint8_t type; + uint16_t interval; + uint16_t window; + uint8_t own_bdaddr_type; + uint8_t filter; +} PACKED le_set_scan_parameters_cp; +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 + +#define OCF_LE_SET_SCAN_ENABLE 0x000C +typedef __packed struct _le_set_scan_enable_cp{ + uint8_t enable; + uint8_t filter_dup; +} PACKED le_set_scan_enable_cp; +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 + +#define OCF_LE_CREATE_CONN 0x000D +typedef __packed struct _le_create_connection_cp{ + uint16_t interval; + uint16_t window; + uint8_t initiator_filter; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_create_connection_cp; +#define LE_CREATE_CONN_CP_SIZE 25 + +#define OCF_LE_CREATE_CONN_CANCEL 0x000E + +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F +typedef __packed struct _le_read_white_list_size_rp{ + uint8_t status; + uint8_t size; +} PACKED le_read_white_list_size_rp; +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 + +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 +typedef __packed struct _le_add_device_to_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_add_device_to_white_list_cp; +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 +typedef __packed struct _le_remove_device_from_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_remove_device_from_white_list_cp; +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_CONN_UPDATE 0x0013 +typedef __packed struct _le_connection_update_cp{ + uint16_t handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_connection_update_cp; +#define LE_CONN_UPDATE_CP_SIZE 14 + +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 +typedef __packed struct _le_set_host_channel_classification_cp{ + uint8_t map[5]; +} PACKED le_set_host_channel_classification_cp; +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 + +#define OCF_LE_READ_CHANNEL_MAP 0x0015 +typedef __packed struct _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef __packed struct _le_read_channel_map_rp{ + uint8_t status; + uint16_t handle; + uint8_t map[5]; +} PACKED le_read_channel_map_rp; +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 + +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 +typedef __packed struct _le_read_remote_used_features_cp{ + uint16_t handle; +} PACKED le_read_remote_used_features_cp; +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 + +#define OCF_LE_ENCRYPT 0x0017 +typedef __packed struct _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef __packed struct _le_encrypt_rp{ + uint8_t status; + uint8_t encdata[16]; +} PACKED le_encrypt_rp; +#define LE_ENCRYPT_RP_SIZE 17 + +#define OCF_LE_RAND 0x0018 +typedef __packed struct _le_rand_rp{ + uint8_t status; + uint8_t random[8]; +} PACKED le_rand_rp; +#define LE_RAND_RP_SIZE 9 + +#define OCF_LE_START_ENCRYPTION 0x0019 +typedef __packed struct _le_start_encryption_cp{ + uint16_t handle; + uint8_t random[8]; + uint16_t diversifier; + uint8_t key[16]; +} PACKED le_start_encryption_cp; +#define LE_START_ENCRYPTION_CP_SIZE 28 + +#define OCF_LE_LTK_REPLY 0x001A +typedef __packed struct _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef __packed struct _le_ltk_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_reply_rp; +#define LE_LTK_REPLY_RP_SIZE 3 + +#define OCF_LE_LTK_NEG_REPLY 0x001B +typedef __packed struct _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef __packed struct _le_ltk_neg_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_neg_reply_rp; +#define LE_LTK_NEG_REPLY_RP_SIZE 3 + +#define OCF_LE_READ_SUPPORTED_STATES 0x001C +typedef __packed struct _le_read_supported_states_rp{ + uint8_t status; + uint8_t states[8]; +} PACKED le_read_supported_states_rp; +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 + +#define OCF_LE_RECEIVER_TEST 0x001D +typedef __packed struct _le_receiver_test_cp{ + uint8_t frequency; +} PACKED le_receiver_test_cp; +#define LE_RECEIVER_TEST_CP_SIZE 1 + +#define OCF_LE_TRANSMITTER_TEST 0x001E +typedef __packed struct _le_transmitter_test_cp{ + uint8_t frequency; + uint8_t length; + uint8_t payload; +} PACKED le_transmitter_test_cp; +#define LE_TRANSMITTER_TEST_CP_SIZE 3 + +#define OCF_LE_TEST_END 0x001F +typedef __packed struct _le_test_end_rp{ + uint8_t status; + uint16_t num_pkts; +} PACKED le_test_end_rp; +#define LE_TEST_END_RP_SIZE 3 + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3f + + +/*------------- Events -------------*/ +#define EVT_CONN_COMPLETE 0x03 +typedef __packed struct _evt_conn_complete{ + uint8_t status; + uint16_t handle; + tBDAddr bdaddr; + uint8_t link_type; + uint8_t encr_mode; +} PACKED evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef __packed struct _evt_disconn_complete{ + uint8_t status; + uint16_t handle; + uint8_t reason; +} PACKED evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef __packed struct _evt_encrypt_change{ + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} PACKED evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C + +#define EVT_CMD_COMPLETE 0x0E +typedef __packed struct _evt_cmd_complete{ + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef __packed struct _evt_cmd_status{ + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef __packed struct _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef __packed struct _evt_num_comp_pkts{ + uint8_t num_hndl; + /* variable length part */ +} PACKED evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +/* variable length part of evt_num_comp_pkts. */ +typedef __packed struct _evt_num_comp_pkts_param{ + uint16_t hndl; + uint16_t num_comp_pkts; +} PACKED evt_num_comp_pkts_param; +#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 + +#define EVT_DATA_BUFFER_OVERFLOW 0x1A +typedef __packed struct _evt_data_buffer_overflow{ + uint8_t link_type; +} PACKED evt_data_buffer_overflow; +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 + +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef __packed struct _evt_encryption_key_refresh_complete{ + uint8_t status; + uint16_t handle; +} PACKED evt_encryption_key_refresh_complete; +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 + +#define EVT_LE_META_EVENT 0x3E +typedef __packed struct _evt_le_meta_event{ + uint8_t subevent; + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef __packed struct _evt_le_connection_complete{ + uint8_t status; + uint16_t handle; + uint8_t role; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; +} PACKED evt_le_connection_complete; +#define EVT_LE_CONN_COMPLETE_SIZE 18 + +#define EVT_LE_ADVERTISING_REPORT 0x02 +typedef __packed struct _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t data_length; + uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef __packed struct _evt_le_connection_update_complete{ + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; +} PACKED evt_le_connection_update_complete; +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 + +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +typedef __packed struct _evt_le_read_remote_used_features_complete{ + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} PACKED evt_le_read_remote_used_features_complete; +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 + +#define EVT_LE_LTK_REQUEST 0x05 +typedef __packed struct _evt_le_long_term_key_request{ + uint16_t handle; + uint8_t random[8]; + uint16_t ediv; +} PACKED evt_le_long_term_key_request; +#define EVT_LE_LTK_REQUEST_SIZE 12 + +/** +* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, +* application can use @ref evt_blue_aci structure to parse the packet. +*/ +#define EVT_VENDOR 0xFF + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + + + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); + +typedef enum { + WAITING_TYPE, + WAITING_OPCODE1, + WAITING_OPCODE2, + WAITING_EVENT_CODE, + WAITING_HANDLE, + WAITING_HANDLE_FLAG, + WAITING_PARAM_LEN, + WAITING_DATA_LEN1, + WAITING_DATA_LEN2, + WAITING_PAYLOAD +}hci_state; + +typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); + +/* HCI library functions. */ + +int hci_send_req(struct hci_request *r, BOOL async); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,170 @@ +/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +* File Name : ble_hci_le.h +* Author : AMG RF FW team +* Version : V1.1.0 +* Date : 18-July-2016 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.1, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_LE_H_ +#define __BLE_HCI_LE_H_ + +#include "ble_hal_types.h" +#include "ble_link_layer.h" + +/** + * @defgroup HCI_Error_codes HCI Error codes + * @{ + */ +#define HCI_UNKNOWN_COMMAND 0x01 +#define HCI_NO_CONNECTION 0x02 +#define HCI_HARDWARE_FAILURE 0x03 +#define HCI_PAGE_TIMEOUT 0x04 +#define HCI_AUTHENTICATION_FAILURE 0x05 +#define HCI_PIN_OR_KEY_MISSING 0x06 +#define HCI_MEMORY_FULL 0x07 +#define HCI_CONNECTION_TIMEOUT 0x08 +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a +#define HCI_ACL_CONNECTION_EXISTS 0x0b +#define HCI_COMMAND_DISALLOWED 0x0c +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d +#define HCI_REJECTED_SECURITY 0x0e +#define HCI_REJECTED_PERSONAL 0x0f +#define HCI_HOST_TIMEOUT 0x10 +#define HCI_UNSUPPORTED_FEATURE 0x11 +#define HCI_INVALID_PARAMETERS 0x12 +#define HCI_OE_USER_ENDED_CONNECTION 0x13 +#define HCI_OE_LOW_RESOURCES 0x14 +#define HCI_OE_POWER_OFF 0x15 +#define HCI_CONNECTION_TERMINATED 0x16 +#define HCI_REPEATED_ATTEMPTS 0x17 +#define HCI_PAIRING_NOT_ALLOWED 0x18 +#define HCI_UNKNOWN_LMP_PDU 0x19 +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a +#define HCI_SCO_OFFSET_REJECTED 0x1b +#define HCI_SCO_INTERVAL_REJECTED 0x1c +#define HCI_AIR_MODE_REJECTED 0x1d +#define HCI_INVALID_LMP_PARAMETERS 0x1e +#define HCI_UNSPECIFIED_ERROR 0x1f +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 +#define HCI_UNIT_LINK_KEY_USED 0x26 +#define HCI_QOS_NOT_SUPPORTED 0x27 +#define HCI_INSTANT_PASSED 0x28 +#define HCI_PAIRING_NOT_SUPPORTED 0x29 +#define HCI_TRANSACTION_COLLISION 0x2a +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c +#define HCI_QOS_REJECTED 0x2d +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e +#define HCI_INSUFFICIENT_SECURITY 0x2f +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 +#define HCI_ROLE_SWITCH_PENDING 0x32 +#define HCI_SLOT_VIOLATION 0x34 +#define HCI_ROLE_SWITCH_FAILED 0x35 +#define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 +#define HCI_CONN_REJ_NO_CH_FOUND 0x39 +#define HCI_CONTROLLER_BUSY 0x3A +#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B +#define HCI_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_CONN_TERM_MIC_FAIL 0x3D +#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E +#define HCI_MAC_CONN_FAILED 0x3F +/** + * @} + */ + + +/* + * HCI library functions. + * Each function returns 0 in case of success, otherwise one of the error codes. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(uint8_t enable); + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter); + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter); + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); + +int hci_le_rand(uint8_t random_number[8]); + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); + +int hci_acl_data(const uint8_t * data, uint16_t len); + +int hci_le_set_random_address(tBDAddr bdaddr); + +int hci_read_bd_addr(tBDAddr bdaddr); + +int hci_le_read_white_list_size(uint8_t *size); + +int hci_le_clear_white_list(); + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); + +int hci_le_ltk_request_reply(uint8_t key[16]); + +int hci_le_ltk_request_neg_reply(); + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); + +int hci_le_create_connection_cancel(void); + +int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level); + +int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi); + +int hci_le_read_local_supported_features(uint8_t *features); + +int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); + +int hci_le_read_supported_states(uint8_t states[8]); + +int hci_le_receiver_test(uint8_t frequency); + +int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); + +int hci_le_test_end(uint16_t *num_pkts); + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion); + + + +#endif /* __BLE_HCI_LE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,161 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_link_layer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's link layer. It contains +* definition of functions for link layer, most of which are +* mapped to HCI commands. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef _BLE_LINK_LAYER_H +#define _BLE_LINK_LAYER_H + +#include <ble_status.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + *@name Advertising filter + *Advertising policy for filtering (white list related) + *@{ + */ +#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ +#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ +/** + * @} + */ + + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef uint8_t tBDAddr[6]; + + +/** + *@name Bluetooth address types + * Bluetooth address types + *@{ + */ +#define PUBLIC_ADDR (0) +#define RANDOM_ADDR (1) +#define STATIC_RANDOM_ADDR (1) +#define RESOLVABLE_PRIVATE_ADDR (2) +#define NON_RESOLVABLE_PRIVATE_ADDR (3) +/** + * @} + */ + +/** + *@name Directed advertising types + * Type of advertising during directed advertising + *@{ + */ +#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) +#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) +/** + * @} + */ + +/** + * @name Advertising type + * @{ + */ + +/** + * undirected scannable and connectable + */ +#define ADV_IND (0x00) + +/** + * directed non scannable + */ +#define ADV_DIRECT_IND (0x01) + +/** + * scannable non connectable + */ +#define ADV_SCAN_IND (0x02) + +/** + * non-connectable and no scan response + */ +#define ADV_NONCONN_IND (0x03) + +/** + * scan response + */ +#define SCAN_RSP (0x04) + +/** + * @} + */ + +/* 0X05-0XFF RESERVED */ + +/** + * @name Advertising ranges + * @{ + */ + +/** + * lowest allowed interval value for connectable types(20ms)..multiple of 625us + */ +#define ADV_INTERVAL_LOWEST_CONN (0X0020) + +/** + * highest allowed interval value (10.24s)..multiple of 625us. + */ +#define ADV_INTERVAL_HIGHEST (0X4000) + +/** + * lowest allowed interval value for non connectable types + * (100ms)..multiple of 625us. + */ +#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) + +/** + * @} + */ + +/** + * @name Advertising channels + * @{ + */ +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 +/** + * @} + */ + +/** + * @name Scan_types Scan types + * @{ + */ +#define PASSIVE_SCAN 0 +#define ACTIVE_SCAN 1 +/** + * @} + */ + +/** + * @} + */ + + +#endif /* _BLE_LINK_LAYER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,47 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for linked list library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef _BLE_LIST_H_ +#define _BLE_LIST_H_ + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +uint8_t list_is_empty (tListNode * listHead); + +void list_insert_head (tListNode * listHead, tListNode * node); + +void list_insert_tail (tListNode * listHead, tListNode * node); + +void list_remove_node (tListNode * node); + +void list_remove_head (tListNode * listHead, tListNode ** node ); + +void list_remove_tail (tListNode * listHead, tListNode ** node ); + +void list_insert_node_after (tListNode * node, tListNode * ref_node); + +void list_insert_node_before (tListNode * node, tListNode * ref_node); + +int list_get_size (tListNode * listHead); + +void list_get_next_node (tListNode * ref_node, tListNode ** node); + +void list_get_prev_node (tListNode * ref_node, tListNode ** node); + +#endif /* _BLE_LIST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_OSAL_H__ +#define __BLE_OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __BLE_OSAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,158 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_sm.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's security manager. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_SM_H__ +#define __BLE_SM_H__ + +/****************************************************************************** +* Macros +*****************************************************************************/ + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/* IO capabilities */ +/** + * @anchor IO_capabilities + * @name IO capabilities + * @{ + */ +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define IO_CAP_KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) +/** + * @} + */ + +/** + * @anchor Auth_req + * @name Authentication requirements + * @{ + */ +#define BONDING (0x01) +#define NO_BONDING (0x00) +/** + * @} + */ + +/** + * @anchor MITM_req + * @name MITM protection requirements + * @{ + */ +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor OOB_Data + * @name Out-Of-Band data + * @{ + */ +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) +/** + * @} + */ + +/** + * @anchor Author_req + * @name Authorization requirements + * @{ + */ +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor Conn_authorization + * @name Connection authorization + * @{ + */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) +/** + * @} + */ + +/** + * @anchor Use_fixed_pin + * @name Use fixed pin + * @{ + */ +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +/** + * @} + */ + +/** + * @anchor link_security_status + * @name Link security status + * @{ + */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) +/** + * @} + */ + +/** + * @anchor SMP_pairing_failed_codes + * @name SMP pairing failed reason codes + * @{ + */ +#define PASSKEY_ENTRY_FAILED (0x01) +#define OOB_NOT_AVAILABLE (0x02) +#define AUTH_REQ_CANNOT_BE_MET (0x03) +#define CONFIRM_VALUE_FAILED (0x04) +#define PAIRING_NOT_SUPPORTED (0x05) +#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) +#define CMD_NOT_SUPPORTED (0x07) +#define UNSPECIFIED_REASON (0x08) +#define VERY_EARLY_NEXT_ATTEMPT (0x09) +#define SM_INVALID_PARAMS (0x0A) +/** + * @} + */ + +/** + * @anchor pairing_failed_codes + * @name Pairing failed error codes + * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event + * @{ + */ +#define SM_PAIRING_SUCCESS (0x00) +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,188 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_status.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file with BLE Stack status codes. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_STATUS_H__ +#define __BLE_STATUS_H__ + +#include <ble_hal_types.h> + +/** @addtogroup Middlewares + * @{ + */ + +/** @defgroup ST + * @{ + */ + +/** @defgroup SimpleBlueNRG_HCI + * @{ + */ + +/** @defgroup ble_status Bluetooth Status/Error Codes + * @{ + */ + +typedef uint8_t tBleStatus; + +/* Error Codes as specified by the specification + * according to the spec the error codes range + * from 0x00 to 0x3F + */ +/** + * @name Standard error codes + * @brief Standard error codes. See Core v 4.1, Vol. 2, part D. + * @{ + */ +#define ERR_CMD_SUCCESS (0x00) +#define BLE_STATUS_SUCCESS (0x00) +#define ERR_UNKNOWN_HCI_COMMAND (0x01) +#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) + +#define ERR_AUTH_FAILURE (0x05) +#define ERR_PIN_OR_KEY_MISSING (0x06) +#define ERR_MEM_CAPACITY_EXCEEDED (0x07) +#define ERR_CONNECTION_TIMEOUT (0x08) + +#define ERR_COMMAND_DISALLOWED (0x0C) + +#define ERR_UNSUPPORTED_FEATURE (0x11) +#define ERR_INVALID_HCI_CMD_PARAMS (0x12) +#define ERR_RMT_USR_TERM_CONN (0x13) +#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) +#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) +#define ERR_LOCAL_HOST_TERM_CONN (0x16) + +#define ERR_UNSUPP_RMT_FEATURE (0x1A) + +#define ERR_INVALID_LMP_PARAM (0x1E) +#define ERR_UNSPECIFIED_ERROR (0x1F) + +#define ERR_LL_RESP_TIMEOUT (0x22) +#define ERR_LMP_PDU_NOT_ALLOWED (0x24) + +#define ERR_INSTANT_PASSED (0x28) + +#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) +#define ERR_CONTROLLER_BUSY (0x3A) + +#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) + +#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) + +#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) + + +/** + * @} + */ +/** + * @name Vendor-specific error codes + * @brief Error codes defined by ST related to BlueNRG stack + * @{ + */ +/** + * The command cannot be executed due to the current state of the device. + */ +#define BLE_STATUS_FAILED (0x41) +/** + * Some parameters are invalid. + */ +#define BLE_STATUS_INVALID_PARAMS (0x42) +/** + * It is not allowed to start the procedure (e.g. another the procedure is ongoing + * or cannot be started on the given handle). + */ +#define BLE_STATUS_NOT_ALLOWED (0x46) +/** + * Unexpected error. + */ +#define BLE_STATUS_ERROR (0x47) +#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) + +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +#define BLE_STATUS_INVALID_CID (0x50) + +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) +#define BLE_STATUS_IRK_NOT_FOUND (0x5B) +#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) +#define BLE_STATUS_SEC_DB_FULL (0x5D) +#define BLE_STATUS_DEV_NOT_BONDED (0x5E) +#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) + +#define BLE_STATUS_INVALID_HANDLE (0x60) +#define BLE_STATUS_INVALID_PARAMETER (0x61) +#define BLE_STATUS_OUT_OF_HANDLE (0x62) +#define BLE_STATUS_INVALID_OPERATION (0x63) +#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) +#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) +#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) + +/** + * Returned when no valid slots are available (e.g. when there are no available state machines). + */ +#define BLE_STATUS_NO_VALID_SLOT (0x82) + +/** + * Returned when a scan window shorter than minimum allowed value has been requested (i.e. 2ms) + */ + +#define BLE_STATUS_SCAN_WINDOW_SHORT (0x83) +/** + * Returned when the maximum requested interval to be allocated is shorter then the current + * anchor period and a there is no submultiple for the current anchor period that is between + * the minimum and the maximum requested intervals. + */ + +#define BLE_STATUS_NEW_INTERVAL_FAILED (0x84) +/** + * Returned when the maximum requested interval to be allocated is greater than the current anchor + * period and there is no multiple of the anchor period that is between the minimum and the maximum + * requested intervals. + */ + +#define BLE_STATUS_INTERVAL_TOO_LARGE (0x85) +/** + * Returned when the current anchor period or a new one can be found that is compatible to the + * interval range requested by the new slot but the maximum available length that can be allocated is + * less than the minimum requested slot length. + */ + +#define BLE_STATUS_LENGTH_FAILED (0x86) +/** + * @} + */ + +/** + * @name Library Error Codes + * @brief Error codes defined by ST related to MCU library. + * @{ + */ +#define BLE_STATUS_TIMEOUT (0xFF) +#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) +#define BLE_STATUS_NULL_PARAM (0xF1) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,813 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci_const.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with ACI definitions for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_CONST_H_ +#define __BLUENRG_ACI_CONST_H_ + +#include "ble_compiler.h" +#include "ble_link_layer.h" +#include "ble_hci_const.h" +#include "bluenrg_gatt_server.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define OCF_HAL_GET_FW_BUILD_NUMBER 0x0000 +typedef __packed struct _hal_get_fw_build_number_rp{ + uint8_t status; + uint16_t build_number; +} PACKED hal_get_fw_build_number_rp; +#define HAL_GET_FW_BUILD_NUMBER_RP_SIZE 3 +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +#define OCF_HAL_READ_CONFIG_DATA 0x000D +typedef __packed struct _hal_read_config_data_cp{ + uint8_t offset; +} PACKED hal_read_config_data_cp; +#define HAL_READ_CONFIG_DATA_RP_SIZE 1 +typedef __packed struct _hal_read_config_data_rp{ + uint8_t status; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE]; +} PACKED hal_read_config_data_rp; + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef __packed struct _hal_set_tx_power_level_cp{ + uint8_t en_high_power; + uint8_t pa_level; +} PACKED hal_set_tx_power_level_cp; +#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 + +#define OCF_HAL_DEVICE_STANDBY 0x0013 + +#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014 +typedef __packed struct _hal_le_tx_test_packet_number_rp{ + uint8_t status; + uint32_t number_of_packets; +} PACKED hal_le_tx_test_packet_number_rp; + +#define OCF_HAL_TONE_START 0x0015 +typedef __packed struct _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_HAL_TONE_STOP 0x0016 +#define OCF_HAL_GET_LINK_STATUS 0x0017 +typedef __packed struct _hal_get_link_status_rp{ + uint8_t status; + uint8_t link_status[8]; + uint16_t conn_handle[8]; +} PACKED hal_get_link_status_rp; + +#define OCF_HAL_GET_ANCHOR_PERIOD 0x0019 +typedef __packed struct _hal_get_anchor_period_rp{ + uint8_t status; + uint32_t anchor_period; + uint32_t max_free_slot; +} PACKED hal_get_anchor_period_rp; + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef __packed struct _get_updater_version_rp{ + uint8_t status; + uint8_t version; +} PACKED get_updater_version_rp; +#define GET_UPDATER_VERSION_RP_SIZE 2 + +#define OCF_GET_UPDATER_BUFSIZE 0x0023 +typedef __packed struct _get_updater_bufsize_rp{ + uint8_t status; + uint8_t buffer_size; +} PACKED get_updater_bufsize_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 + +#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 + +#define OCF_UPDATER_ERASE_SECTOR 0x0026 +typedef __packed struct _updater_erase_sector_cp{ + uint32_t address; +} PACKED updater_erase_sector_cp; +#define UPDATER_ERASE_SECTOR_CP_SIZE 4 + +#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 +#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_prog_data_block_cp{ + uint32_t address; + uint16_t data_len; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; +} PACKED updater_prog_data_block_cp; + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef __packed struct _updater_read_data_block_cp{ + uint32_t address; + uint16_t data_len; +} PACKED updater_read_data_block_cp; +#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[VARIABLE_SIZE]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef __packed struct _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef __packed struct _updater_calc_crc_rp{ + uint8_t status; + uint32_t crc; +} PACKED updater_calc_crc_rp; +#define UPDATER_CALC_CRC_RP_SIZE 5 + +#define OCF_UPDATER_HW_VERSION 0x002A +typedef __packed struct _updater_hw_version_rp{ + uint8_t status; + uint8_t version; +} PACKED updater_hw_version_rp; +#define UPDATER_HW_VERSION_RP_SIZE 2 + +#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 + +#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 + +#define OCF_GAP_SET_DISCOVERABLE 0x0083 + +#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 +typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ + uint8_t own_bdaddr_type; + uint8_t directed_adv_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint16_t adv_interv_min; + uint16_t adv_interv_max; +} PACKED gap_set_direct_conectable_cp_IDB05A1; + +typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB04A1; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef __packed struct _gap_set_io_capability_cp{ + uint8_t io_capability; +} PACKED gap_set_io_capability_cp; +#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 + +#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 +typedef __packed struct _gap_set_auth_requirement_cp{ + uint8_t mitm_mode; + uint8_t oob_enable; + uint8_t oob_data[16]; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t bonding_mode; +} PACKED gap_set_auth_requirement_cp; +#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 + +#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 +typedef __packed struct _gap_set_author_requirement_cp{ + uint16_t conn_handle; + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef __packed struct _gap_passkey_response_cp{ + uint16_t conn_handle; + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef __packed struct _gap_authorization_response_cp{ + uint16_t conn_handle; + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 + +#define OCF_GAP_INIT 0x008A +typedef __packed struct _gap_init_cp_IDB05A1{ + uint8_t role; + uint8_t privacy_enabled; + uint8_t device_name_char_len; +} PACKED gap_init_cp_IDB05A1; +#define GAP_INIT_CP_SIZE_IDB05A1 3 + +typedef __packed struct _gap_init_cp_IDB04A1{ + uint8_t role; +} PACKED gap_init_cp_IDB04A1; +#define GAP_INIT_CP_SIZE_IDB04A1 1 +typedef __packed struct _gap_init_rp{ + uint8_t status; + uint16_t service_handle; + uint16_t dev_name_char_handle; + uint16_t appearance_char_handle; +} PACKED gap_init_rp; +#define GAP_INIT_RP_SIZE 7 + +#define OCF_GAP_SET_NON_CONNECTABLE 0x008B +typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ + uint8_t advertising_event_type; + uint8_t own_address_type; +#endif +} PACKED gap_set_non_connectable_cp_IDB05A1; + +typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp_IDB04A1; + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef __packed struct _gap_set_undirected_connectable_cp{ + uint8_t adv_filter_policy; + uint8_t own_addr_type; +} PACKED gap_set_undirected_connectable_cp; +#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 + +#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D +typedef __packed struct _gap_slave_security_request_cp{ + uint16_t conn_handle; + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef __packed struct _gap_delete_ad_type_cp{ + uint8_t ad_type; +} PACKED gap_delete_ad_type_cp; +#define GAP_DELETE_AD_TYPE_CP_SIZE 1 + +#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 +typedef __packed struct _gap_get_security_level_rp{ + uint8_t status; + uint8_t mitm_protection; + uint8_t bonding; + uint8_t oob_data; + uint8_t passkey_required; +} PACKED gap_get_security_level_rp; +#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 + +#define OCF_GAP_SET_EVT_MASK 0x0091 +typedef __packed struct _gap_set_evt_mask_cp{ + uint16_t evt_mask; +} PACKED gap_set_evt_mask_cp; +#define GAP_SET_EVT_MASK_CP_SIZE 2 + +#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 + +#define OCF_GAP_TERMINATE 0x0093 +typedef __packed struct _gap_terminate_cp{ + uint16_t handle; + uint8_t reason; +} PACKED gap_terminate_cp; +#define GAP_TERMINATE_CP_SIZE 3 + +#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 + +#define OCF_GAP_ALLOW_REBOND_DB 0x0095 + +typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ + uint16_t conn_handle; +} PACKED gap_allow_rebond_cp_IDB05A1; + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef __packed struct _gap_start_limited_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_limited_discovery_proc_cp; +#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 +typedef __packed struct _gap_start_general_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_general_discovery_proc_cp; +#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 +typedef __packed struct _gap_start_name_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_name_discovery_proc_cp; +#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 + +#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 + +#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; + +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t use_reconn_addr; + tBDAddr reconn_addr; +} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; + +#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B +#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 +typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t num_whitelist_entries; + uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; +} PACKED gap_start_selective_conn_establish_proc_cp; + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef __packed struct _gap_create_connection_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_create_connection_cp; +#define GAP_CREATE_CONNECTION_CP_SIZE 24 + +#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D + +#define OCF_GAP_START_CONNECTION_UPDATE 0x009E +typedef __packed struct _gap_start_connection_update_cp{ + uint16_t conn_handle; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_connection_update_cp; +#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 + +#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F +typedef __packed struct _gap_send_pairing_request_cp{ + uint16_t conn_handle; + uint8_t force_rebond; +} PACKED gap_send_pairing_request_cp; +#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 + +#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 +typedef __packed struct _gap_resolve_private_address_cp{ + tBDAddr address; +} PACKED gap_resolve_private_address_cp; +#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 +typedef __packed struct _gap_resolve_private_address_rp{ + uint8_t status; + tBDAddr address; +} PACKED gap_resolve_private_address_rp; + +#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 +#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 +typedef __packed struct _gap_set_broadcast_mode_cp{ + uint16_t adv_interv_min; + uint16_t adv_interv_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; +} PACKED gap_set_broadcast_mode_cp; + +#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 +typedef __packed struct _gap_start_observation_proc_cp{ + uint16_t scan_interval; + uint16_t scan_window; + uint8_t scan_type; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_observation_proc_cp; + +#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 +typedef __packed struct _gap_get_bonded_devices_rp{ + uint8_t status; + uint8_t num_addr; + uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; +} PACKED gap_get_bonded_devices_rp; + +#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 +typedef __packed struct _gap_is_device_bonded_cp{ + uint8_t peer_address_type; + tBDAddr peer_address; +} PACKED gap_is_device_bonded_cp; + + +#define OCF_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef __packed struct _gatt_add_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_serv_rp; +#define GATT_ADD_SERV_RP_SIZE 3 + +#define OCF_GATT_INCLUDE_SERV 0x0103 +typedef __packed struct _gatt_include_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_include_serv_rp; +#define GATT_INCLUDE_SERV_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR 0x0104 +typedef __packed struct _gatt_add_char_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_rp; +#define GATT_ADD_CHAR_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR_DESC 0x0105 +typedef __packed struct _gatt_add_char_desc_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_desc_rp; +#define GATT_ADD_CHAR_DESC_RP_SIZE 3 + +#define OCF_GATT_UPD_CHAR_VAL 0x0106 + +#define OCF_GATT_DEL_CHAR 0x0107 +typedef __packed struct _gatt_del_char_cp{ + uint16_t service_handle; + uint16_t char_handle; +} PACKED gatt_del_char_cp; +#define GATT_DEL_CHAR_CP_SIZE 4 + +#define OCF_GATT_DEL_SERV 0x0108 +typedef __packed struct _gatt_del_serv_cp{ + uint16_t service_handle; +} PACKED gatt_del_serv_cp; +#define GATT_DEL_SERV_CP_SIZE 2 + +#define OCF_GATT_DEL_INC_SERV 0x0109 +typedef __packed struct _gatt_del_inc_serv_cp{ + uint16_t service_handle; + uint16_t inc_serv_handle; +} PACKED gatt_del_inc_serv_cp; +#define GATT_DEL_INC_SERV_CP_SIZE 4 + +#define OCF_GATT_SET_EVT_MASK 0x010A +typedef __packed struct _gatt_set_evt_mask_cp{ + uint32_t evt_mask; +} PACKED gatt_set_evt_mask_cp; +#define GATT_SET_EVT_MASK_CP_SIZE 4 + +#define OCF_GATT_EXCHANGE_CONFIG 0x010B +typedef __packed struct _gatt_exchange_config_cp{ + uint16_t conn_handle; +} PACKED gatt_exchange_config_cp; +#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 + +#define OCF_ATT_FIND_INFO_REQ 0x010C +typedef __packed struct _att_find_info_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED att_find_info_req_cp; +#define ATT_FIND_INFO_REQ_CP_SIZE 6 + +#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D +#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 +typedef __packed struct _att_find_by_type_value_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[2]; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU - 7]; +} PACKED att_find_by_type_value_req_cp; + +#define OCF_ATT_READ_BY_TYPE_REQ 0x010E +#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_type_req_cp; + +#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F +#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_group_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_group_type_req_cp; + +#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 +#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val +typedef __packed struct _att_prepare_write_req_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t value_offset; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU-5]; +} PACKED att_prepare_write_req_cp; + +#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 +typedef __packed struct _att_execute_write_req_cp{ + uint16_t conn_handle; + uint8_t execute; +} PACKED att_execute_write_req_cp; +#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 + +#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 +typedef __packed struct _gatt_disc_all_prim_serivces_cp{ + uint16_t conn_handle; +} PACKED gatt_disc_all_prim_services_cp; +#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 + +#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 +typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ + uint16_t conn_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_disc_prim_service_by_uuid_cp; +#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid + +#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 +typedef __packed struct _gatt_disc_find_included_services_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED gatt_find_included_services_cp; +#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 + +#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 +typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ + uint16_t conn_handle; + uint16_t start_attr_handle; + uint16_t end_attr_handle; +} PACKED gatt_disc_all_charac_of_serv_cp; +#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 + +#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 + +#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ + uint16_t conn_handle; + uint16_t char_val_handle; + uint16_t char_end_handle; +} PACKED gatt_disc_all_charac_descriptors_cp; +#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 + +#define OCF_GATT_READ_CHARAC_VAL 0x0118 +typedef __packed struct _gatt_read_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_val_cp; +#define GATT_READ_CHARAC_VAL_CP_SIZE 4 + +#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 +typedef __packed struct _gatt_read_using_charac_uuid_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_read_using_charac_uuid_cp; +#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID + +#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A +typedef __packed struct _gatt_read_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_val_cp; +#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 + +#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B +#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles +typedef __packed struct _gatt_read_multiple_charac_val_cp{ + uint16_t conn_handle; + uint8_t num_handles; + uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_read_multiple_charac_val_cp; + +#define OCF_GATT_WRITE_CHAR_VALUE 0x011C + +#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D +#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_write_long_charac_val_cp; + +#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E +#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_charac_reliable_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; +} PACKED gatt_write_charac_reliable_cp; + +#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F +#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; +} PACKED gatt_write_long_charac_desc_cp; + +#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 +typedef __packed struct _gatt_read_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_desc_cp; +#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 + +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 +typedef __packed struct _gatt_read_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_desc_cp; +#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 +#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 3]; +} PACKED gatt_write_without_resp_cp; + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 +#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_signed_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 13]; +} PACKED gatt_signed_write_without_resp_cp; + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 +typedef __packed struct _gatt_confirm_indication_cp{ + uint16_t conn_handle; +} PACKED gatt_confirm_indication_cp; +#define GATT_CONFIRM_INDICATION_CP_SIZE 2 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef __packed struct _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 +typedef __packed struct _gatt_set_security_permission_cp{ + uint16_t service_handle; + uint16_t attr_handle; + uint8_t security_permission; +} PACKED gatt_set_security_permission_cp; +#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_GATT_READ_HANDLE_VALUE 0x012A +typedef __packed struct _gatt_read_handle_val_cp{ + uint16_t attr_handle; +} PACKED gatt_read_handle_val_cp; +#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 +typedef __packed struct _gatt_read_handle_val_rp{ + uint8_t status; + uint16_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; +} PACKED gatt_read_handle_val_rp; + +#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B +typedef __packed struct _gatt_read_handle_val_offset_cp{ + uint16_t attr_handle; + uint8_t offset; +} PACKED gatt_read_handle_val_offset_cp; +#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 +typedef __packed struct _gatt_read_handle_val_offset_rp{ + uint8_t status; + uint8_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; +} PACKED gatt_read_handle_val_offset_rp; + +#define OCF_GATT_UPD_CHAR_VAL_EXT 0x012C +#define GATT_UPD_CHAR_VAL_EXT_CP_SIZE 10 // without value +typedef __packed struct _gatt_upd_char_val_ext_cp{ + uint16_t service_handle; + uint16_t char_handle; + uint8_t update_type; + uint16_t char_length; + uint16_t value_offset; + uint8_t value_length; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_UPD_CHAR_VAL_EXT_CP_SIZE]; +} PACKED gatt_upd_char_val_ext_cp; + +#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 +typedef __packed struct _l2cap_conn_param_update_req_cp{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_update_req_cp; +#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 + +#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint16_t min_ce_length; + uint16_t max_ce_length; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; + +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; + +/** + * @defgroup BlueNRG_Events BlueNRG events (vendor specific) + * @{ + */ + +/** + * Vendor specific event for BlueNRG. + */ +typedef __packed struct _evt_blue_aci{ + uint16_t ecode; /**< One of the BlueNRG event codes. */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_blue_aci; + + +/** + * @} + */ + +#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gap.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GAP layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BNRG_GAP_H__ +#define __BNRG_GAP_H__ + +#include <ble_link_layer.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + * @name GAP UUIDs + * @{ + */ +#define GAP_SERVICE_UUID (0x1800) +#define DEVICE_NAME_UUID (0x2A00) +#define APPEARANCE_UUID (0x2A01) +#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) +#define RECONNECTION_ADDR_UUID (0x2A03) +#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) +/** + * @} + */ + +/** + * @name Characteristic value lengths + * @{ + */ +#define DEVICE_NAME_CHARACTERISTIC_LEN (8) +#define APPEARANCE_CHARACTERISTIC_LEN (2) +#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) +#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) +#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) +/** + * @} + */ + +/*------------- AD types for adv data and scan response data ----------------*/ + +/** + * @defgroup AD_Types AD Types + * @brief AD Types + * @{ + */ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +/** + * @anchor Flags_AD_Type_bits + * @name Flags AD Type bits + * @brief Bits in Flags AD Type + * @{ + */ +#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) +#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) +#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) +#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) +#define FLAG_BIT_LE_BR_EDR_HOST (0x10) +/** + * @} + */ + +/** + * @name Service UUID AD types + * @{ + */ +#define AD_TYPE_16_BIT_SERV_UUID (0x02) +#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) +#define AD_TYPE_32_BIT_SERV_UUID (0x04) +#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) +#define AD_TYPE_128_BIT_SERV_UUID (0x06) +#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) +/** + * @} + */ + +/* LOCAL NAME AD types */ +/** + * @name Local name AD types + * @{ + */ +#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) +#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) +/** + * @} + */ + +/* TX power level AD type*/ +#define AD_TYPE_TX_POWER_LEVEL (0x0A) + +/* Class of device */ +#define AD_TYPE_CLASS_OF_DEVICE (0x0D) + +/* security manager TK value AD type */ +#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) + +/* security manager OOB flags */ +#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) + +/* slave connection interval AD type */ +#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) + +/* service solicitation UUID list Ad types*/ +/** + * @name Service solicitation UUID list AD types + * @{ + */ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) +#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) +/** + * @} + */ + +/* service data AD type */ +#define AD_TYPE_SERVICE_DATA (0x16) + +/* manufaturer specific data AD type */ +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/* appearance AD type */ +#define AD_TYPE_APPEARANCE (0x19) + +/* advertising interval AD type */ +#define AD_TYPE_ADVERTISING_INTERVAL (0x1A) + +/** + * @} + */ + +#define MAX_ADV_DATA_LEN (31) + +#define DEVICE_NAME_LEN (7) +#define BD_ADDR_SIZE (6) + +/** + * @name Privacy flag values + * @{ + */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) +/** + * @} + */ + +/** + * @name Intervals + * Intervals in terms of 625 micro sec + * @{ + */ +#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ +#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ +#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ +#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ +#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ +#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ +#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ +#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ +/** + * @} + */ + +/** + * @name Timeout values + * @{ + */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ +/** + * @} + */ + +/** + * @anchor gap_roles + * @name GAP Roles + * @{ +*/ +#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) +#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) + +#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) +#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) +/** + * @} + */ + +/** + * @anchor gap_procedure_codes + * @name GAP procedure codes + * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event + * and aci_gap_terminate_gap_procedure() command. + * @{ + */ +#define GAP_LIMITED_DISCOVERY_PROC (0x01) +#define GAP_GENERAL_DISCOVERY_PROC (0x02) +#define GAP_NAME_DISCOVERY_PROC (0x04) +#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) +#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) +#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) +#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) +#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1231 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gap_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GAP_ACI_H__ +#define __BLUENRG_GAP_ACI_H__ + +/** + *@addtogroup GAP GAP + *@brief GAP layer. + *@{ + */ + +/** + *@defgroup GAP_Functions GAP functions + *@brief API for GAP layer. + *@{ + */ + +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". + * @param privacy_enabled Enable (1) or disable (0) privacy. + * @param device_name_char_len Length of the device name characteristic + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, + uint8_t device_name_char_len, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Privacy Flag (peripheral role only) + * @li Reconnection Address (peripheral role only) + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB04A1(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); + +/** + * @brief Set the Device in non-discoverable mode. + * @note This command will disable the LL advertising. + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_discoverable(void); + +/** + * @brief Put the device in limited discoverable mode + * (as defined in GAP specification volume 3, section 9.2.3). + * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. + * The advertising can be disabled at any time by issuing + * aci_gap_set_non_discoverable() command. + * The AdvIntervMin and AdvIntervMax parameters are optional. If both + * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). + * Host can set the Local Name, a Service UUID list and the Slave Connection + * Minimum and Maximum. If provided, these data will be inserted into the + * advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() + * separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following + * standard AD types: + * @li AD Flags + * @li TX Power Level + * + * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates + * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. + * + * Example: + * @code + * + * #define ADV_INTERVAL_MIN_MS 100 + * #define ADV_INTERVAL_MAX_MS 200 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, + * (ADV_INTERVAL_MAX_MS*1000)/0.625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * sizeof(serviceUUIDList), serviceUUIDList, + * 0, 0); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 250 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 500 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg NO_WHITE_LIST_USE + * @arg WHITE_LIST_FOR_ONLY_SCAN + * @arg WHITE_LIST_FOR_ONLY_CONN + * @arg WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +/** + * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4). + * @note The device will be discoverable until the Host issue Aci_Gap_Set_Non_Discoverable command. + * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses + * the default values for advertising intervals (1.28 s and 2.56 s respectively for IDB04A1). + * When using connectable undirected advertising events:\n + * @li Adv_Interval_Min = 30 ms + * @li Adv_Interval_Max = 60 ms + * \nWhen using non-connectable advertising events or scannable undirected advertising events:\n + * @li Adv_Interval_Min = 100 ms + * @li Adv_Interval_Max = 150 ms + * Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided, + * these data will be inserted into the advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following standard AD types: + * @li AD Flags + * @li TX Power Level + * + * Usage example: + * + * @code + * + * #define ADV_INTERVAL_MIN_MS 800 + * #define ADV_INTERVAL_MAX_MS 900 + * #define CONN_INTERVAL_MIN_MS 100 + * #define CONN_INTERVAL_MAX_MS 300 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625, + * (ADV_INTERVAL_MAX_MS*1000)/625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * 0, NULL, + * (CONN_INTERVAL_MIN_MS*1000)/1250, + * (CONN_INTERVAL_MAX_MS*1000)/1250); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 1.28 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 2.56 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ONLY_SCAN + * @arg @ref WHITE_LIST_FOR_ONLY_CONN + * @arg @ref WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); + +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @param adv_interv_min Minimum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @param adv_interv_max Maximum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max); +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); + +/** + * @brief Set the IO capabilities of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param io_capability One of the allowed codes for IO Capability: + * @arg @ref IO_CAP_DISPLAY_ONLY + * @arg @ref IO_CAP_DISPLAY_YES_NO + * @arg @ref IO_CAP_KEYBOARD_ONLY + * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT + * @arg @ref IO_CAP_KEYBOARD_DISPLAY + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_io_capability(uint8_t io_capability); + +/** + * @brief Set the authentication requirements for the device. + * @note If the oob_enable is set to 0, oob_data will be ignored. + * This command has to be given only when the device is not in a connected state. + * @param mitm_mode MITM mode: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @param oob_enable If OOB data are present or not: + * @arg @ref OOB_AUTH_DATA_ABSENT + * @arg @ref OOB_AUTH_DATA_PRESENT + * @param oob_data Out-Of-Band data + * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process + * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process + * @param use_fixed_pin If application wants to use a fixed pin or not: + * @arg @ref USE_FIXED_PIN_FOR_PAIRING + * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING + * If a fixed pin is not used, it has to be provided by the application with + * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will + * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is + * accepted. + * @param bonding_mode One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode); + /** + * @brief Set the authorization requirements of the device. + * @note This command has to be given when connected to a device if authorization is required to access services + * which require authorization. + * @param conn_handle Handle of the connection. + * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required + * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables + * the authorization requirement in the device and when a remote device + * tries to read/write a characeristic with authorization requirements, the stack will + * send back an error response with "Insufficient authorization" error code. + * After pairing is complete a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event + * will be sent to the Host. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); + +/** + * @brief Provide the pass key that will be used during pairing. + * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param conn_handle Connection handle + * @param passkey Pass key that will be used during the pairing process. Must be a number between + * 0 and 999999. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); + +/** + * @brief Authorize a device to access attributes. + * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. + * + * @param conn_handle Connection handle + * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) + * @arg @ref CONNECTION_REJECTED : Reject (reject connection) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); + +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @param own_address_type If Privacy is disabled, then the peripheral address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the peripheral address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); + +/** + * @brief Put the device into undirected connectable mode. + * @note If privacy is enabled in the device, a resolvable private address is generated and used + * as the advertiser's address. If not, the address of the type specified in own_addr_type + * is used for advertising. + * @param own_addr_type Type of our address used during advertising: + * if BLUENRG (IDB04A1) + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * else if BLUENRG_MS (IDB05A1) + * If Privacy is disabled: + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled: + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_filter_policy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ALL + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); + +/** + * @brief Send a slave security request to the master. + * @note This command has to be issued to notify the master of the security requirements of the slave. + * The master may encrypt the link, initiate the pairing procedure, or reject the request. + * @param conn_handle Connection handle + * @param bonding One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @param mitm_protection If MITM protection is required or not: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); + +/** + * @brief Update advertising data. + * @note This command can be used to update the advertising data for a particular AD type. + * If the AD type specified does not exist, then it is added to the advertising data. + * If the overall advertising data length is more than 31 octets after the update, then + * the command is rejected and the old data is retained. + * @param AdvLen Length of AdvData array + * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification + * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. + * Example + * @code + * tBleStatus ret; + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; + * + * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * 8, local_name, 3, serviceUUIDList, 0, 0); + * ret = aci_gap_update_adv_data(5, manuf_data); + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); + +/** + * @brief Delete an AD Type + * @note This command can be used to delete the specified AD type from the advertisement data if + * present. + * @param ad_type One of the allowed AD types (see @ref AD_Types) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); + +/** + * @brief Get the current security settings + * @note This command can be used to get the current security settings of the device. + * @param mitm_protection @arg 0: Not required + * @arg 1: Required + * @param bonding @arg 0: No bonding mode + * @arg 1: Bonding mode + * @param oob_data @arg 0: Data absent + * @arg 1: Data present + * @param passkey_required @arg 0: Not required + * @arg 1: Fixed pin is present which is being used + * @arg 2: Passkey required for pairing. An event will be generated + * when required. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required); + +/** + * @brief Add addresses of bonded devices into the controller's whitelist. + * @note The command will return an error if there are no devices in the database or if it was unable + * to add the device into the whitelist. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_configure_whitelist(void); + +/** + * @brief Terminate a connection. + * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. + * @param conn_handle Connection handle + * @param reason Reason for requesting disconnection. The error code can be any of ones as specified + * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); + +/** + * @brief Clear the security database. + * @note All the devices in the security database will be removed. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_clear_security_database(void); + +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @param conn_handle + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB04A1(void); + +/** + * @brief Start the limited discovery procedure. + * @note The controller is commanded to start active scanning. When this procedure is started, + * only the devices in limited discoverable mode are returned to the upper layers. + * The procedure is terminated when either the upper layers issue a command to terminate the + * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code + * set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated + * due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC. + * The device found when the procedure is ongoing is returned to the upper layers through the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the general discovery procedure. + * @note The controller is commanded to start active scanning. The procedure is terminated when + * either the upper layers issue a command to terminate the procedure by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC + * or a timeout happens. When the procedure is terminated due to any of the above reasons, + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to + * @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to + * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the name discovery procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. Once a connection is established, GATT procedure is started to read the + * device name characteristic. When the read is completed (successfully or unsuccessfully), + * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also + * contains the name of the device if the device name was read successfully. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Start the auto connection establishment procedure. + * @note The devices specified are added to the white list of the controller and a LE_Create_Connection + * call will be made to the controller by GAP with the initiator filter policy set to + * use whitelist to determine which advertiser to connect to. When a command is issued to + * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the + * controller by GAP. + * The procedure is terminated when either a connection is successfully established with one of + * the specified devices in the white list or the procedure is explicitly terminated by issuing + * the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start a general connection establishment procedure. + * @note The host enables scanning in the controller with the scanner filter policy set + * to accept all advertising packets and from the scanning results all the devices + * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * The upper layer then has to select one of the devices to which it wants to connect + * by issuing the command aci_gap_create_connection(). The procedure is terminated + * when a connection is established or the upper layer terminates the procedure by + * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates); +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); + +/** + * @brief Start a selective connection establishment procedure. + * @note The GAP adds the specified device addresses into white list and enables scanning in + * the controller with the scanner filter policy set to accept packets only from + * devices in whitelist. All the devices found are sent to the upper layer by the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the + * devices to which it wants to connect by issuing the command aci_gap_create_connection(). + * On completion of the procedure a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated + * with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * The procedure is terminated when a connection is established or the upper layer terminates + * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure + * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start the direct connection establishment procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. The procedure can be terminated explicitly by the upper layer by issuing + * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the + * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller + * by GAP. + * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can + * be explicitly terminated by the upper layer by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is + * returned with the procedure code set to the corresponding procedure. + * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes"). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); + +/** + * @brief Start the connection parameter update procedure. + * @note Allowed by the Central to update the connection parameter of the specified connection. + * A Link Layer Connection Update procedure is started on the controller. + * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to + * the upper layer. + * @param conn_handle Handle of the connection for which the update procedure has to be started. + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Send a pairing request. + * @note Send the SM pairing request to start a pairing process from a Central. The authentication + * requirements and IO capabilities should be set before issuing this command using + * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). + * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. + * @param conn_handle Handle of the connection for which the pairing request has to be sent. + * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded + * @arg 0x01: Pairing request will be sent even if the device was previously bonded + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param[in] address Address to be resolved. + * @param[out] actual_address The public or static random address of the peer device, distributed during pairing phase. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); + +/** + * @brief This command gets the list of bonded devices. + * @note It returns the number of addresses and the corresponding address types and values. + * Example: + * @code + * tBleStatus ret; + * uint8_t num_devices = 0; + * uint8_t device_list[12*7]; + * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); + * for(int i = 0; i < num_devices; i+=7){ + * uint8_t addr_type = device_list[i]; + * uint8_t addr = device_list[i+1]; + * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); + * } + * @endcode + * + * @param[out] num_devices The number of bonded devices. + * @param[out] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address + * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. + * @param device_list_size Maximum size of the device_list buffer used to return the device list. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); + +/** + * @brief Puts the device into broadcast mode + * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address + * as specified in the own_addr_type parameter of the command. + * @param adv_interv_min Minimum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_interv_max Maximum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param own_addr_type If Privacy is disabled, the broadcaster address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the broadcaster address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_data_length Length of the advertising data in the advertising packet + * @param adv_data Advertising data used by the device while advertising + * @param num_whitelist_entries Number of devices to be added to whitelist + * @param addr_array It will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Starts an observation procedure, when the device is in Observer role. + * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer + * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth + * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. + * The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. + * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param own_address_type If Privacy is disabled, then the scanner address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the scanner address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates); + +/** + * @brief The command finds whether a device is bonded. + * @note If the device is using a resolvable private address and it has been bonded, then the command will return + * BLE_STATUS_SUCCESS. + * @param peer_address_type The address type of the peer device + * @arg @ref PUBLIC_ADDR. + * @arg @ref RANDOM_ADDR. + * @param peer_address Address used by the peer device while advertising. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address); + + +/** + * @} + */ + +/** + * @defgroup GAP_Events GAP events + * @{ + */ + +/** + * This event is generated by the controller when the limited discoverable + * mode ends due to timeout (180 seconds). No parameters in the event. + */ +#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) + + +/** + * This event is generated when the pairing process has completed successfully + * or a pairing procedure timeout has occurred or the pairing has failed. + * This is to notify the application that we have paired with a remote device + * so that it can take further actions or to notify that a timeout has occurred + * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. + */ +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +typedef __packed struct _evt_gap_pairing_cmplt{ + uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ + /** + * 0x00: Pairing Success. Pairing with a remote device was successful\n + * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n + * 0x02: Pairing Failed. The pairing failed with the remote device. + */ + uint8_t status; +} PACKED evt_gap_pairing_cmplt; + + +/** + * This event is generated by the Security manager to the application when a pass key is required for pairing. + * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. + * See @ref _evt_gap_pass_key_req. + */ +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +typedef __packed struct _evt_gap_pass_key_req{ + uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ +} PACKED evt_gap_pass_key_req; + + +/** + * This event is generated by the Security manager to the application when the application + * has set that authorization is required for reading/writing of attributes. This event will + * be generated as soon as the pairing is complete. When this event is received, + * aci_gap_authorization_response() command should be used by the application. + * See @ref _evt_gap_author_req. + */ +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +typedef __packed struct _evt_gap_author_req{ + uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ +} PACKED evt_gap_author_req; + +/** + * This event is generated when the slave security request is successfully sent to the master. + * No parameters for this event. + */ +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) + +/** + * This event is generated on the slave when a aci_gap_slave_security_request() is called to reestablish the bond + * with a master but the master has lost the bond. When this event is received, the upper layer has to issue the + * command aci_gap_allow_rebond() in order to allow the slave to continue the pairing process with the master. + * On the master this event is raised when aci_gap_send_pairing_request() is called to reestablish a bond with a slave + * but the slave has lost the bond. In order to create a new bond the master has to launch aci_gap_send_pairing_request() + * with force_rebond set to 1. + * No parameters for this event + */ +#define EVT_BLUE_GAP_BOND_LOST (0X0405) + +/** + * The event is given by the GAP layer to the upper layers when a device is discovered during scanning + * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. + */ +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef __packed struct _evt_gap_device_found{ + uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ + uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ + tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ + uint8_t data_length; /**< Length of advertising or scan response data. */ + uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ +} PACKED evt_gap_device_found; + +/** + * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated + * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. + */ +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef __packed struct _evt_gap_procedure_complete{ + uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ + /** + * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed + * due to authentication requirements). + */ + uint8_t status; + /** + * Procedure specific data.\n + * @li For Name Discovery Procedure:\n + * the name of the peer device if the procedure completed successfully. + * @li For General Connection Establishment Procedure:\n + * The reconnection address written to the peripheral device if the peripheral is privacy enabled + */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_gap_procedure_complete; + +/** + * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral + * is not able to resolve the private address of the peer device after connecting to it. + */ +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) +typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ + uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ +} PACKED evt_gap_addr_not_resolved_IDB05A1; +/** + * This event is raised when the reconnection address is generated during the general connection + * establishment procedure. The same address is set into the peer device also as a part of the general + * connection establishment procedure. In order to make use of the reconnection address the next time + * while connecting to the bonded peripheral, the application needs to use this reconnection address + * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() + * and aci_gap_start_auto_conn_establish_proc(). + */ +#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) +typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ + uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ +} PACKED evt_gap_reconnection_addr_IDB04A1; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1128 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GATT_ACI_H__ +#define __BLUENRG_GATT_ACI_H__ + +#include "bluenrg_gatt_server.h" + +/** + *@addtogroup GATT GATT + *@brief GATT layer. + *@{ + */ + +/** + *@defgroup GATT_Functions GATT functions + *@brief API for GATT layer. + *@{ + */ + +/** + * @brief Initialize the GATT layer for server and client roles. + * @note It adds also the GATT service with Service Changed Characteristic. + * Until this command is issued the GATT channel will not process any commands + * even if the connection is opened. This command has to be given + * before using any of the GAP features. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_init(void); + +/** + * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs + * to reserve the handle ranges for this service using max_attr_records parameter. This + * parameter specifies the maximum number of attribute records that can be added to this + * service (including the service attribute, include attribute, characteristic attribute, + * characteristic value attribute and characteristic descriptor attribute). Handle of the + * created service is returned. + * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors + * are allocated from the attribute pool. + * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field + * @param service_type Primary or secondary service. See @ref Service_type "Service Type". + * @param max_attr_records Maximum number of attribute records that can be added to this service + * (including the service declaration itself) + * @param[out] serviceHandle Handle of the Service. When this service is added to the service, + * a handle is allocated by the server to this service. Server also + * allocates a range of handles for this service from serviceHandle to + * <serviceHandle + max_attr_records>. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, + const uint8_t* service_uuid, + uint8_t service_type, + uint8_t max_attr_records, + uint16_t *serviceHandle); + +/** + * @brief Include a service given by included_start_handle and included_end_handle to another service + * given by service_handle. Attribute server creates an INCLUDE definition attribute and return + * the handle of this attribute in included_handle. + * @param service_handle Handle of the service to which another service has to be included + * @param included_start_handle Start Handle of the service which has to be included in service + * @param included_end_handle End Handle of the service which has to be included in service + * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". + * @param[in] included_uuid 16-bit or 128-bit UUID. + * @param[out] included_handle Handle of the include declaration. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle); + +/** + * @brief Add a characteristic to a service. + * @param serviceHandle Handle of the service to which the characteristic has to be added. + * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param charUuid 16-bit or 128-bit UUID. + * @param charValueLen Maximum length of the characteristic value. + * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, + * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". + * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @arg GATT_DONT_NOTIFY_EVENTS + * @arg GATT_NOTIFY_ATTRIBUTE_WRITE + * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP + * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. + * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client + * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE + * properties. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle); + +/** + * Add a characteristic descriptor to a service. + * @param serviceHandle Handle of the service to which the characteristic belongs + * @param charHandle Handle of the characteristic to which description has to be added. + * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG + * (Well_known_UUIDs) or a user-defined one. + * @param descValueMaxLen The maximum length of the descriptor value + * @param descValueLen Current Length of the characteristic descriptor value + * @param[in] descValue Value of the characteristic description + * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". + * @arg ATTR_NO_ACCESS + * @arg ATTR_ACCESS_READ_ONLY + * @arg ATTR_ACCESS_WRITE_REQ_ONLY + * @arg ATTR_ACCESS_READ_WRITE + * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE + * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param[out] descHandle Handle of the Characteristic Descriptor. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle); + +/** + * @brief Update a characteristic value in a service. + * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. The command is queued into the + * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, + * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or + * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate + * than what is allowed by the link. Throughput on BLE link depends on connection interval and + * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() + * for more info on how to suggest new connection parameters from a slave). If the application does not + * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function + * returns @ref BLE_STATUS_SUCCESS or any other error code.\n + * Example:\n + * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some + * notifications will be lost. + * @code + * tBleStatus Free_Fall_Notify(void) + * { + * uint8_t val; + * tBleStatus ret; + * + * val = 0x01; + * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); + * + * if (ret != BLE_STATUS_SUCCESS){ + * PRINTF("Error while updating FFall characteristic.\n") ; + * return BLE_STATUS_ERROR ; + * } + * return BLE_STATUS_SUCCESS; + * } + * @endcode + * Here if BlueNRG buffer become full, the application try again to send the notification. + * @code + * struct timer t; + * Timer_Set(&t, CLOCK_SECOND*10); + * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ + * // Radio is busy (buffer full). + * if(Timer_Expired(&t)) + * break; + * } + * @endcode + * + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic + * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, + * and the attribute value is of variable length, then the length of the attribute will + * be set to the charValueLen. If the charValOffset is set to a value greater than 0, + * then the length of the attribute will be set to the maximum length as specified for + * the attribute while adding the characteristic. + * @param charValueLen Length of the characteristic value in octets + * @param[in] charValue Characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue); +/** + * @brief Delete the specified characteristic from the service. + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); + +/** + * @brief Delete the specified service from the GATT server database. + * @param servHandle Handle of the service to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_service(uint16_t servHandle); + +/** + * @brief Delete the Include definition from the service. + * @param servHandle Handle of the service to which Include definition belongs + * @param includeServHandle Handle of the Included definition to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); + +/** + * @brief Perform an ATT MTU exchange procedure. + * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP + * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated + * to indicate the end of the procedure. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); + +/** + * @brief Send a @a Find @a Information @a Request. + * @note This command is used to obtain the mapping of attribute handles with their associated + * types. The responses of the procedure are given through the + * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by + * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range of attributes to be discovered on the server + * @param end_handle Ending handle of the range of attributes to be discovered on the server + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send a @a Find @a By @a Type @a Value @a Request + * @note The Find By Type Value Request is used to obtain the handles of attributes that + * have a given 16-bit UUID attribute type and a given attribute value. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid 2 octet UUID to find (little-endian) + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). + * @param attr_val Attribute value to find + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send a @a Read @a By @a Type @a Request + * @note The Read By Type Request is used to obtain the values of attributes where the attribute type + * is known but the handle is not known. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Read @a By @a Group @a Type @a Request + * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute + * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping + * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Prepare @a Write @a Request + * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param attr_handle The handle of the attribute to be written + * @param value_offset The offset of the first octet to be written + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). + * @param attr_val The value of the attribute to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send an @a Execute @a Write @a Request + * @note The Execute Write Request is used to request the server to write or cancel the write of all the + * prepared values currently held in the prepare queue from this client. + * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param execute @arg 0x00 Cancel all prepared writes + * @arg 0x01 Immediately write all pending prepared values. + * @return Value indicating success or error code. + */ +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); + +/** + * @brief This command will start the GATT client procedure to discover all primary services on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +/** + * @brief Start the procedure to discover the primary services of the specified UUID on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to find all included services. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle Start handle of the service + * @param end_handle End handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Start the procedure to discover all the characteristics of a given service. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_attr_handle Start attribute handle of the service + * @param end_attr_handle End attribute handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +/** + * @brief Start the procedure to discover all the characteristics specified by a UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Start attribute handle of the service + * @param end_handle End attribute handle of the service + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); + +/** + * @brief Start the procedure to discover all characteristic descriptors on the server. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. + * @param conn_handle Connection handle for which the command is given. + * @param char_val_handle Starting handle of the characteristic + * @param char_end_handle End handle of the characteristic + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +/** + * @brief Start the procedure to read the attribute value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to read all the characteristics specified by the UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range to be searched + * @param end_handle End handle of the range to be searched + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start a procedure to read multiple characteristic values from a server. + * @note This sub-procedure is used to read multiple Characteristic Values from a server when the + * client knows the Characteristic Value Handles. + * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param num_handles The number of handles for which the value has to be read + * @param set_of_handles The handles for which the attribute value has to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles); + +/** + * @brief Start the procedure to write a characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to write a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start the procedure to write a characteristic reliably. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to write a long characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP + * event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic descriptor + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start the procedure to write a characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to read the descriptor specified. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the descriptor to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to write a characteristic value without waiting for any response from the server. + * @note No events are generated after this command is executed. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 3) + * @param[in] attr_val Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start a signed write without response from the server. + * @note The procedure i used to write a characteristic value with an authentication signature without waiting + * for any response from the server. It cannot be used when the link is encrypted. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 13). + * @param attr_val Value to be written + * @return Value indicating success or error code + */ +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Confirm an indication + * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); + +/** + * @brief Allow or reject a write request from a client. + * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, + * then the status has to be set to 1 and the error code has to be set to the error code that has to be + * passed to the client. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n + * 0x01: The value cannot be written to the attribute specified by the attr_handle. + * @param err_code The error code that has to be passed to the client in case the write has to be rejected. + * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val); + +/** + * @brief Allow the GATT server to send a response to a read request from a client. + * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ + * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response + * can be sent to the client. So if the application wishes to update any of the attributes before + * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value + * and then give this command. The application should perform the required operations within 30 seconds, + * otherwise the GATT procedure will go to timeout. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_allow_read(uint16_t conn_handle); + +/** + * @brief Set the security permission for the attribute handle specified. + * @note Currently the setting of security permission is allowed only for client configuration descriptor. + * @param service_handle Handle of the service which contains the attribute whose security + * permission has to be modified. + * @param attr_handle Handle of the attribute whose security permission has to be modified. + * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission); + +/** + * @brief This command sets the value of the descriptor specified by charDescHandle. + * @param servHandle Handle of the service which contains the descriptor. + * @param charHandle Handle of the characteristic which contains the descriptor. + * @param charDescHandle Handle of the descriptor whose value has to be set. + * @param charDescValOffset Offset from which the descriptor value has to be updated. + * @param charDescValueLen Length of the descriptor value + * @param[in] charDescValue descriptor value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue); + +/** + * @brief Reads the value of the attribute handle specified from the local GATT database. + * @param attr_handle Handle of the attribute to read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + + /** + * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. + * @param attr_handle Handle of the attribute to read + * @param offset Offset from which the value needs to be read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); +/** + * @brief Update the value of a characteristic and sends notifications or indications. + * @note This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute + * up to 512 bytes and indicate selectively the generation of indications and notifications. + * @param service_handle Handle of the service to which the characteristic belongs. + * @param char_handle Handle of the characteristic + * @param update_type Bitmask that controls generation of notifications and indications. It can be a combination + * @arg @ref NOTIFICATION (0x01): send notification, if enabled. + * @arg @ref INDICATION (0x02): send indication, if enabled. + * If set to 0 no notifications or indications are sent. + * @param char_length Total length of the characteristic value. In case of a variable size characteristic, + * this field specifies the new length of the characteristic value after the update; + * in case of fixed length characteristic this field is ignored. + * @param value_offset The offset from which the attribute value has to be updated + * @param value_length Length of the value to be updated + * @param[out] value Updated characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value); + +/** + * @} + */ + + +/** + * @defgroup GATT_Events GATT events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** + * This event (if enabled, see @ref Gatt_Event_Mask "Gatt Event Mask") is raised to the application + * by the GATT server when a client modifies any attribute on the server, as consequence of one of + * the following GATT procedures: + * @li write without response + * @li signed write without response + * @li write characteristic value + * @li write long characteristic value + * @li reliable write. + * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. + */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint16_t offset; /**< Offset from which the write has been performed by the peer device */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB05A1; + +typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB04A1; + +/** + * This event is generated by the client/server to the application on a GATT timeout (30 seconds). + * See @ref _evt_gatt_procedure_timeout. + */ +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +typedef __packed struct _evt_gatt_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ +} PACKED evt_gatt_procedure_timeout; + +/** + * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). + * See @ref _evt_att_exchange_mtu_resp. + */ +#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) +typedef __packed struct _evt_att_exchange_mtu_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data (always 1). */ + uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ +} PACKED evt_att_exchange_mtu_resp; + +/** + * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and + * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. + */ +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef __packed struct _evt_att_find_information_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ + /** + * A sequence of handle-uuid pairs.\n + * @li if format=1, each pair is:\n + * [2 octets for handle, 2 octets for UUIDs] \n + * @li if format=2, each pair is:\n + * [2 octets for handle, 16 octets for UUIDs] + */ + uint8_t handle_uuid_pair[VARIABLE_SIZE]; +} PACKED evt_att_find_information_resp; + +/** + * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See + * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. + */ +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +typedef __packed struct _evt_att_find_by_type_val_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + /** + * Handles Information List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] + */ + uint8_t handles_info_list[VARIABLE_SIZE]; +} PACKED evt_att_find_by_type_val_resp; + +/** + * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and + * aci_gatt_disc_all_charac_of_serv(). + * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. + */ +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef __packed struct _evt_att_read_by_type_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ + /** + * Attribute Data List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] + */ + uint8_t handle_value_pair[VARIABLE_SIZE]; +} PACKED evt_att_read_by_type_resp; + +/** + * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). + * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. + */ +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +typedef __packed struct _evt_att_read_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ +} PACKED evt_att_read_resp; + +/** + * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). + * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. + */ +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +typedef __packed struct _evt_att_read_blob_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ +} PACKED evt_att_read_blob_resp; + +/** + * This event is generated in response to a @a Read @a Multiple @a Request. + * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. + */ +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +typedef __packed struct _evt_att_read_mult_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ +} PACKED evt_att_read_mult_resp; + +/** + * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). + * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. + */ +#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) +typedef __packed struct _evt_att_read_by_group_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_data_length; /**< The size of each Attribute Data. */ + /** + * A list of Attribute Data where the attribute data is composed by: + * @li 2 octets for Attribute Handle + * @li 2 octets for End Group Handle + * @li (attribute_data_length - 4) octets for Attribute Value + */ + uint8_t attribute_data_list[VARIABLE_SIZE]; +} PACKED evt_att_read_by_group_resp; + +/** + * This event is generated in response to a @a Prepare @a Write @a Request. + * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. + */ +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +typedef __packed struct _evt_att_prepare_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attribute_handle; /**< The handle of the attribute to be written. */ + uint16_t offset; /**< The offset of the first octet to be written. */ + uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ +} PACKED evt_att_prepare_write_resp; + +/** + * This event is generated in response to an @a Execute @a Write @a Request. + * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. + */ +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +typedef __packed struct _evt_att_exec_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Always 0. */ +} PACKED evt_att_exec_write_resp; + +/** + * This event is generated when an indication is received from the server. + * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. + */ +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +typedef __packed struct _evt_gatt_indication{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_indication; + +/** + * This event is generated when a notification is received from the server. + * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. + */ +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef __packed struct _evt_gatt_notification{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_attr_notification; + +/** + * This event is generated when a GATT client procedure completes either with error or successfully. + * See @ref _evt_gatt_procedure_complete. + */ +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef __packed struct _evt_gatt_procedure_complete{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ + uint8_t data_length; /**< Length of error_code field (always 1). */ + /** + * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). + */ + uint8_t error_code; +} PACKED evt_gatt_procedure_complete; + +/** + * This event is generated when an Error Response is received from the server. The error response can be given + * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended + * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. + */ +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +typedef __packed struct _evt_gatt_error_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t req_opcode; /**< The request that generated this error response. */ + uint16_t attr_handle; /**< The attribute handle that generated this error response. */ + uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ +} PACKED evt_gatt_error_resp; + +/** + * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using + * Characteristic UUID" procedure. + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. + */ +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + /** + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. + */ + uint8_t attr_value[VARIABLE_SIZE]; +} PACKED evt_gatt_disc_read_char_by_uuid_resp; + +/** + * This event is given to the application when a write request, write command or signed write command + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * If the write is rejected by the application, then the value of the attribute will not be modified. + * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. + * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef __packed struct _evt_gatt_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_write_permit_req; + +/** + * This event is given to the application when a read request or read blob request is received by the server + * from the client. This event will be given to the application only if the event bit for this event generation + * is set when the characteristic was added. + * On receiving this event, the application can update the value of the handle if it desires and when done + * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef __packed struct _evt_gatt_read_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ + uint8_t data_length; /**< Length of offset field. */ + uint16_t offset; /**< Contains the offset from which the read has been requested */ +} PACKED evt_gatt_read_permit_req; + +/** + * This event is given to the application when a read multiple request or read by type request is received + * by the server from the client. This event will be given to the application only if the event bit for this + * event generation is set when the characteristic was added. + * On receiving this event, the application can update the values of the handles if it desires and when done + * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_multi_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) +typedef __packed struct _evt_gatt_read_multi_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ +} PACKED evt_gatt_read_multi_permit_req; + +/** + * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2). + * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES. + * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value(). + * See @ref evt_gatt_tx_pool_vailable. + * + */ +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE (0x0C16) +typedef __packed struct _evt_gatt_tx_pool_available{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t available_buffers; /**< Length of data field. */ +} PACKED evt_gatt_tx_pool_available; + +/** + * This event is raised on the server when the client confirms the reception of an indication. + */ +#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT (0x0C17) +typedef __packed struct _evt_gatt_server_confirmation{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ +} PACKED evt_gatt_server_confirmation; +/** + * This event is given to the application when a prepare write request + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * Based on the response from the application, the attribute value will be modified by the stack. + * If the write is rejected by the application, then the value of the attribute will not be modified + * and an error response will be sent to the client, with the error code as specified by the application. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ (0x0C18) +typedef __packed struct _evt_gatt_prepare_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint16_t offset; /**< The offset from which the prepare write has been requested */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_prepare_write_permit_req; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,229 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gatt_server.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GATT server layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BNRG_GATT_SERVER_H__ +#define __BNRG_GATT_SERVER_H__ + +#include "ble_compiler.h" +#include "ble_status.h" + +/** + *@addtogroup GATT GATT + *@{ + */ + +/** + * @anchor Well-Known_UUIDs + * @name Well-Known UUIDs + * @{ + */ +#define PRIMARY_SERVICE_UUID (0x2800) +#define SECONDARY_SERVICE_UUID (0x2801) +#define INCLUDE_SERVICE_UUID (0x2802) +#define CHARACTERISTIC_UUID (0x2803) +#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) +#define CHAR_USER_DESC_UUID (0x2901) +#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) +#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) +#define CHAR_FORMAT_DESC_UUID (0x2904) +#define CHAR_AGGR_FMT_DESC_UUID (0x2905) +#define GATT_SERVICE_UUID (0x1801) +#define GAP_SERVICE_UUID (0x1800) +#define SERVICE_CHANGED_UUID (0x2A05) +/** + * @} + */ + +/** + * @anchor Access_permissions + * @name Access permissions + * Access permissions for an attribute + * @{ + */ +#define ATTR_NO_ACCESS (0x00) +#define ATTR_ACCESS_READ_ONLY (0x01) +#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) +#define ATTR_ACCESS_READ_WRITE (0x03) +#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) +#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) +/** + * Allows all write procedures + */ +#define ATTR_ACCESS_WRITE_ANY (0x0E) +/** + * @} + */ + +/** + * @anchor Char_properties + * @name Characteristic properties. + * @{ + */ +#define CHAR_PROP_BROADCAST (0x01) +#define CHAR_PROP_READ (0x02) +#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) +#define CHAR_PROP_WRITE (0x08) +#define CHAR_PROP_NOTIFY (0x10) +#define CHAR_PROP_INDICATE (0x20) +#define CHAR_PROP_SIGNED_WRITE (0x40) +#define CHAR_PROP_EXT (0x80) +/** + * @} + */ + + +/** + * @anchor Security_permissions + * @name Security permissions for an attribute. + * @{ + */ +#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ +#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ +#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ +#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ +/** + * @} + */ + +/** + * @anchor UUID_Types + * @name Type of UUID (16 bit or 128 bit). + * @{ + */ +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) +/** + * @} + */ + +/** + * @anchor Service_type + * @name Type of service (primary or secondary) + * @{ + */ +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) +/** + * @} + */ + +/** + * @anchor Gatt_Event_Mask + * @name Gatt Event Mask + * Type of event generated by GATT server + * @{ + */ +#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ +#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. + An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ +#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd + or a signed write cmd are received by the server for this attribute. + An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ +#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is + received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ +/** + * @} + */ + +/** + * @name Type of characteristic length + * See aci_gatt_add_char() + * @{ + */ +#define CHAR_VALUE_LEN_CONSTANT (0x00) +#define CHAR_VALUE_LEN_VARIABLE (0x01) +/** + * @} + */ + + +/** + * @name Encryption key size + * @{ + */ +/** + * Minimum encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Maximum encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) +/** + * @} + */ + +/** + * @name Characteristic Presentation Format + * @{ + */ +typedef __packed struct _charactFormat { + uint8_t format; + int8_t exp; + uint16_t unit; + uint8_t name_space; + uint16_t desc; +} PACKED charactFormat; + +/** + * @} + */ + +/** + * @name Format + * @{ + */ +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F +/** + * @} + */ + +/** + * @name Unit + * @{ + */ +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 +/** + * @} + */ + + +/** + * ATT MTU size + */ +#define ATT_MTU (23) + +/** + * @} + */ + + /** + * @name Update type of aci_gatt_upd_char_val_ext(). + * @{ + */ + +#define NOTIFICATION 1 +#define INDICATION 2 + +#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,385 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hal_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with HCI commands for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_HAL_ACI_H__ +#define __BLUENRG_HAL_ACI_H__ + +/** + *@addtogroup HAL HAL + *@brief Hardware Abstraction Layer. + *@{ + */ + +/** + * @defgroup HAL_Functions HAL functions + * @brief API for BlueNRG HAL layer. + * @{ + */ + +/** + * @brief This command retrieves the buid number of the firmware. + * @param[out] build_number Build number identifying the firmware release. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number); + +/** + * @brief This command writes a value to a low level configure data structure. + * @note It is useful to setup directly some low level parameters for the system at runtime. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * + * @param len Length of data to be written + * @param[out] val Data to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val); + +/** + * @brief This command requests the value in the low level configure data structure. + * The number of read bytes changes for different Offset. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * @param data_len Length of the data buffer + * @param[out] data_len_out_p length of the data returned by the read. + * @param[out] data Read data + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data); + +/** + * @brief This command sets the TX power level of the BlueNRG. + * @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines + * the output power level (dBm). + * When the system starts up or reboots, the default TX power level will be used, which is + * the maximum value of 8dBm. Once this command is given, the output power will be changed + * instantly, regardless if there is Bluetooth communication going on or not. For example, + * for debugging purpose, the BlueNRG can be set to advertise all the time and use this + * command to observe the signal strength changing. The system will keep the last received + * TX power level from the command, i.e. the 2nd command overwrites the previous TX power + * level. The new TX power level remains until another Set TX Power command, or the system + * reboots.\n + * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the + * right value, depending on the selected hardware configuration for the RF network: + * normal mode or high power mode. + * @param pa_level Can be from 0 to 7. Set the PA level value. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +/** + * @brief This command returns the number of packets sent in Direct Test Mode. + * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets + * have been transmitted. This command can be used to check how many packets have been sent + * during the Direct TX test.\n + * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again. + * The counter is not cleared until the next Direct TX test starts. + * @param[out] number_of_packets Number of packets sent during the last Direct TX test. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets); + +/** + * @brief Put the device in standby mode. + * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the + * device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode, + * the device can still wake up itself with the internal timer. But in standby mode, this timer is + * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command + * sent via SPI bus. + * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code + * ERR_COMMAND_DISALLOWED will be returned. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_device_standby(void); + +/** + * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. + * @note The frequency sine wave at the specific channel may be used for test purpose only. + * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. + * This command shouldn't be used when normal Bluetooth activities are ongoing. + * The tone should be stopped by aci_hal_tone_stop() command. + * + * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the + * channel central frequency minus 250 kHz. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +/** + * This command is used to stop the previously started aci_hal_tone_start() command. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_stop(void); + +/** + * @brief This command returns the status of all the connections. + * @note This command returns the status of the 8 Bluetooth low energy links managed by the device. + * @param[out] link_status Array of link status (8 links). See @ref Link_Status. + * @param[out] conn_handle Array of connection handles for each link. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]); + +/** + * @brief This command returns the anchor period and the largest available slot. + * @note This command returns information about the anchor period to help application in selecting + * slot timings when operating in multi-link scenarios. + * @param anchor_period Current anchor period (multiple of 0.625 ms). + * @param max_free_slot Maximum available time (multiple of 0.625 ms) that can be allocated for a new slot. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot); + +/** + * @} + */ + +/** + * @defgroup HAL_Events HAL events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_HAL_INITIALIZED (0x0001) +typedef __packed struct _evt_hal_initialized{ + uint8_t reason_code; /**< Reset reason. See @ref Reset_Reasons */ +} PACKED evt_hal_initialized; + +/** + * This event is generated when an overflow occurs in the event queue read by the external microcontroller. + * This is normally caused when the external microcontroller does not read pending events. + * The returned bitmap indicates which event has been lost. Please note that one bit set to 1 indicates one or + * more occurrences of the particular events. The event EVT_BLUE_HAL_EVENTS_LOST cannot be lost and it will + * be inserted in the event queue as soon as a position is freed in the event queue. This event should not + * happen under normal operating condition where external microcontroller promptly reads events signaled by + * IRQ pin. It is provided to detected unexpected behavior of the external microcontroller or to allow + * application to recover situations where critical events are lost. + */ +#define EVT_BLUE_HAL_EVENTS_LOST_IDB05A1 (0x0002) +typedef __packed struct _evt_hal_events_lost{ + uint8_t lost_events[8]; /**< Bitmap of lost events. Each bit indicates one or more occurrences of the specific event. See @ref Lost_Events */ +} PACKED evt_hal_events_lost_IDB05A1; + + +/** + * This event is given to the application after the @ref ACI_BLUE_INITIALIZED_EVENT + * when a system crash is detected. This events returns system crash information for debugging purposes. + * Information reported are useful to understand the root cause of the crash. + */ +#define EVT_BLUE_HAL_CRASH_INFO_IDB05A1 (0x0003) +typedef __packed struct _evt_hal_crash_info{ + uint8_t crash_type; /**< Type of crash: Assert failed (0), NMI Fault (1), Hard Fault (2) */ + uint32_t sp; /**< SP register */ + uint32_t r0; /**< R0 register */ + uint32_t r1; /**< R1 register */ + uint32_t r2; /**< R2 register */ + uint32_t r3; /**< R3 register */ + uint32_t r12; /**< R12 register */ + uint32_t lr; /**< LR register */ + uint32_t pc; /**< PC register */ + uint32_t xpsr; /**< xPSR register */ + uint8_t debug_data_len; /**< length of debug_data field */ + uint8_t debug_data[VARIABLE_SIZE]; /**< Debug data */ +} PACKED evt_hal_crash_info_IDB05A1; + + +/** + * @} + */ + + +/** + * @anchor Reset_Reasons + * @name Reset Reasons + * See @ref EVT_BLUE_HAL_INITIALIZED. + * @{ + */ +#define RESET_NORMAL 1 /**< Normal startup. */ +#define RESET_UPDATER_ACI 2 /**< Updater mode entered with ACI command */ +#define RESET_UPDATER_BAD_FLAG 3 /**< Updater mode entered due to a bad BLUE flag */ +#define RESET_UPDATER_PIN 4 /**< Updater mode entered with IRQ pin */ +#define RESET_WATCHDOG 5 /**< Reset caused by watchdog */ +#define RESET_LOCKUP 6 /**< Reset due to lockup */ +#define RESET_BROWNOUT 7 /**< Brownout reset */ +#define RESET_CRASH 8 /**< Reset caused by a crash (NMI or Hard Fault) */ +#define RESET_ECC_ERR 9 /**< Reset caused by an ECC error */ +/** + * @} + */ + + +/** + * @defgroup Config_vals Offsets and lengths for configuration values. + * @brief Offsets and lengths for configuration values. + * See aci_hal_write_config_data(). + * @{ + */ + +/** + * @name Configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ +#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ +#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ +#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ +#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. + It can be written only if aci_hal_write_config_data() is the first command after reset. */ +#define CONFIG_DATA_RANDOM_ADDRESS (0x80) /**< Stored static random address. Read-only. */ + +/** + * Select the BlueNRG mode configurations.\n + * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) + * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) + * @li Mode 3: master/slave, 8 connections, RAM1 and RAM2. + * @li Mode 4: master/slave, 4 connections, RAM1 and RAM2 simultaneous scanning and advertising. + */ +#define CONFIG_DATA_MODE_OFFSET (0x2D) + +#define CONFIG_DATA_WATCHDOG_DISABLE (0x2F) /**< Set to 1 to disable watchdog. It is enabled by default. */ +/** + * @} + */ + +/** + * @name Length for configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_LEN (6) +#define CONFIG_DATA_DIV_LEN (2) +#define CONFIG_DATA_ER_LEN (16) +#define CONFIG_DATA_IR_LEN (16) +#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) +#define CONFIG_DATA_MODE_LEN (1) +#define CONFIG_DATA_WATCHDOG_DISABLE_LEN (1) +/** + * @} + */ + +/** + * @anchor Link_Status + * @name Status of the link + * See @ref aci_hal_get_link_status(). + * @{ + */ +#define STATUS_IDLE 0 +#define STATUS_ADVERTISING 1 +#define STATUS_CONNECTED_AS_SLAVE 2 +#define STATUS_SCANNING 3 +#define STATUS_CONNECTED_AS_MASTER 5 +#define STATUS_TX_TEST 6 +#define STATUS_RX_TEST 7 +/** + * @} + */ + +/** + * @} + */ + + /** + * @anchor Lost_Events + * @name Lost events bitmap + * See @ref EVT_BLUE_HAL_EVENTS_LOST. + * @{ + */ +#define EVT_DISCONN_COMPLETE_BIT 0 +#define EVT_ENCRYPT_CHANGE_BIT 1 +#define EVT_READ_REMOTE_VERSION_COMPLETE_BIT 2 +#define EVT_CMD_COMPLETE_BIT 3 +#define EVT_CMD_STATUS_BIT 4 +#define EVT_HARDWARE_ERROR_BIT 5 +#define EVT_NUM_COMP_PKTS_BIT 6 +#define EVT_ENCRYPTION_KEY_REFRESH_BIT 7 +#define EVT_BLUE_HAL_INITIALIZED_BIT 8 +#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE_BIT 9 +#define EVT_BLUE_GAP_PAIRING_CMPLT_BIT 10 +#define EVT_BLUE_GAP_PASS_KEY_REQUEST_BIT 11 +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST_BIT 12 +#define EVT_BLUE_GAP_SECURITY_REQ_INITIATED_BIT 13 +#define EVT_BLUE_GAP_BOND_LOST_BIT 14 +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE_BIT 15 +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_BIT 16 +#define EVT_BLUE_L2CAP_CONN_UPDATE_RESP_BIT 17 +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT_BIT 18 +#define EVT_BLUE_L2CAP_CONN_UPDATE_REQ_BIT 19 +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_BIT 20 +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT_BIT 21 +#define EVT_BLUE_EXCHANGE_MTU_RESP_BIT 22 +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP_BIT 23 +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP_BIT 24 +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP_BIT 25 +#define EVT_BLUE_ATT_READ_RESP_BIT 26 +#define EVT_BLUE_ATT_READ_BLOB_RESP_BIT 27 +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP_BIT 28 +#define EVT_BLUE_ATT_READ_BY_GROUP_RESP_BIT 29 +#define EVT_BLUE_ATT_WRITE_RESP_BIT 30 +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP_BIT 31 +#define EVT_BLUE_ATT_EXEC_WRITE_RESP_BIT 32 +#define EVT_BLUE_GATT_INDICATION_BIT 33 +#define EVT_BLUE_GATT_NOTIFICATION_BIT 34 +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE_BIT 35 +#define EVT_BLUE_GATT_ERROR_RESP_BIT 36 +#define EVT_BLUE_GATT_DISC_READ_CHARAC_BY_UUID_RESP_BIT 37 +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ_BIT 38 +#define EVT_BLUE_GATT_READ_PERMIT_REQ_BIT 39 +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ_BIT 40 +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_BIT 41 +#define EVT_BLUE_GATT_SERVER_RX_CONFIRMATION_BIT 42 +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ_BIT 43 +#define EVT_LL_CONNECTION_COMPLETE_BIT 44 +#define EVT_LL_ADVERTISING_REPORT_BIT 45 +#define EVT_LL_CONNECTION_UPDATE_COMPLETE_BIT 46 +#define EVT_LL_READ_REMOTE_USED_FEATURES_BIT 47 +#define EVT_LL_LTK_REQUEST_BIT 48 +/** + * @} + */ + +/** + * @name Hardware error event codes + * See @ref EVT_HARDWARE_ERROR. + * @{ + */ +/** + * Error on the SPI bus has been detected, most likely caused by incorrect SPI configuration on the external micro-controller. + */ +#define SPI_FRAMING_ERROR 0 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define RADIO_STATE_ERROR 1 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define TIMER_OVERRUN_ERROR 2 + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,166 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_l2cap_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with L2CAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_L2CAP_ACI_H__ +#define __BLUENRG_L2CAP_ACI_H__ + +/** + *@addtogroup L2CAP L2CAP + *@brief L2CAP layer. + *@{ + */ + +/** + *@defgroup L2CAP_Functions L2CAP functions + *@brief API for L2CAP layer. + *@{ + */ + +/** + * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. + * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request + * (accepts or rejects). + * @param conn_handle Connection handle on which the connection parameter update request has to be sent. + * @param interval_min Defines minimum value for the connection event interval in the following manner: + * connIntervalMin = interval_min x 1.25ms + * @param interval_max Defines maximum value for the connection event interval in the following manner: + * connIntervalMax = interval_max x 1.25ms + * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). + * @param timeout_multiplier Defines connection timeout parameter in the following manner: + * timeout_multiplier x 10ms. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier); +/** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param min_ce_length Minimum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_ce_length Maximum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept); + /** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept); + +/** + * @} + */ + +/** + * @defgroup L2CAP_Events L2CAP events + * @{ + */ + +/** + * This event is generated when the master responds to the L2CAP connection update request packet. + * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. + */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef __packed struct _evt_l2cap_conn_upd_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ +/** + * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. + * @li 0x01 in case of Command Reject. + */ + uint8_t code; + uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ + uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ +/** + * Result code (parameters accepted or rejected) in case of Connection Parameter Update + * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). + */ + uint16_t result; +} PACKED evt_l2cap_conn_upd_resp; + +/** + * This event is generated when the master does not respond to the connection update request + * within 30 seconds. + */ +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) +typedef __packed struct _evt_l2cap_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */ +} PACKED evt_l2cap_procedure_timeout; + +/** + * The event is given by the L2CAP layer when a connection update request is received from the slave. + * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). + */ +#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) +typedef __packed struct _evt_l2cap_conn_upd_req{ +/** + * Handle of the connection for which the connection update request has been received. + * The same handle has to be returned while responding to the event with the command + * aci_l2cap_connection_parameter_update_response(). + */ + uint16_t conn_handle; + uint8_t event_data_length; /**< Length of following data. */ +/** + * This is the identifier which associates the request to the + * response. The same identifier has to be returned by the upper + * layer in the command aci_l2cap_connection_parameter_update_response(). + */ + uint8_t identifier; + uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ + uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ +} PACKED evt_l2cap_conn_upd_req; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_updater_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with updater commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_UPDATER_ACI_H__ +#define __BLUENRG_UPDATER_ACI_H__ + +#include <ble_compiler.h> + +/** + * @defgroup Updater Updater + * @brief Updater. + * @{ + */ + +/** + * @defgroup Updater_Functions Updater functions + * @brief API for BlueNRG Updater. + * @{ + */ + +tBleStatus aci_updater_start(void); + +tBleStatus aci_updater_reboot(void); + +tBleStatus aci_get_updater_version(uint8_t *version); + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); + +tBleStatus aci_erase_blue_flag(void); + +tBleStatus aci_reset_blue_flag(void); + +tBleStatus aci_updater_erase_sector(uint32_t address); + +tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); + +tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); + +tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); + +tBleStatus aci_updater_hw_version(uint8_t *version); + +/** + * @} + */ + +/** + * @defgroup Updater_Events Updater events + * @{ + */ +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_INITIALIZED (0x0001) +typedef __packed struct _evt_blue_initialized{ + uint8_t reason_code; +} PACKED evt_blue_initialized; +/** + * @} + */ + +/** + * @} + */ + + + +#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,204 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_utils.h +* Author : AMS - VMA, RF Application Team +* Version : V1.0.1 +* Date : 03-October-2014 +* Description : Header file for BlueNRG utility functions +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + * @file bluenrg_utils.h + * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description + * + * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> +**/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLUENRG_UTILS_H +#define __BLUENRG_UTILS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ble_hal_types.h" +#include "ble_compiler.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct{ + uint8_t stack_mode; + uint8_t day; + uint8_t month; + uint8_t year; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint16_t hs_startup_time; /* In system time units*/ +} IFR_config2_TypeDef; + +/** + * Structure inside IFR for configuration options. + */ +typedef __packed struct{ + uint8_t cold_ana_act_config_table[64]; + uint8_t hot_ana_config_table[64]; + uint8_t stack_mode; + uint8_t gpio_config; + uint8_t rsrvd1[2]; + uint32_t rsrvd2[3]; + uint32_t max_conn_event_time; + uint32_t ls_crystal_period; + uint32_t ls_crystal_freq; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint8_t rsrvd3; + uint16_t hs_startup_time; /* In system time units*/ + uint8_t rsrvd4[2]; + uint32_t uid; + uint8_t rsrvd5; + uint8_t year; + uint8_t month; + uint8_t day; + uint32_t unused[5]; +} PACKED IFR_config_TypeDef; + +/* Exported constants --------------------------------------------------------*/ +extern const IFR_config_TypeDef IFR_config; + +/* Exported macros -----------------------------------------------------------*/ +#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)+1) +#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) + +/* Convert 2 digit BCD number to an integer */ +#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) + +/* Convert 2 digit number to a BCD number */ +#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) + +/** + * Return values + */ +#define BLE_UTIL_SUCCESS 0 +#define BLE_UTIL_UNSUPPORTED_VERSION 1 +#define BLE_UTIL_WRONG_IMAGE_SIZE 2 +#define BLE_UTIL_ACI_ERROR 3 +#define BLE_UTIL_CRC_ERROR 4 +#define BLE_UTIL_PARSE_ERROR 5 +#define BLE_UTIL_WRONG_VERIFY 6 + +/* Exported functions ------------------------------------------------------- */ +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int program_device(const uint8_t *fw_image, uint32_t fw_size); + +/** + * @brief Read raw data from IFR (3 64-bytes blocks). + * @param data Pointer to the buffer that will contain the read data. + * Its size must be 192 bytes. This data can be parsed by + * parse_IFR_data_config(). + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION) + */ +int read_IFR(uint8_t data[192]); + +/** + * @brief Verify raw data from IFR (3 64-bytes blocks). + * @param ifr_data Pointer to the buffer that will contain the data to verify. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) + */ +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); + +/** + * @brief Program raw data to IFR (3 64-bytes blocks). + * @param ifr_image Pointer to the buffer that will contain the data to program. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful + */ +int program_IFR(const IFR_config_TypeDef *ifr_image); + +/** + * @brief Parse IFR raw data. + * @param data Pointer to the raw data: last 64 bytes read from IFR sector. + * @param IFR_config Data structure that will be filled with parsed data. + * @retval None + */ +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); + +/** + * @brief Check for the correctness of parsed data. + * @param IFR_config Data structure filled with parsed data. + * @retval int It returns 0 if successful, or PARSE_ERROR in case data is + * not correct. + */ +int IFR_validate(IFR_config2_TypeDef *IFR_config); + +/** + * @brief Modify IFR data. (Last 64-bytes block). + * @param IFR_config Structure that contains the new parameters inside the + * IFR configuration data. + * @note It is highly recommended to parse the IFR configuration from + * a working IFR block (this should be done with parse_IFR_data_config()). + * Then it is possible to write the new parameters inside the IFR_config + * structure. + * @param data Pointer to the buffer that contains the original data. It + * will be modified according to the new data in the IFR_config + * structure. Then this data must be written in the last + * 64-byte block in the IFR. + * Its size must be 64 bytes. + * @retval None + */ +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); + +/** + * @brief Get BlueNRG hardware and firmware version + * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). + * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN + * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. + * @retval Status of the call + */ +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); + +/** + * @brief Get BlueNRG updater version + * @param version This parameter returns the updater version. If the updadter version is 0x03 + * the chip has the updater old, needs to update the bootloader. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterVersion(uint8_t *version); + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version); + +/** + * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on + * the HW bootloader related to the 32 MHz external crystal oscillator. + * @retval TRUE if the HW bootloader is already patched, FALSE otherwise + */ +uint8_t isHWBootloader_Patched(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__BLUENRG_UTILS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file bluenrg_targets.h + * @author AST / EST + * @version V0.0.1 + * @date 24-July-2015 + * @brief This header file is intended to manage the differences between + * the different supported base-boards which might mount the + * X_NUCLEO_IDB0XA1 BlueNRG BLE Expansion Board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent from recursive inclusion --------------------------------*/ +#ifndef _BLUENRG_TARGETS_H_ +#define _BLUENRG_TARGETS_H_ + +#if !defined(BLUENRG_PIN_SPI_MOSI) +#define BLUENRG_PIN_SPI_MOSI (D11) +#endif +#if !defined(BLUENRG_PIN_SPI_MISO) +#define BLUENRG_PIN_SPI_MISO (D12) +#endif +#if !defined(BLUENRG_PIN_SPI_nCS) +#define BLUENRG_PIN_SPI_nCS (A1) +#endif +#if !defined(BLUENRG_PIN_SPI_RESET) +#define BLUENRG_PIN_SPI_RESET (D7) +#endif +#if !defined(BLUENRG_PIN_SPI_IRQ) +#define BLUENRG_PIN_SPI_IRQ (A0) +#endif + +/* NOTE: Refer to README for further details regarding BLUENRG_PIN_SPI_SCK */ +#if !defined(BLUENRG_PIN_SPI_SCK) +#define BLUENRG_PIN_SPI_SCK (D3) +#endif + +/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv) + * Mode 0x01: slave or master, 1 connection + * Mode 0x02: slave or master, 1 connection + * Mode 0x03: master/slave, 8 connections + * Mode 0x04: master/slave, 4 connections (simultaneous scanning and advertising) + * Check Table 285 of + * BlueNRG-MS Bluetooth LE stack application command interface (ACI) User Manual (UM1865) at st.com + */ +#if !defined(BLUENRG_STACK_MODE) +#define BLUENRG_STACK_MODE (0x04) +#endif + +#endif // _BLUENRG_TARGTES_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef _BTLE_H_ +#define _BTLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "bluenrg_aci.h" +#include "ble_hci_const.h" +#include "bluenrg_hal_aci.h" +#include "stm32_bluenrg_ble.h" +#include "bluenrg_gap.h" +#include "bluenrg_gatt_server.h" + +extern uint16_t g_gap_service_handle; +extern uint16_t g_appearance_char_handle; +extern uint16_t g_device_name_char_handle; +extern uint16_t g_preferred_connection_parameters_char_handle; + +void btleInit(void); +void SPI_Poll(void); +void User_Process(void); +void setConnectable(void); +void setVersionString(uint8_t hwVersion, uint16_t fwVersion); +const char* getVersionString(void); +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type); + + +extern int btle_handler_pending; +extern void btle_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.h + * @author CL + * @version V1.0.1 + * @date 15-June-2014 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_BLUENRG_BLE_H +#define __STM32_BLUENRG_BLE_H + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdint.h> +#include "ble_gp_timer.h" +#include "ble_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup X-NUCLEO-IDB04A1 + * @{ + */ + +/** @addtogroup STM32_BLUENRG_BLE + * @{ + */ + +/** @defgroup STM32_BLUENRG_BLE_Exported_Functions + * @{ + */ + +// FIXME: add prototypes for BlueNRG here +void BlueNRG_RST(void); +uint8_t BlueNRG_DataPresent(void); +void BlueNRG_HW_Bootloader(void); +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size); +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, + uint8_t Nb_bytes1, + uint8_t Nb_bytes2); +void Clear_SPI_EXTI_Flag(void); + +void print_csv_time(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_BLUENRG_BLE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_debug.h" + +#ifndef __PAYLOAD_H__ +#define __PAYLOAD_H__ + +class UnitPayload +{ +public: + uint8_t length; + uint8_t id; + uint8_t *data; + uint8_t *idptr; + + + + void set_length(uint8_t l) { + length=l; + } + + void set_id(uint8_t i) { + id=i; + } + + void set_data(uint8_t* data1) { + for(int j=0;j<length;j++) + { + data[j]=data1[j]; + } + } + + uint8_t get_length() { + return length; + } + + uint8_t get_id() { + return id; + } + + uint8_t* get_data() { + return data; + } + +}; + +class Payload { + UnitPayload *payload; + int stringLength; + int payloadUnitCount; + +public: + Payload(const uint8_t *tokenString, uint8_t string_ength); + Payload(); + ~Payload(); + uint8_t getPayloadUnitCount(); + + uint8_t getIDAtIndex(int index); + uint8_t getLengthAtIndex(int index); + uint8_t* getDataAtIndex(int index); + int8_t getInt8AtIndex(int index); + uint16_t getUint16AtIndex(int index); + uint8_t* getSerializedAdDataAtIndex(int index); +}; + + +class PayloadUnit { +private: + uint8_t* lenPtr; + uint8_t* adTypePtr; + uint8_t* dataPtr; + +public: + PayloadUnit() { + lenPtr = NULL; + adTypePtr = NULL; + dataPtr = NULL; + } + + PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { + lenPtr = len; + adTypePtr = adType; + dataPtr = data; + } + + void setLenPtr(uint8_t *len) { + lenPtr = len; + } + + void setAdTypePtr(uint8_t *adType) { + adTypePtr = adType; + } + + void setDataPtr(uint8_t *data) { + dataPtr = data; + } + + uint8_t* getLenPtr() { + return lenPtr; + } + + uint8_t* getAdTypePtr() { + return adTypePtr; + } + + uint8_t* getDataPtr() { + return dataPtr; + } + + void printDataAsHex() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("0x%x ", dataPtr[i]); + } + PRINTF("\n"); + } + + void printDataAsString() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("%c", dataPtr[i]); + } + PRINTF("\n"); + } + +}; + +class PayloadPtr { +private: + PayloadUnit *unit; + int payloadUnitCount; +public: + PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + int stringLength = string_ength; + payloadUnitCount = 0; + + int index = 0; + while(index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + // allocate memory to unit + unit = new PayloadUnit[payloadUnitCount]; + int i = 0; + int nextUnitOffset = 0; + + while(i<payloadUnitCount) { + unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); + unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); + unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); + + nextUnitOffset += *unit[i].getLenPtr()+1; + i++; + + } + } + + PayloadUnit getUnitAtIndex(int index) { + return unit[index]; + } + + int getPayloadUnitCount() { return payloadUnitCount; } + + ~PayloadPtr() { + if(unit) delete[] unit; + + unit = NULL; + } +}; + +#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include "ble_status.h" +#include "ble_hal_types.h" + +#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do {\ + uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ + }while(0) + + +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); + +#endif // __UTIL_H__ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/mbed_lib.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "bluenrg", + "target_overrides": { + "K64F": { + "target.macros_add": ["BLUENRG_PIN_SPI_SCK=D13"] + }, + "DISCO_L475VG_IOT01A": { + "target.macros_add": ["BLUENRG_PIN_SPI_MOSI=PC_12", + "BLUENRG_PIN_SPI_MISO=PC_11", + "BLUENRG_PIN_SPI_nCS=PD_13", + "BLUENRG_PIN_SPI_RESET=PA_8", + "BLUENRG_PIN_SPI_IRQ=PE_6", + "BLUENRG_PIN_SPI_SCK=PC_10"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,37 @@ +{ + "name": "x-nucleo-idb0xa1", + "version": "2.2.0", + "description": "ST driver for the mbed BLE API.", + "keywords": [ + "expansion", + "board", + "x-nucleo", + "nucleo", + "ST", + "STM", + "Bluetooth", + "BLE" + ], + "author": "Andrea Palmieri", + "repository": { + "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git", + "type": "git" + }, + "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "extraIncludes": [ + "x-nucleo-idb0xa1", + "x-nucleo-idb0xa1/utils", + "x-nucleo-idb0xa1/platform", + "x-nucleo-idb0xa1/bluenrg-hci" + ], + "dependencies": { + "mbed-drivers": ">=0.11.3", + "ble": "^2.7.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,474 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.cpp + * @author STMicroelectronics + * @brief Implementation of BLEDeviceInstanceBase + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGDevice + * @brief BlueNRG BLE_API Device Adaptation + * @{ + */ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGDevice.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" + +#include "btle.h" +#include "ble_utils.h" +#include "ble_osal.h" + +#include "ble_debug.h" +#include "stm32_bluenrg_ble.h" + +extern "C" { + #include "ble_hci.h" + #include "bluenrg_utils.h" +} + +#define HEADER_SIZE 5 +#define MAX_BUFFER_SIZE 255 + +/** + * The singleton which represents the BlueNRG transport for the BLEDevice. + * + * See file 'bluenrg_targets.h' for details regarding the peripheral pins used! + */ +#include "bluenrg_targets.h" + +BlueNRGDevice bluenrgDeviceInstance(BLUENRG_PIN_SPI_MOSI, + BLUENRG_PIN_SPI_MISO, + BLUENRG_PIN_SPI_SCK, + BLUENRG_PIN_SPI_nCS, + BLUENRG_PIN_SPI_RESET, + BLUENRG_PIN_SPI_IRQ); + +/** +* BLE-API requires an implementation of the following function in order to +* obtain its transport handle. +*/ +BLEInstanceBase * +createBLEInstance(void) +{ + return (&bluenrgDeviceInstance); +} + +/**************************************************************************/ +/** + @brief Constructor + * @param mosi mbed pin to use for MOSI line of SPI interface + * @param miso mbed pin to use for MISO line of SPI interface + * @param sck mbed pin to use for SCK line of SPI interface + * @param cs mbed pin to use for not chip select line of SPI interface + * @param rst mbed pin to use for BlueNRG reset + * @param irq mbed pin for BlueNRG IRQ +*/ +/**************************************************************************/ +BlueNRGDevice::BlueNRGDevice(PinName mosi, + PinName miso, + PinName sck, + PinName cs, + PinName rst, + PinName irq) : + isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq) +{ + // Setup the spi for 8 bit data, low clock polarity, + // 1-edge phase, with an 8MHz clock rate + spi_.format(8, 0); + spi_.frequency(8000000); + + // Deselect the BlueNRG chip by keeping its nCS signal high + nCS_ = 1; + + wait_us(500); + + // Prepare communication between the host and the BlueNRG SPI interface + HCI_Init(); + + // Set the interrupt handler for the device + irq_.mode(PullDown); // set irq mode + irq_.rise(&HCI_Isr); +} + +/**************************************************************************/ +/** + @brief Destructor +*/ +/**************************************************************************/ +BlueNRGDevice::~BlueNRGDevice(void) +{ +} + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param hw_version The HW version is written to this parameter + * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise + */ +uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version) +{ + uint8_t status; + + status = getBlueNRGUpdaterHWVersion(hw_version); + + return (status); +} + +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns BLE_STATUS_SUCCESS on success, or a number + * not equal to 0 in case of error + * (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size) +{ + int status = program_device(fw_image, fw_size); + + return (status); +} + + +/** + * @brief Initialises anything required to start using BLE + * @param[in] instanceID + * The ID of the instance to initialize. + * @param[in] callback + * A callback for when initialization completes for a BLE + * instance. This is an optional parameter set to NULL when not + * supplied. + * + * @return BLE_ERROR_NONE if the initialization procedure was started + * successfully. + */ +ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback) +{ + if (isInitialized) { + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_ALREADY_INITIALIZED + }; + callback.call(&context); + return BLE_ERROR_ALREADY_INITIALIZED; + } + + // Init the BlueNRG/BlueNRG-MS stack + btleInit(); + + isInitialized = true; + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_NONE + }; + callback.call(&context); + + return BLE_ERROR_NONE; +} + + +/** + @brief Resets the BLE HW, removing any existing services and + characteristics + @param[in] void + @returns void +*/ +void BlueNRGDevice::reset(void) +{ + /* Reset BlueNRG SPI interface. Hold reset line to 0 for 1500us */ + rst_ = 0; + wait_us(1500); + rst_ = 1; + + /* Wait for the radio to come back up */ + wait_us(5000); +} + +/*! + @brief Wait for any BLE Event like BLE Connection, Read Request etc. + @param[in] void + @returns char * +*/ +void BlueNRGDevice::waitForEvent(void) +{ + bool must_return = false; + + do { + bluenrgDeviceInstance.processEvents(); + + if(must_return) return; + + __WFE(); /* it is recommended that SEVONPEND in the + System Control Register is NOT set */ + must_return = true; /* after returning from WFE we must guarantee + that conrol is given back to main loop before next WFE */ + } while(true); + +} + +/*! + @brief get GAP version + @brief Get the BLE stack version information + @param[in] void + @returns char * + @returns char * +*/ +const char *BlueNRGDevice::getVersion(void) +{ + return getVersionString(); +} + +/**************************************************************************/ +/*! + @brief get reference to GAP object + @param[in] void + @returns Gap& +*/ +/**************************************************************************/ +Gap &BlueNRGDevice::getGap() +{ + return BlueNRGGap::getInstance(); +} + +const Gap &BlueNRGDevice::getGap() const +{ + return BlueNRGGap::getInstance(); +} + +/**************************************************************************/ +/*! + @brief get reference to GATT server object + @param[in] void + @returns GattServer& +*/ +/**************************************************************************/ +GattServer &BlueNRGDevice::getGattServer() +{ + return BlueNRGGattServer::getInstance(); +} + +const GattServer &BlueNRGDevice::getGattServer() const +{ + return BlueNRGGattServer::getInstance(); +} + +/**************************************************************************/ +/*! + @brief shut down the BLE device + @param[out] error if any +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::shutdown(void) { + PRINTF("BlueNRGDevice::reset\n"); + + if (!isInitialized) { + return BLE_ERROR_INITIALIZATION_INCOMPLETE; + } + + /* Reset the BlueNRG device first */ + reset(); + + /* Shutdown the BLE API and BlueNRG glue code */ + ble_error_t error; + + /* GattServer instance */ + error = BlueNRGGattServer::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* GattClient instance */ + error = BlueNRGGattClient::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* Gap instance */ + error = BlueNRGGap::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + isInitialized = false; + + PRINTF("BlueNRGDevice::reset complete\n"); + return BLE_ERROR_NONE; + +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size) +{ + uint16_t byte_count; + uint8_t len = 0; + uint8_t char_ff = 0xff; + volatile uint8_t read_char; + + uint8_t i = 0; + volatile uint8_t tmpreg; + + uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00}; + uint8_t header_slave[HEADER_SIZE]; + + /* Select the chip */ + nCS_ = 0; + + /* Read the header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = (uint8_t)(tmpreg); + } + + if (header_slave[0] == 0x02) { + /* device is ready */ + byte_count = (header_slave[4]<<8)|header_slave[3]; + + if (byte_count > 0) { + + /* avoid to read more data that size of the buffer */ + if (byte_count > buff_size){ + byte_count = buff_size; + } + + for (len = 0; len < byte_count; len++){ + read_char = spi_.write(char_ff); + buffer[len] = read_char; + } + } + } + /* Release CS line to deselect the chip */ + nCS_ = 1; + + // Add a small delay to give time to the BlueNRG to set the IRQ pin low + // to avoid a useless SPI read at the end of the transaction + for(volatile int i = 0; i < 2; i++)__NOP(); + +#ifdef PRINT_CSV_FORMAT + if (len > 0) { + print_csv_time(); + for (int i=0; i<len; i++) { + PRINT_CSV(" %02x", buffer[i]); + } + PRINT_CSV("\n"); + } +#endif + + return len; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRGDevice::spiWrite(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t result = 0; + uint32_t i; + volatile uint8_t tmpreg; + + unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00}; + + disable_irq(); + + /* CS reset */ + nCS_ = 0; + + /* Exchange header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = tmpreg; + } + + if (header_slave[0] == 0x02) { + /* SPI is ready */ + if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { + + /* Buffer is big enough */ + for (i = 0; i < Nb_bytes1; i++) { + spi_.write(*(data1 + i)); + } + for (i = 0; i < Nb_bytes2; i++) { + spi_.write(*(data2 + i)); + } + } else { + /* Buffer is too small */ + result = -2; + } + } else { + /* SPI is not ready */ + result = -1; + } + + /* Release CS line */ + //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); + nCS_ = 1; + + enable_irq(); + + return result; +} + +bool BlueNRGDevice::dataPresent() +{ + return (irq_ == 1); +} + +void BlueNRGDevice::disable_irq() +{ + irq_.disable_irq(); +} + +void BlueNRGDevice::enable_irq() +{ + irq_.enable_irq(); +} + +void BlueNRGDevice::processEvents() { + btle_handler(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,68 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattClient.h" + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + uuid = uuidIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + + void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) { + lastHandle = lastHandleIn; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1477 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file BlueNRGGap.cpp + * @author STMicroelectronics + * @brief Implementation of BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGap + * @brief BlueNRG BLE_API GAP Adaptation + * @{ + */ + +#include "BlueNRGDevice.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_payload.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/* + * Utility to process GAP specific events (e.g., Advertising timeout) + */ +void BlueNRGGap::Process(void) +{ + if(AdvToFlag) { + AdvToFlag = false; + stopAdvertising(); + } + + if(ScanToFlag) { + ScanToFlag = false; + stopScan(); + } +} + +/**************************************************************************/ +/*! + @brief Sets the advertising parameters and payload for the device. + Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API + + @params[in] advData + The primary advertising data payload + @params[in] scanResponse + The optional Scan Response payload if the advertising + type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED + in \ref GapAdveritinngParams + + @returns \ref ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @retval BLE_ERROR_BUFFER_OVERFLOW + The proposed action would cause a buffer overflow. All + advertising payloads must be <= 31 bytes, for example. + + @retval BLE_ERROR_NOT_IMPLEMENTED + A feature was requested that is not yet supported in the + nRF51 firmware or hardware. + + @retval BLE_ERROR_PARAM_OUT_OF_RANGE + One of the proposed values is outside the valid range. + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) +{ + PRINTF("BlueNRGGap::setAdvertisingData\n\r"); + /* Make sure we don't exceed the advertising payload length */ + if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + PRINTF("Exceeded the advertising payload length\n\r"); + return BLE_ERROR_BUFFER_OVERFLOW; + } + + /* Make sure we have a payload! */ + if (advData.getPayloadLen() != 0) { + PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); + + /* Align the GAP Service Appearance Char value coherently + This setting is duplicate (see below GapAdvertisingData::APPEARANCE) + since BLE API has an overloaded function for appearance + */ + STORE_LE_16(deviceAppearance, advData.getAppearance()); + setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0])); + + + for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { + loadPtr.getUnitAtIndex(index); + + PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); + PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); + + switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { + /**< TX Power Level (in dBm) */ + case GapAdvertisingData::TX_POWER_LEVEL: + { + PRINTF("Advertising type: TX_POWER_LEVEL\n\r"); + int8_t enHighPower = 0; + int8_t paLevel = 0; + + int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); + tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); +#ifdef DEBUG + PRINTF("dbm=%d, ret=%d\n\r", dbm, ret); + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); +#endif + if(ret == BLE_STATUS_SUCCESS) { + aci_hal_set_tx_power_level(enHighPower, paLevel); + } + break; + } + /**< Appearance */ + case GapAdvertisingData::APPEARANCE: + { + PRINTF("Advertising type: APPEARANCE\n\r"); + + GapAdvertisingData::Appearance appearanceP; + memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2); + + PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]); + /* Align the GAP Service Appearance Char value coherently */ + setAppearance(appearanceP); + break; + } + + } // end switch + + } //end for + + } + + // update the advertising data in the shield if advertising is running + if (state.advertising == 1) { + tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS != ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload()); + if (ret) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + } + + _advData = advData; + _scanResponse = scanResponse; + + return BLE_ERROR_NONE; +} + +/* + * Utility to set ADV timeout flag + */ +void BlueNRGGap::setAdvToFlag(void) { + AdvToFlag = true; + signalEventsToProcess(); +} + +/* + * ADV timeout callback + */ +#ifdef AST_FOR_MBED_OS +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().stopAdvertising(); +} +#else +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().setAdvToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getAdvTimeout(); + t.detach(); /* disable the callback from the timeout */ +} +#endif /* AST_FOR_MBED_OS */ + +/* + * Utility to set SCAN timeout flag + */ +void BlueNRGGap::setScanToFlag(void) { + ScanToFlag = true; + signalEventsToProcess(); +} + +static void scanTimeoutCB(void) +{ + BlueNRGGap::getInstance().setScanToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getScanTimeout(); + t.detach(); /* disable the callback from the timeout */ +} + +/**************************************************************************/ +/*! + @brief Starts the BLE HW, initialising any services that were + added before this function was called. + + @param[in] params + Basic advertising details, including the advertising + delay, timeout and how the device should be advertised + + @note All services must be added before calling this function! + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ + +ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) +{ + tBleStatus ret; + int err; + + /* Make sure we support the advertising type */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { + /* ToDo: This requires a proper security implementation, etc. */ + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /* Check interval range */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { + /* Min delay is slightly longer for unconnectable devices */ + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } else { + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } + + /* Check timeout is zero for Connectable Directed */ + if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { + /* Timeout must be 0 with this type, although we'll never get here */ + /* since this isn't implemented yet anyway */ + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* Check timeout for other advertising types */ + if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && + (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* + * Advertising filter policy setting + * FIXME: the Security Manager should be implemented + */ + AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode(); + if(mode != ADV_POLICY_IGNORE_WHITELIST) { + ret = aci_gap_configure_whitelist(); + if(ret != BLE_STATUS_SUCCESS) { + PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret); + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } + + uint8_t advFilterPolicy = NO_WHITE_LIST_USE; + switch(mode) { + case ADV_POLICY_FILTER_SCAN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN; + break; + case ADV_POLICY_FILTER_CONN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN; + break; + case ADV_POLICY_FILTER_ALL_REQS: + advFilterPolicy = WHITE_LIST_FOR_ALL; + break; + default: + advFilterPolicy = NO_WHITE_LIST_USE; + break; + } + + /* Check the ADV type before setting scan response data */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED || + params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) { + + /* set scan response data */ + PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen()); + ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS!=ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + } else { + hci_le_set_scan_resp_data(0, NULL); + } + + setAdvParameters(); + PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType()); + + err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload()); + + if (err) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + + tBDAddr dummy_addr = { 0 }; + uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval; + uint16_t advIntervalMax = advIntervalMin + 1; + + err = hci_le_set_advertising_parameters( + advIntervalMin, + advIntervalMax, + params.getAdvertisingType(), + addr_type, + 0x00, + dummy_addr, + /* all channels */ 7, + advFilterPolicy + ); + + if (err) { + PRINTF("impossible to set advertising parameters\n\r"); + PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1); + PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy); + return BLE_ERROR_INVALID_PARAM; + } + + err = hci_le_set_advertise_enable(0x01); + if (err) { + PRINTF("impossible to start advertising\n\r"); + return BLE_ERROR_UNSPECIFIED; + } + + if(params.getTimeout() != 0) { + PRINTF("!!! attaching adv to!!!\n"); +#ifdef AST_FOR_MBED_OS + minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000)); +#else + advTimeout.attach(advTimeoutCB, params.getTimeout()); +#endif + } + + return BLE_ERROR_NONE; + +} + + +/**************************************************************************/ +/*! + @brief Stops the BLE HW and disconnects from any devices + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::stopAdvertising(void) +{ + if(state.advertising == 1) { + + int err = hci_le_set_advertise_enable(0); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + PRINTF("Advertisement stopped!!\n\r") ; + //Set GapState_t::advertising state + state.advertising = 0; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason) +{ + tBleStatus ret; + + ret = aci_gap_terminate(connectionHandle, reason); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_COMMAND_DISALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason) +{ + return disconnect(m_connectionHandle, reason); +} + +/**************************************************************************/ +/*! + @brief Sets the 16-bit connection handle + + @param[in] conn_handle + Connection Handle which is set in the Gap Instance + + @returns void +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionHandle(uint16_t conn_handle) +{ + m_connectionHandle = conn_handle; +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit connection handle + + @param[in] void + + @returns uint16_t + Connection Handle of the Gap Instance +*/ +/**************************************************************************/ +uint16_t BlueNRGGap::getConnectionHandle(void) +{ + return m_connectionHandle; +} + +/**************************************************************************/ +/*! + @brief Sets the BLE device address. SetAddress will reset the BLE + device and re-initialize BTLE. Will not start advertising. + + @param[in] type + Type of Address + + @param[in] address[6] + Value of the Address to be set + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address) +{ + if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if(type == BLEProtocol::AddressType::PUBLIC){ + tBleStatus ret = aci_hal_write_config_data( + CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + address + ); + if(ret != BLE_STATUS_SUCCESS) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } else if (type == BLEProtocol::AddressType::RANDOM_STATIC) { + // ensure that the random static address is well formed + if ((address[5] & 0xC0) != 0xC0) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // thanks to const correctness of the API ... + tBDAddr random_address = { 0 }; + memcpy(random_address, address, sizeof(random_address)); + int err = hci_le_set_random_address(random_address); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // It is not possible to get the bluetooth address when it is set + // store it locally in class data member + memcpy(bdaddr, address, sizeof(bdaddr)); + } else { + // FIXME random addresses are not supported yet + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + // if we're here then the address was correctly set + // commit it inside the addr_type + addr_type = type; + isSetAddress = true; + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Returns boolean if the address of the device has been set + or not + + @returns bool + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +bool BlueNRGGap::getIsSetAddress() +{ + return isSetAddress; +} + +/**************************************************************************/ +/*! + @brief Returns the address of the device if set + + @returns Pointer to the address if Address is set else NULL + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) +{ + uint8_t bdaddr[BDADDR_SIZE]; + uint8_t data_len_out; + + // precondition, check that pointers in input are valid + if (typeP == NULL || address == NULL) { + return BLE_ERROR_INVALID_PARAM; + } + + if (addr_type == BLEProtocol::AddressType::PUBLIC) { + tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr); + if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) { + return BLE_ERROR_UNSPECIFIED; + } + } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) { + // FIXME hci_read_bd_addr and + // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1 + // does not work, use the address stored in class data member + memcpy(bdaddr, this->bdaddr, sizeof(bdaddr)); + } else { + // FIXME: should be implemented with privacy features + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + *typeP = addr_type; + memcpy(address, bdaddr, BDADDR_SIZE); + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief obtains preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + + if (!g_preferred_connection_parameters_char_handle) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // Peripheral preferred connection parameters are an array of 4 uint16_t + uint8_t parameters_packed[parameter_size * 4]; + uint16_t bytes_read = 0; + + tBleStatus err = aci_gatt_read_handle_value( + g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE, + sizeof(parameters_packed), + &bytes_read, + parameters_packed + ); + + PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read); + + // check that the read succeed and the result have the expected length + if (err || bytes_read != sizeof(parameters_packed)) { + return BLE_ERROR_UNSPECIFIED; + } + + // memcpy field by field + memcpy(¶ms->minConnectionInterval, parameters_packed, parameter_size); + memcpy(¶ms->maxConnectionInterval, ¶meters_packed[parameter_size], parameter_size); + memcpy(¶ms->slaveLatency, ¶meters_packed[2 * parameter_size], parameter_size); + memcpy(¶ms->connectionSupervisionTimeout, ¶meters_packed[3 * parameter_size], parameter_size); + + return BLE_ERROR_NONE; +} + + +/**************************************************************************/ +/*! + @brief sets preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + uint8_t parameters_packed[parameter_size * 4]; + + // ensure that parameters are correct + // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC + if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) && + params->minConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) && + params->maxConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (params->slaveLatency > 0x01F3) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) && + params->connectionSupervisionTimeout != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // copy the parameters inside the byte array + memcpy(parameters_packed, ¶ms->minConnectionInterval, parameter_size); + memcpy(¶meters_packed[parameter_size], ¶ms->maxConnectionInterval, parameter_size); + memcpy(¶meters_packed[2 * parameter_size], ¶ms->slaveLatency, parameter_size); + memcpy(¶meters_packed[3 * parameter_size], ¶ms->connectionSupervisionTimeout, parameter_size); + + tBleStatus err = aci_gatt_update_char_value( + g_gap_service_handle, + g_preferred_connection_parameters_char_handle, + /* offset */ 0, + sizeof(parameters_packed), + parameters_packed + ); + + if (err) { + PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ; + switch (err) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief updates preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) +{ + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(gapRole == Gap::CENTRAL) { + ret = aci_gap_start_connection_update(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout, + CONN_L1, CONN_L2); + } else { + ret = aci_l2cap_connection_parameter_update_request(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout); + } + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case ERR_COMMAND_DISALLOWED: + case BLE_STATUS_NOT_ALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sets the Device Name Characteristic + + @param[in] deviceName + pointer to device name to be set + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) +{ + tBleStatus ret; + uint8_t nameLen = 0; + + nameLen = strlen((const char*)deviceName); + PRINTF("DeviceName Size=%d\n\r", nameLen); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_device_name_char_handle, + 0, + nameLen, + deviceName); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Gets the Device Name Characteristic + + @param[in] deviceName + pointer to device name + + @param[in] lengthP + pointer to device name length + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) +{ + tBleStatus ret; + + ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + *lengthP, + (uint16_t *)lengthP, + deviceName); + PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } +} + +/**************************************************************************/ +/*! + @brief Sets the Device Appearance Characteristic + + @param[in] appearance + device appearance + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance) +{ + tBleStatus ret; + uint8_t deviceAppearance[2]; + + STORE_LE_16(deviceAppearance, appearance); + PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_appearance_char_handle, + 0, 2, (uint8_t *)deviceAppearance); + if (BLE_STATUS_SUCCESS == ret){ + return BLE_ERROR_NONE; + } + + PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Gets the Device Appearance Characteristic + + @param[in] appearance + pointer to device appearance value + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) +{ + tBleStatus ret; + uint16_t lengthP = 2; + + ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + lengthP, + &lengthP, + (uint8_t*)appearanceP); + PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + +} + +GapScanningParams* BlueNRGGap::getScanningParams(void) +{ + return &_scanningParams; +} + +static void makeConnection(void) +{ + BlueNRGGap::getInstance().createConnection(); +} + +void BlueNRGGap::Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI) +{ + switch (reason) { + case DEVICE_FOUND: + { + GapAdvertisingParams::AdvertisingType_t type; + bool isScanResponse = false; + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * Private Random Address + * => scan_results = FALSE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type); + if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV || + (addr_type == RESOLVABLE_PRIVATE_ADDR || + addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) { + return; + } + + switch(adv_type) { + case ADV_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + break; + case ADV_DIRECT_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED; + break; + case ADV_SCAN_IND: + case SCAN_RSP: + type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED; + isScanResponse = true; + break; + case ADV_NONCONN_IND: + type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED; + break; + default: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + } + + PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n", + *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + if(!_connecting) { + processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data); + } + PRINTF("!!!After processAdvertisementReport\n\r"); + } + break; + + case DISCOVERY_COMPLETE: + // The discovery is complete. If this is due to a stop scanning (i.e., the device + // we are interested in has been found) and a connection has been requested + // then we start the device connection. + PRINTF("DISCOVERY_COMPLETE\n\r"); + _scanning = false; + + // Since the DISCOVERY_COMPLETE event can be received during the scanning interval, + // we need to delay the starting of connection + uint16_t delay = (_scanningParams.getInterval()*0.625); + +#ifdef AST_FOR_MBED_OS + if(_connecting) { + minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay)); + } +#else + Clock_Wait(delay); + if(_connecting) { + makeConnection(); + } +#endif /* AST_FOR_MBED_OS */ + + break; + } +} + +ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) +{ + + tBleStatus ret = BLE_STATUS_SUCCESS; + + // Stop ADV before scanning + /* + if (state.advertising == 1) { + stopAdvertising(); + } + */ + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * White List is empty + * => scan operation = FAILURE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + uint8_t whiteListSize = whitelistAddresses.size; + if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + ret = btleStartRadioScan(scanningParams.getActiveScanning(), + scanningParams.getInterval(), + scanningParams.getWindow(), + addr_type); + + PRINTF("Scanning...\n\r"); + PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000); + PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000); + //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval()); + //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1); + //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2); + if (BLE_STATUS_SUCCESS == ret){ + PRINTF("Observation Procedure Started\n"); + _scanning = true; + + if(scanningParams.getTimeout() != 0) { + PRINTF("!!! attaching scan to!!!\n"); + scanTimeout.attach(scanTimeoutCB, scanningParams.getTimeout()); + } + + return BLE_ERROR_NONE; + } + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + switch (ret) { + case BLE_STATUS_INVALID_CID: + PRINTF("Observation Procedure not implemented!!!\n\r"); + return BLE_ERROR_NOT_IMPLEMENTED; + default: + PRINTF("Observation Procedure failed (0x%02X)\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } + +} + +ble_error_t BlueNRGGap::stopScan() { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(_scanning) { + ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC); + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Discovery Procedure Terminated\n"); + return BLE_ERROR_NONE; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief set Tx power level + @param[in] txPower Transmission Power level + @returns ble_error_t +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setTxPower(int8_t txPower) +{ + tBleStatus ret; + + int8_t enHighPower = 0; + int8_t paLevel = 0; + + ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + ret = aci_hal_set_tx_power_level(enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief get permitted Tx power values + @param[in] values pointer to pointer to permitted power values + @param[in] num number of values +*/ +/**************************************************************************/ +void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { + static const int8_t permittedTxValues[] = { + -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8 + }; + + *valueArrayPP = permittedTxValues; + *countP = sizeof(permittedTxValues) / sizeof(int8_t); +} + +/**************************************************************************/ +/*! + @brief Set advertising parameters according to the current state + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setAdvParameters(void) +{ + uint32_t advIntMS; + + if(state.connected == 1) { + advIntMS = (conn_min_interval*1.25)-GUARD_INT; + advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS); + + PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval); + } else { + advInterval = _advParams.getIntervalInADVUnits(); + } +} + +/**************************************************************************/ +/*! + @brief Set connection parameters according to the current state (ADV and/or SCAN) + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionParameters(void) +{ + if (state.connected == 1) { + + PRINTF("state.connected=1\r\n"); + scanInterval = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(conn_min_interval*1.25); + scanWindow = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(((conn_min_interval*1.25)/100)*60); // scanWin ~= 60%(scanInt) + + } else if (state.advertising == 1) { + + if (_scanningParams.getInterval() < advInterval) { + PRINTF("state.adv=1 scanInterval<advInterval\r\n"); + scanInterval = advInterval; + scanWindow = advInterval; + } else { + PRINTF("state.adv=1 scanInterval>=advInterval\r\n"); + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + } + + if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms + conn_min_interval = MAX_INT_CONN; + conn_max_interval = MAX_INT_CONN; + } else { + conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + } + + } else { + + PRINTF("state.adv = 0\r\n"); + + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) || + SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms + conn_min_interval = DEF_INT_CONN; + conn_max_interval = DEF_INT_CONN; + } else { + conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + } + } + PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval)); + PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow)); + PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25)); + PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25)); + +} + +ble_error_t BlueNRGGap::createConnection () +{ + tBleStatus ret; + + /* + Before creating connection, set parameters according + to previous or current procedure (ADV and/or SCAN) + */ + setConnectionParameters(); + + /* + Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, + Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max + */ + ret = aci_gap_create_connection(scanInterval, + scanWindow, + _peerAddrType, + (unsigned char*)_peerAddr, + addr_type, + conn_min_interval, conn_max_interval, 0, + SUPERV_TIMEOUT, CONN_L1, CONN_L1); + + //_connecting = false; + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Connection started.\n"); + _connecting = false; + return BLE_ERROR_NONE; + } +} + +ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) +{ + /* avoid compiler warnings about unused variables */ + (void)connectionParams; + + setScanParams(scanParams->getInterval(), + scanParams->getWindow(), + scanParams->getTimeout(), + scanParams->getActiveScanning() + ); + + // Save the peer address + for(int i=0; i<BDADDR_SIZE; i++) { + _peerAddr[i] = peerAddr[i]; + } + _peerAddrType = peerAddrType; + + _connecting = true; + + if(_scanning) { + stopScan(); + } else { + PRINTF("Calling createConnection from connect()\n\r"); + return createConnection(); + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the advertising policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode) +{ + advertisingPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the scanning policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode) +{ + scanningPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Get the current advertising policy filter mode. + + @returns The advertising policy filter mode. +*/ +/**************************************************************************/ +Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const +{ + return advertisingPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Get the current scanning policy filter mode. + + @returns The scanning policy filter mode. + +*/ +/**************************************************************************/ +Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const +{ + return scanningPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGap's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::reset(void) +{ + PRINTF("BlueNRGGap::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (Gap::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + AdvToFlag = false; + ScanToFlag = false; + + /* Clear derived class members */ + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + return BLE_ERROR_NONE; +} + +void BlueNRGGap::setConnectionInterval(uint16_t interval) { + conn_min_interval = interval; + conn_max_interval = interval; +} + +Gap::Role_t BlueNRGGap::getGapRole(void) +{ + return (gapRole); +} + +void BlueNRGGap::setGapRole(Gap::Role_t role) +{ + gapRole = role; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,403 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTClient + * @brief BlueNRG BLE_API GattClient Adaptation + * @{ + */ + +#include "BlueNRGGattClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +#include <new> +#include <assert.h> + +ble_error_t BlueNRGGattClient::createGattConnectionClient(Gap::Handle_t connectionHandle) +{ + if(MAX_ACTIVE_CONNECTIONS <= _numConnections) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + for(uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + + if(_connectionPool[i] == NULL) { + BlueNRGGattConnectionClient *gattConnectionClient = new(std::nothrow) BlueNRGGattConnectionClient(this, connectionHandle); + + if (gattConnectionClient == NULL) { + return BLE_ERROR_NO_MEM; + } + + _connectionPool[i] = gattConnectionClient; + _connectionPool[i]->onServiceDiscoveryTermination(terminationCallback); + _numConnections++; + + PRINTF("createGattConnectionClient: _connectionPool index=%d\r\n", i); + PRINTF("createGattConnectionClient: succesfully added new gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + break; + } + } + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattClient::removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason) +{ + + PRINTF("removeGattConnectionClient: connectionHandle=%d reason=0x%x\r\n", connectionHandle, reason); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("removeGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("removeGattConnectionClient: Found gattConnectionClient\r\n"); + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + PRINTF("removeGattConnectionClient: succesfully removed gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + + break; + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + + return BLE_ERROR_NONE; +} + +BlueNRGGattConnectionClient * BlueNRGGattClient::getGattConnectionClient(Gap::Handle_t connectionHandle) { + PRINTF("getGattConnectionClient\r\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("getGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("getGattConnectionClient: Found gattConnectionClient\r\n"); + return _connectionPool[i]; + } + } + + return NULL; +} + +void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code) { + + if(error_code != BLE_STATUS_SUCCESS) { + return; + } + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->gattProcedureCompleteCB(error_code); +} + +void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServicesCB(event_data_length, + attribute_data_length, + attribute_data_list); +} + +void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServiceCB(event_data_length, + handles_info_list); +} + +ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->findServiceChars(); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharsCB(event_data_length, + handle_value_pair_length, + handle_value_pair); +} + +void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharByUUIDCB(event_data_length, + attr_handle, + attr_value); +} + +void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->discAllCharacDescCB(event_data_length, + format, + handle_uuid_pair); +} + +void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charReadCB(event_data_length, + attribute_value); +} + +void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWritePrepareCB(event_data_length, + attribute_handle, + offset, + part_attr_value); +} + +void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWriteExecCB(event_data_length); +} + +ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattClient launchServiceDiscovery\n\r"); + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->launchServiceDiscovery(sc, cc, matchingServiceUUID, matchingCharacteristicUUIDIn); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, matchingServiceUUID); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, startHandle, endHandle); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +bool BlueNRGGattClient::isServiceDiscoveryActive(void) const +{ + bool isSDActive = false; + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + isSDActive |= _connectionPool[i]->isServiceDiscoveryActive(); + } + } + + return isSDActive; +} + +void BlueNRGGattClient::terminateServiceDiscovery(void) +{ + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + _connectionPool[i]->terminateServiceDiscovery(); + } + } +} + +void BlueNRGGattClient::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; ++i) { + if (_connectionPool[i]) { + _connectionPool[i]->onServiceDiscoveryTermination(callback); + } + } +} + +ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->read(attributeHandle, offset); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->write(cmd, attributeHandle, length, value); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(characteristic.getConnectionHandle()); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverCharacteristicDescriptors(characteristic, discoveryCallback, terminationCallback); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattClient's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattClient::reset(void) +{ + PRINTF("BlueNRGGattClient::reset\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if(_connectionPool[i] != NULL) { + _connectionPool[i]->reset(); + + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + } + } + + return BLE_ERROR_NONE; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,816 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGattConnectionClient + * @brief BlueNRG GattConnectionClient Adaptation + * @{ + */ + +#include "BlueNRGGattConnectionClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" +#include "ble_debug.h" + +// #define PRINTF printf + +static uint8_t props_mask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 + }; + +void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code) +{ + if(error_code != BLE_STATUS_SUCCESS) { + _currentState = GATT_IDLE; + return; + } + + // Service Discovery complete +/* + if(_currentState != GATT_IDLE && + _currentState != GATT_DISCOVERY_TERMINATED && + _currentState != GATT_WRITE_CHAR && + _currentState != GATT_READ_CHAR) { +*/ + if(_currentState == GATT_SERVICE_DISCOVERY) { + findServiceChars(); + return; + } + + if(_currentState == GATT_CHAR_DESC_DISCOVERY) { + _currentState = GATT_IDLE; + if(charDescTerminationCallback != NULL) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { + _characteristic, + BLE_ERROR_NONE + }; + charDescTerminationCallback(¶ms); + } + return; + } + + // Read complete + if(_currentState == GATT_READ_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processReadResponse(&readCBParams); + free((void*)(readCBParams.data)); + readCBParams.data = NULL; + return; + } + + // Write complete + if(_currentState == GATT_WRITE_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); + return; + } +} + +void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numAttr; + + numAttr = (event_data_length - 1) / attribute_data_length; + + offset = 0; + for (i=0; i<numAttr; i++) { + startHandle = attribute_data_list[offset]; + endHandle = attribute_data_list[offset+2]; + + // UUID Type + if (attribute_data_length == 6) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4]; + PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(attribute_data_list+offset+4, UUID::LSB); + +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + + } + + PRINTF("Setup serviceIndex = %d\n\r", _numServices); + discoveredService[_numServices].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += attribute_data_length; + } + + PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr); + +} + +void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numHandlePairs; + + numHandlePairs = (event_data_length - 1) / 2; + + offset = 0; + for (i=0; i<numHandlePairs; i++) { + startHandle = handles_info_list[offset]; + endHandle = handles_info_list[offset+2]; + + PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle); + + + if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle); + uuid = _matchingServiceUUID.getShortUUID(); + } else { +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02x", longUUIDBytes[i]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB); + } + + discoveredService[i].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += 4; + } +} + +void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) +{ + // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + uint8_t i, numChar, offset; + + numChar = (event_data_length - 1) / handle_value_pair_length; + + PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar); + + offset = 0; + for (i=0; i<numChar; i++) { + // UUID Type + if (handle_value_pair_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(handle_value_pair+offset+5, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & handle_value_pair[offset+2]); + p._read = (props_mask[1] & handle_value_pair[offset+2])>>1; + p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2; + p._write = (props_mask[3] & handle_value_pair[offset+2])>>3; + p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4; + p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5; + p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = handle_value_pair[offset+2]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = handle_value_pair[offset]; + valueHandle = handle_value_pair[offset+3]; + lastHandle = valueHandle+1; + PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle); + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; + + offset += handle_value_pair_length; + } +} + +void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) +{ + // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + + PRINTF("serviceCharByUUIDCB\n\r"); + + // UUID Type + if (event_data_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = attr_value[4]<<8|attr_value[3]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(attr_value+3, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & attr_value[0]); + p._read = (props_mask[1] & attr_value[0])>>1; + p._writeWoResp = (props_mask[2] & attr_value[0])>>2; + p._write = (props_mask[3] & attr_value[0])>>3; + p._notify = (props_mask[4] & attr_value[0])>>4; + p._indicate = (props_mask[5] & attr_value[0])>>5; + p._authSignedWrite = (props_mask[6] & attr_value[0])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = attr_value[0]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = attr_handle; + valueHandle = attr_value[1]; + lastHandle = valueHandle+1; + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + // update the last handle and call the characteristic discovery callback for previous char + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; +} + +ble_error_t BlueNRGGattConnectionClient::findServiceChars(void) +{ + PRINTF("findServiceChars\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + + DiscoveredService *service; + + // complete the discovery of the last characteristic of the previous service. + // Its last handle wasn't known before this point + // update the handle and call the characteristic discovery callback. + if (_servIndex != 0 && _numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle()); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars = 0; + + // We finished chars discovery for all services + if(_servIndex >= _numServices) { + PRINTF("!!!We finished chars discovery for all services!!!\n\r"); + //_currentState = GATT_CHARS_DISCOVERY_COMPLETE; + + terminateServiceDiscovery(); + + return BLE_ERROR_NONE; + } + + service = &discoveredService[_servIndex]; + /* + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID()); + } else { + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); + } + */ + + if(serviceDiscoveryCallback) { + serviceDiscoveryCallback(service); + } + + PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex); + //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle()); + + if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) { + PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r"); + ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle()); + } else { + + uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID()); + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; +#ifdef DEBUG + PRINTF("findServiceChars C UUID-"); + for(unsigned i = 0; i < 2; i++) { + PRINTF("%02X", short_uuid[i]); + } + PRINTF("\n\r"); +#endif + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID(); +#ifdef DEBUG + PRINTF("(findServiceChars) C UUID-"); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", uuid[i]); + } + PRINTF("\r\n"); +#endif + } + + ret = aci_gatt_disc_charac_by_uuid(_connectionHandle, + service->getStartHandle(), + service->getEndHandle(), + uuid_type, + uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _servIndex++; + } + + PRINTF("findServiceChars ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + unsigned j; + + if(isServiceDiscoveryActive()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if(!sc && !cc) { + // nothing to do + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r"); + return BLE_ERROR_NONE; + } + + serviceDiscoveryCallback = sc; + characteristicDiscoveryCallback = cc; + _matchingServiceUUID = matchingServiceUUID; + _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn; + + //reset services + _numServices = 0; + _numChars = 0; + _servIndex = 0; + for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) { + discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE); + } + + if(matchingServiceUUID == BLE_UUID_UNKNOWN) { + + // Wildcard: search for all services + PRINTF("Wildcard: search for all services\r\n"); + ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle); + + } else { + PRINTF("search for specific services\r\n"); + + uint8_t type = matchingServiceUUID.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID()); +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x"); + for(j = 0; j < 2; j++) { + PRINTF("%02X", short_uuid[j]); + } + PRINTF("\n\r"); +#endif + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; + + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)matchingServiceUUID.getBaseUUID(); + +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x"); + for(j = 0; j < 16; j++) { + PRINTF("%02X", uuid[j]); + } + PRINTF("\n\r"); +#endif + } + + // search for specific service by UUID + ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_SERVICE_DISCOVERY; + } + + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)matchingServiceUUID; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)startHandle; + (void)endHandle; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const +{ + if(_currentState == GATT_SERVICE_DISCOVERY) { + return true; + } + + return false; +} + +void BlueNRGGattConnectionClient::terminateServiceDiscovery(void) +{ + _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED; + + if (terminationCallback) { + terminationCallback(_connectionHandle); + } +} + +void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value) +{ + // copy the data read, they will be forwarded to the user once the procedure + // has completed + readCBParams.connHandle = _connectionHandle; + readCBParams.offset = 0; + readCBParams.len = event_data_length; + readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length)); + memcpy((void*)(readCBParams.data), attribute_value, event_data_length); +} + +ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + /* avoid compiler warnings about unused variables */ + (void)offset; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // Save the attribute_handle not provided by evt_att_read_resp + gattc->readCBParams.handle = attributeHandle; + + ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle); + + if(ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_READ_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } +} + +void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) +{ + // Update the write response params + writeCBParams.handle = attribute_handle; + writeCBParams.offset = offset; + writeCBParams.len = event_data_length-4; //(?) + writeCBParams.data = part_attr_value; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length) +{ + /* avoid compiler warnings about unused variables */ + (void)event_data_length; + + writeCBParams.connHandle = _connectionHandle; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + /* avoid compiler warnings about unused variables */ + (void)cmd; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // We save the write response params (used by the callback) because + // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE + gattc->writeCBParams.connHandle = _connectionHandle; + gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD; + gattc->writeCBParams.handle = attributeHandle; + gattc->writeCBParams.offset = 0; + gattc->writeCBParams.len = length; + gattc->writeCBParams.data = value; + + ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); + + if (ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_WRITE_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } + +} + +void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + GattAttribute::Handle_t attHandle; + UUID uuid; + uint8_t i, numCharacDesc, offset, handle_uuid_length; + + handle_uuid_length = 4; //Handle + UUID_16 + if (format == 2) + handle_uuid_length = 18; //Handle + UUID_128 + + numCharacDesc = (event_data_length - 1) / handle_uuid_length; + + offset = 0; + + PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n", + event_data_length, format); + + + for (i=0; i<numCharacDesc; i++) { + memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle)); + + // UUID Type + if (handle_uuid_length == 4) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2]; + PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB); +#ifdef DEBUG + PRINTF("D UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + } + + if(charDescDiscoveryCallback != NULL) { + CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { + _characteristic, + DiscoveredCharacteristicDescriptor( + _characteristic.getGattClient(), + _connectionHandle, + attHandle, + uuid + ) + }; + charDescDiscoveryCallback(¶ms); + } + + _numCharDesc++; + + offset += handle_uuid_length; + } +} + +ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { + + tBleStatus ret; + + if(_currentState != GATT_IDLE) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + charDescDiscoveryCallback = discoveryCallback; + charDescTerminationCallback = terminationCallback; + + GattAttribute::Handle_t valueHandle = characteristic.getValueHandle(); + GattAttribute::Handle_t lastHandle = characteristic.getLastHandle(); + + PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle); + ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle); + + if (ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_CHAR_DESC_DISCOVERY; + _characteristic = characteristic; + return BLE_ERROR_NONE; + } + switch (ret) { + case BLE_STATUS_INVALID_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattConnectionClient::reset(void) { + PRINTF("BlueNRGGattConnectionClient::reset\n"); + + /* Clear all state, including private members */ + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + _numServices = 0; + _servIndex = 0; + _numChars = 0; + _numCharDesc = 0; + + /* Clear class members */ + memset(discoveredService, 0, sizeof(discoveredService)); + memset(discoveredChar, 0, sizeof(discoveredChar)); + + // free response if allocated + if(readCBParams.data) { + free((void*)(readCBParams.data)); + } + + return BLE_ERROR_NONE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,755 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTSERVER + * @brief BlueNRG BLE_API GattServer Adaptation + * @{ + */ + +#include "BlueNRGGattServer.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/**************************************************************************/ +/*! + @brief Adds a new service to the GATT table on the peripheral + + @params[in] service + Pointer to instance of the Gatt Server to add + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::addService(GattService &service) +{ + /* ToDo: Make sure we don't overflow the array, etc. */ + /* ToDo: Make sure this service UUID doesn't already exist (?) */ + /* ToDo: Basic validation */ + + tBleStatus ret; + uint8_t type; + uint16_t short_uuid; + uint8_t primary_short_uuid[2]; + uint8_t primary_base_uuid[16]; + uint8_t char_base_uuid[16]; + const uint8_t *base_uuid; + const uint8_t *base_char_uuid; + + uint8_t charsCount = service.getCharacteristicCount(); + const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount; + + // check that there is enough characteristics left in the + // characteristic array. + if (charsCount > available_characteristics) { + PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics); + return BLE_ERROR_NO_MEM; + } + + const uint16_t maxAttrRecords = computeAttributesRecord(service); + + type = (service.getUUID()).shortOrLong(); + PRINTF("AddService(): Type:%d\n\r", type); + + /* Add the service to the BlueNRG */ + short_uuid = (service.getUUID()).getShortUUID(); + STORE_LE_16(primary_short_uuid, short_uuid); + + if(type==UUID::UUID_TYPE_LONG) { + base_uuid = (service.getUUID()).getBaseUUID(); + + COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]); + } + + ret = BLE_STATUS_SUCCESS; + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_serv(UUID_TYPE_16, + primary_short_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_serv(UUID_TYPE_128, + primary_base_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_OUT_OF_HANDLE: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case ERR_UNSPECIFIED_ERROR: + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_ERROR: + default: + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + + + service.setHandle(servHandle); + //serviceHandleVector.push_back(servHandle); + PRINTF("added servHandle handle =%u\n\r", servHandle); + uint16_t bleCharacteristic; + + //iterate to include all characteristics + for (uint8_t i = 0; i < charsCount; i++) { + GattCharacteristic *p_char = service.getCharacteristic(i); + uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); + + uint8_t int_8_uuid[2]; + STORE_LE_16(int_8_uuid, char_uuid); + + type = (p_char->getValueAttribute().getUUID()).shortOrLong(); + + if(type==UUID::UUID_TYPE_LONG) { + base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); +#ifdef DEBUG + for(uint8_t j=0; j<16; j++) { + PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]); + } + PRINTF("\n\r"); +#endif + COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]); + } + + PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); + /* + * Gatt_Evt_Mask -> HardCoded (0) + * Encryption_Key_Size -> Hardcoded (16) + * isVariable (variable length value field) -> Hardcoded (1) + */ + uint8_t Gatt_Evt_Mask = 0x0; + + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP; + } + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; + } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_16, + int_8_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_128, + char_base_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + case BLE_STATUS_CHARAC_ALREADY_EXISTS: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); + + p_characteristics[characteristicCount++] = p_char; + /* Set the characteristic value handle */ + p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE); + PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle()); + + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + ble_error_t err = write(p_char->getValueAttribute().getHandle(), + p_char->getValueAttribute().getValuePtr(), + p_char->getValueAttribute().getLength(), false /* localOnly */); + if (err) { + PRINTF("ERROR HERE !!!!\r\n"); + return err; + } + } + + // add descriptors now + uint16_t descHandle = 0; + PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); + + for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { + GattAttribute *descriptor = p_char->getDescriptor(descIndex); + uint8_t desc_uuid[16] = { 0 }; + + + uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT; + STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID()); + + if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) { + desc_uuid_type = CHAR_DESC_TYPE_128_BIT; + const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID(); + + COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]); + } + + ret = aci_gatt_add_char_desc(service.getHandle(), + bleCharacteristic, + desc_uuid_type, + desc_uuid, + descriptor->getMaxLength(), + descriptor->getLength(), + descriptor->getValuePtr(), + CHAR_DESC_SECURITY_PERMISSION, + CHAR_DESC_ACCESS_PERMISSION, + GATT_NOTIFY_ATTRIBUTE_WRITE, + MIN_ENCRY_KEY_SIZE, + CHAR_ATTRIBUTE_LEN_IS_FIXED, + &descHandle); + PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); + + switch (ret) { + case BLE_STATUS_SUCCESS: + PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); + descriptor->setHandle(descHandle); + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_INVALID_OPERATION: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + } + + serviceCount++; + + //FIXME: There is no GattService pointer array in GattServer. + // There should be one? (Only the user is aware of GattServices!) Report to forum. + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on char handle + + @param[in] attributeHandle + The handle of the GattCharacteristic to read from + @param[in] buffer + Buffer to hold the the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes read into the buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) +{ + tBleStatus ret; + uint16_t charHandle = attributeHandle; + + ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer); + + if(ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on the connection + and char handle + + @param[in] connectionHandle + The handle of the connection + @param[in] attributeHandle + The handle of the GattCharacteristic to write to + @param[in] buffer + Data to use when updating the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes in buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + uint8_t buffer[], + uint16_t *lengthP) { + + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)attributeHandle; + (void)buffer; + (void)lengthP; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t, + const uint8_t[], + uint16_t, bool localOnly) { + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)localOnly; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly) +{ + /* avoid compiler warnings about unused variables */ + (void)localOnly; + + // check that the len of the data to write are compatible with the characteristic + GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle); + if (!characteristic) { + PRINTF("characteristic not found\r\n"); + return BLE_ERROR_INVALID_PARAM; + } + + // if the attribute handle is the attribute handle of the characteristic value then + // write the value + if (attributeHandle == characteristic->getValueHandle()) { + // assert the len in input is correct for this characteristic + const GattAttribute& value_attribute = characteristic->getValueAttribute(); + + // reject write if the lenght exceed the maximum lenght of this attribute + if (value_attribute.getMaxLength() < len) { + PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + // reject write if the attribute size is fixed and the lenght in input is different than the + // length of the attribute. + if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) { + PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + tBleStatus ret; + + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + + PRINTF("updating bleCharacteristic valueHandle=%u,\ + corresponding serviceHandle=%u len=%d\n\r", + attributeHandle, bleCharHandleMap.find(charHandle)->second, len); + + /* + * If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. + */ + ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } else { + // write this handle has a descriptor handle + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + uint16_t service_handle = bleCharHandleMap.find(charHandle)->second; + + tBleStatus ret = aci_gatt_set_desc_value( + service_handle, + charHandle, + attributeHandle, + 0, + len, + buffer + ); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } +} + +/**************************************************************************/ +/*! + @brief Reads a value according to the handle provided + + @param[in] attributeHandle + The handle of the attribute to read from + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle) +{ + uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); + + GattReadCallbackParams readParams; + readParams.handle = attributeHandle; + + //PRINTF("readParams.handle = %d\n\r", readParams.handle); + HCIDataReadEvent(&readParams); + + //EXIT: + if(gapConnectionHandle != 0){ + //PRINTF("Calling aci_gatt_allow_read\n\r"); + aci_gatt_allow_read(gapConnectionHandle); + } + + return BLE_ERROR_NONE; +} + +// ask if the write request should be accepted of rejected +// return 0 in case of success or an ATT error response in +// case of faillure +uint8_t BlueNRGGattServer::Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length, + const uint8_t* data) { + + GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle); + if(!characteristic) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF; + } + + // check if the data length is in range + if (characteristic->getValueAttribute().getMaxLength() < data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + // if the length of the characteristic value is fixed + // then the data in input should be of that length + if (characteristic->getValueAttribute().hasVariableLength() == false && + characteristic->getValueAttribute().getMaxLength() != data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + GattWriteAuthCallbackParams params = { + connection_handle, + attr_handle, + /* offset */ 0, + data_length, + data, + /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED + }; + + return characteristic->authorizeWrite(¶ms) & 0xFF; +} + +/**************************************************************************/ +/*! + @brief Returns the GattCharacteristic according to the handle provided + + @param[in] attrHandle + The handle of the attribute + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) +{ + GattCharacteristic *p_char = NULL; + int i; + uint16_t handle, handle_1; + + PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle); + for(i=0; i<characteristicCount; i++) + { + handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + PRINTF("handle(%d)=%d\n\r", i, handle); + if(i==characteristicCount-1)//Last Characteristic check + { + if(attrHandle>=handle) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); + break; + } + } + else { + handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + //Testing if attribute handle is between two Characteristic Handles + if(attrHandle>=handle && attrHandle<handle_1) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); + break; + } else continue; + } + } + + return p_char; +} + +void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { + this->handleDataWrittenEvent(params); +} + +void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { + PRINTF("Called HCIDataReadEvent\n\r"); + this->handleDataReadEvent(params); +} + +void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { + this->handleEvent(type, charHandle); +} + +void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { + this->handleDataSentEvent(count); +} + + +ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { + // <TODO> + return (ble_error_t)0; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::reset(void) +{ + PRINTF("BlueNRGGattServer::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (GattServer::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + /* Clear class members */ + memset(p_characteristics, 0, sizeof(p_characteristics)); + memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles)); + serviceCount = 0; + characteristicCount = 0; + + return BLE_ERROR_NONE; +} + + +/// compute the number of attributes needed by this service. +uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) { + uint16_t attribute_records = 1; + + for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) { + // add two attributes, one for the characteristic declaration + // and the other for the characteristic value. + attribute_records += 2; + + const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index); + const uint8_t properties = characteristic->getProperties(); + // if notify or indicate are present, two attributes are + // needed + if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) || + (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { + attribute_records += 2; + } + + // if broadcast is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) { + attribute_records += 2; + } + + // if extended properties flag is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) { + attribute_records += 2; + } + + attribute_records += characteristic->getDescriptorCount(); + } + + // for some reason, if there is just a service, this value should + // be equal to 5 + if (attribute_records == 1) { + attribute_records = 5; + } + + return attribute_records; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,421 @@ +/** + ****************************************************************************** + * @file ble_hci.c + * @author AMS/HESA Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "ble_gp_timer.h" +#include "ble_debug.h" + +#include "stm32_bluenrg_ble.h" + +#if BLE_CONFIG_DBG_ENABLE +#undef PRINTF +#endif + +#define HCI_LOG_ON 0 + +#define HCI_READ_PACKET_NUM_MAX (0x40) + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tListNode hciReadPktPool; +tListNode hciReadPktRxQueue; + +// betzw - DEBUG: +//#define POOL_CNT +#ifdef POOL_CNT +#include <stdio.h> +static unsigned int nr_hciReadPktPool; +static unsigned int lowest_nr_hciReadPktPool; +#endif // POOL_CNT + +/* pool of hci read packets */ +static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; + +static volatile uint8_t hci_timer_id; +static volatile uint8_t hci_timeout; + +void hci_timeout_callback(void) +{ + hci_timeout = 1; + return; +} + +void HCI_Init(void) +{ + uint8_t index; + +#ifdef POOL_CNT + nr_hciReadPktPool = 0; +#endif // POOL_CNT + + /* Initialize list heads of ready and free hci data packet queues */ + list_init_head (&hciReadPktPool); + list_init_head (&hciReadPktRxQueue); + + /* Initialize the queue of free hci data packets */ + for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) + { + list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif // POOL_CNT + } + +#ifdef POOL_CNT + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif // POOL_CNT +} + +#define HCI_PCK_TYPE_OFFSET 0 +#define EVENT_PARAMETER_TOT_LEN_OFFSET 2 + +/** + * Verify if HCI packet is correctly formatted. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * @return 0 if HCI packet is as expected + */ +int HCI_verify(const tHciDataPacket * hciReadPacket) +{ + const uint8_t *hci_pckt = hciReadPacket->dataBuff; + + if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) + return 1; /* Incorrect type. */ + + if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) + return 2; /* Wrong length (packet truncated or too long). */ + + return 0; +} + +void HCI_Process(void) +{ + tHciDataPacket * hciReadPacket = NULL; + +#ifdef POOL_CNT + printf("betzw(%s, %d): nr_hciReadPktPool = %u (lowest = %u)\r\n", __func__, __LINE__, + nr_hciReadPktPool, lowest_nr_hciReadPktPool); +#endif // POOL_CNT + + Disable_SPI_IRQ(); + uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); + /* process any pending events read */ + while(list_empty == FALSE) + { + list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + Enable_SPI_IRQ(); + HCI_Event_CB(hciReadPacket->dataBuff); + Disable_SPI_IRQ(); + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + list_empty = list_is_empty(&hciReadPktRxQueue); + } + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG. */ + HCI_HandleSPI(); + Enable_SPI_IRQ(); +} + +BOOL HCI_Queue_Empty(void) +{ + return list_is_empty(&hciReadPktRxQueue); +} + +/** + * When an interrupt is raised by BlueNRG, + * just signal that a new event (availability of SPI data to be read) + * needs to be processed. + */ +void HCI_Isr(void) +{ + signalEventsToProcess(); +} + +/** + * Now, SPI Data are handled in user space. + * In case it has to be called in ISR, take care to + * call Disable_SPI_IRQ/Enable_SPI_IRQ in a proper way. + * The calls Disable_SPI_IRQ/Enable_SPI_IRQ have not been removed + * from this code for backward compatibility. + */ +void HCI_HandleSPI(void) +{ + tHciDataPacket * hciReadPacket = NULL; + uint8_t data_len; + + Clear_SPI_EXTI_Flag(); + while(BlueNRG_DataPresent()){ + if (list_is_empty (&hciReadPktPool) == FALSE){ + + /* enqueueing a packet for read */ + list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool--; + if(nr_hciReadPktPool < lowest_nr_hciReadPktPool) + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif + + data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); + if(data_len > 0){ + hciReadPacket->data_len = data_len; + if(HCI_verify(hciReadPacket) == 0) { + list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); + } else { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else { + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else{ + // HCI Read Packet Pool is empty, wait for a free packet. + Clear_SPI_EXTI_Flag(); + return; + } + + Clear_SPI_EXTI_Flag(); + } +} + +void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){ +#if HCI_LOG_ON + PRINTF("HCI <- "); + for(int i=0; i < n_bytes1; i++) + PRINTF("%02X ", *((uint8_t*)data1 + i)); + for(int i=0; i < n_bytes2; i++) + PRINTF("%02X ", *((uint8_t*)data2 + i)); + PRINTF("\n"); +#endif + + Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); +} + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) +{ + hci_command_hdr hc; + + hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); + hc.plen= plen; + + uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; + header[0] = HCI_COMMAND_PKT; + Osal_MemCpy(header+1, &hc, sizeof(hc)); + + hci_write(header, param, sizeof(header), plen); +} + +static void move_list(tListNode * dest_list, tListNode * src_list) +{ + pListNode tmp_node; + + while(!list_is_empty(src_list)){ + list_remove_tail(src_list, &tmp_node); + list_insert_head(dest_list, tmp_node); + } +} + + /* It ensures that we have at least half of the free buffers in the pool. */ +static void free_event_list(void) +{ + tHciDataPacket * pckt; + + Disable_SPI_IRQ(); + + while(list_get_size(&hciReadPktPool) < HCI_READ_PACKET_NUM_MAX/2){ + list_remove_head(&hciReadPktRxQueue, (tListNode **)&pckt); + list_insert_tail(&hciReadPktPool, (tListNode *)pckt); + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG */ + HCI_HandleSPI(); + } + + Enable_SPI_IRQ(); +} + +int hci_send_req(struct hci_request *r, BOOL async) +{ + uint8_t *ptr; + uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + hci_event_pckt *event_pckt; + hci_uart_pckt *hci_hdr; + int to = DEFAULT_TIMEOUT; + struct timer t; + tHciDataPacket * hciReadPacket = NULL; + tListNode hciTempQueue; + + list_init_head(&hciTempQueue); + + free_event_list(); + + hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); + + if(async){ + return 0; + } + + /* Minimum timeout is 1. */ + if(to == 0) + to = 1; + + Timer_Set(&t, to); + + while(1) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + evt_le_meta_event *me; + int len; + + while(1){ + + Disable_SPI_IRQ(); + HCI_HandleSPI(); + Enable_SPI_IRQ(); + + if(Timer_Expired(&t)){ + goto failed; + } + if(!HCI_Queue_Empty()){ + break; + } + } + + /* Extract packet from HCI event queue. */ + Disable_SPI_IRQ(); + list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + + hci_hdr = (void *)hciReadPacket->dataBuff; + + if(hci_hdr->type == HCI_EVENT_PKT){ + + event_pckt = (void *) (hci_hdr->data); + + ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); + len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); + + switch (event_pckt->evt) { + + case EVT_CMD_STATUS: + cs = (void *) ptr; + + if (cs->opcode != opcode) + goto failed; + + if (r->event != EVT_CMD_STATUS) { + if (cs->status) { + goto failed; + } + break; + } + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_CMD_COMPLETE: + cc = (void *) ptr; + + if (cc->opcode != opcode) + goto failed; + + ptr += EVT_CMD_COMPLETE_SIZE; + len -= EVT_CMD_COMPLETE_SIZE; + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_LE_META_EVENT: + me = (void *) ptr; + + if (me->subevent != r->event) + break; + + len -= 1; + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, me->data, r->rlen); + goto done; + + case EVT_HARDWARE_ERROR: + goto failed; + + default: + break; + } + } + + /* If there are no more packets to be processed, be sure there is at list one + packet in the pool to process the expected event. + If no free packets are available, discard the processed event and insert it + into the pool. */ + if(list_is_empty(&hciReadPktPool) && list_is_empty(&hciReadPktRxQueue)){ + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); + hciReadPacket=NULL; + } + else { + /* Insert the packet in a different queue. These packets will be + inserted back in the main queue just before exiting from send_req(), so that + these events can be processed by the application. + */ + list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); + hciReadPacket = NULL; + } + + HCI_HandleSPI(); + + Enable_SPI_IRQ(); + + } + +failed: + if(hciReadPacket != NULL) { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + move_list(&hciReadPktRxQueue, &hciTempQueue); + Enable_SPI_IRQ(); + return -1; + +done: + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + move_list(&hciReadPktRxQueue, &hciTempQueue); + + Enable_SPI_IRQ(); + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,837 @@ +/** + ****************************************************************************** + * @file ble_hci_le.c + * @author AMG RF Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +int hci_reset(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_RESET; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_disconnect(uint16_t handle, uint8_t reason) +{ + struct hci_request rq; + disconnect_cp cp; + uint8_t status; + + cp.handle = handle; + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) +{ + struct hci_request rq; + read_local_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + + *hci_version = resp.hci_version; + *hci_revision = btohs(resp.hci_revision); + *lmp_pal_version = resp.lmp_pal_version; + *manufacturer_name = btohs(resp.manufacturer_name); + *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); + + return 0; +} + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) +{ + struct hci_request rq; + le_read_buffer_size_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_BUFFER_SIZE; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *pkt_len = resp.pkt_len; + *max_pkt = resp.max_pkt; + + return 0; +} + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter) +{ + struct hci_request rq; + le_set_adv_parameters_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.min_interval = min_interval; + adv_cp.max_interval = max_interval; + adv_cp.advtype = advtype; + adv_cp.own_bdaddr_type = own_bdaddr_type; + adv_cp.direct_bdaddr_type = direct_bdaddr_type; + if(direct_bdaddr != NULL) + Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); + adv_cp.chan_map = chan_map; + adv_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_PARAMETERS; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_adv_data_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.length = length; + Osal_MemCpy(adv_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_DATA; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertise_enable(uint8_t enable) +{ + struct hci_request rq; + le_set_advertise_enable_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.enable = enable?1:0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter) +{ + struct hci_request rq; + le_set_scan_parameters_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.type = type; + scan_cp.interval = interval; + scan_cp.window = window; + scan_cp.own_bdaddr_type = own_bdaddr_type; + scan_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) +{ + struct hci_request rq; + le_set_scan_enable_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.enable = enable?1:0; + scan_cp.filter_dup = filter_dup; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_ENABLE; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_rand(uint8_t random_number[8]) +{ + struct hci_request rq; + le_rand_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_RAND; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + Osal_MemCpy(random_number, resp.random, 8); + + return 0; +} + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_scan_response_data_cp scan_resp_cp; + uint8_t status; + + Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); + scan_resp_cp.length = length; + Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; + rq.cparam = &scan_resp_cp; + rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) +{ + struct hci_request rq; + le_read_adv_channel_tx_power_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *tx_power_level = resp.level; + + return 0; +} + +int hci_le_set_random_address(tBDAddr bdaddr) +{ + struct hci_request rq; + le_set_random_address_cp set_rand_addr_cp; + uint8_t status; + + Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); + Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; + rq.cparam = &set_rand_addr_cp; + rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_read_bd_addr(tBDAddr bdaddr) +{ + struct hci_request rq; + read_bd_addr_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_BD_ADDR; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_BD_ADDR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); + + return 0; +} + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) +{ + struct hci_request rq; + le_create_connection_cp create_cp; + uint8_t status; + + Osal_MemSet(&create_cp, 0, sizeof(create_cp)); + create_cp.interval = interval; + create_cp.window = window; + create_cp.initiator_filter = initiator_filter; + create_cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); + create_cp.own_bdaddr_type = own_bdaddr_type; + create_cp.min_interval=min_interval; + create_cp.max_interval=max_interval; + create_cp.latency = latency; + create_cp.supervision_timeout=supervision_timeout; + create_cp.min_ce_length=min_ce_length; + create_cp.max_ce_length=max_ce_length; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN; + rq.cparam = &create_cp; + rq.clen = LE_CREATE_CONN_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_create_connection_cancel(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN_CANCEL; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) +{ + struct hci_request rq; + le_encrypt_cp params; + le_encrypt_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemCpy(params.key, key, 16); + Osal_MemCpy(params.plaintext, plaintextData, 16); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ENCRYPT; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + le_ltk_neg_reply_cp params; + le_ltk_neg_reply_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + params.handle = 1; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_LTK_NEG_REPLY; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CLEAR_WHITE_LIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0){ + return BLE_STATUS_TIMEOUT; + } + + return status; +} + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) +{ + struct hci_request rq; + le_add_device_to_white_list_cp params; + uint8_t status; + + params.bdaddr_type = bdaddr_type; + Osal_MemCpy(params.bdaddr, bdaddr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; + rq.cparam = ¶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/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1309 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB05A1 cp; + gap_init_rp resp; + + cp.role = role; + cp.privacy_enabled = privacy_enabled; + cp.device_name_char_len = device_name_char_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} +tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB04A1 cp; + gap_init_rp resp; + + cp.role = role; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + SlaveConnIntervMin = htobs(SlaveConnIntervMin); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + SlaveConnIntervMax = htobs(SlaveConnIntervMax); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB05A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.directed_adv_type = directed_adv_type; + cp.adv_interv_min = adv_interv_min; + cp.adv_interv_max = adv_interv_max; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB04A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_io_capability(uint8_t io_capability) +{ + struct hci_request rq; + uint8_t status; + gap_set_io_capability_cp cp; + + cp.io_capability = io_capability; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_IO_CAPABILITY; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode) +{ + struct hci_request rq; + gap_set_auth_requirement_cp cp; + uint8_t status; + + cp.mitm_mode = mitm_mode; + cp.oob_enable = oob_enable; + Osal_MemCpy(cp.oob_data, oob_data, 16); + cp.min_encryption_key_size = min_encryption_key_size; + cp.max_encryption_key_size = max_encryption_key_size; + cp.use_fixed_pin = use_fixed_pin; + cp.fixed_pin = htobl(fixed_pin); + cp.bonding_mode = bonding_mode; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) +{ + struct hci_request rq; + gap_set_author_requirement_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorization_enable = authorization_enable; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) +{ + struct hci_request rq; + gap_passkey_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.passkey = htobl(passkey); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_PASSKEY_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) +{ + struct hci_request rq; + gap_authorization_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorize = authorize; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB05A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + cp.own_address_type = own_address_type; + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB04A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) +{ + struct hci_request rq; + gap_set_undirected_connectable_cp cp; + uint8_t status; + + cp.own_addr_type = own_addr_type; + cp.adv_filter_policy = adv_filter_policy; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) +{ + struct hci_request rq; + gap_slave_security_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.bonding = bonding; + cp.mitm_protection = mitm_protection; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[32]; + uint8_t indx = 0; + + if (AdvLen > (sizeof(buffer)-1)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvLen; + indx++; + + Osal_MemCpy(buffer + indx, AdvData, AdvLen); + indx += AdvLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_UPDATE_ADV_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) +{ + struct hci_request rq; + gap_delete_ad_type_cp cp; + uint8_t status; + + cp.ad_type = ad_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_DELETE_AD_TYPE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required) +{ + struct hci_request rq; + gap_get_security_level_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; + rq.rparam = &resp; + rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *mitm_protection = resp.mitm_protection; + *bonding = resp.bonding; + *oob_data = resp.oob_data; + *passkey_required = resp.passkey_required; + + return resp.status; +} + +tBleStatus aci_gap_configure_whitelist(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) +{ + struct hci_request rq; + gap_terminate_cp cp; + uint8_t status; + + cp.handle = htobs(conn_handle); + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_clear_security_database(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) +{ + struct hci_request rq; + gap_allow_rebond_cp_IDB05A1 cp; + uint8_t status; + + cp.conn_handle = conn_handle; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_allow_rebond_IDB04A1(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_limited_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_general_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_name_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = use_reconn_addr; + indx++; + + Osal_MemCpy(buffer + indx, reconn_addr, 6); + indx += 6; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB05A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB04A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.use_reconn_addr = use_reconn_addr; + Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_start_selective_conn_establish_proc_cp cp; + uint8_t status; + + if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.num_whitelist_entries = num_whitelist_entries; + + Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_create_connection_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CREATE_CONNECTION; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; + rq.cparam = &procedure_code; + rq.clen = 1; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_connection_update_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) +{ + struct hci_request rq; + gap_send_pairing_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.force_rebond = force_rebond; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + gap_resolve_private_address_rp rp; + + Osal_MemCpy(cp.address, private_address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); + + return 0; +} +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + uint8_t status; + + Osal_MemCpy(cp.address, address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_set_broadcast_mode_cp cp; + uint8_t status; + uint8_t indx = 0; + uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; + + if (variable_size > sizeof(cp.var_len_data) ) + return BLE_STATUS_INVALID_PARAMS; + + cp.adv_interv_min = htobs(adv_interv_min); + cp.adv_interv_max = htobs(adv_interv_max); + cp.adv_type = adv_type; + cp.own_addr_type = own_addr_type; + + cp.var_len_data[indx] = adv_data_length; + indx++; + Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); + indx += adv_data_length; + cp.var_len_data[indx] = num_whitelist_entries; + indx ++; + Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_BROADCAST_MODE; + rq.cparam = &cp; + rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_observation_proc_cp cp; + uint8_t status; + + cp.scan_interval = scan_interval; + cp.scan_window = scan_window; + cp.scan_type = scan_type; + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_OBSERVATION_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) +{ + struct hci_request rq; + gap_is_device_bonded_cp cp; + uint8_t status; + + cp.peer_address_type = peer_address_type; + Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_IS_DEVICE_BONDED; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) +{ + struct hci_request rq; + gap_get_bonded_devices_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_BONDED_DEVICES; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (rp.status) { + return rp.status; + } + + *num_devices = rp.num_addr; + if(device_list != NULL) + Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1505 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.c +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : File with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_gatt_init(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INIT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[19]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, service_uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = service_type; + indx++; + + buffer[indx] = max_attr_records; + indx++; + + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle) +{ + struct hci_request rq; + gatt_include_serv_rp resp; + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + service_handle = htobs(service_handle); + Osal_MemCpy(buffer, &service_handle, 2); + indx += 2; + + included_start_handle = htobs(included_start_handle); + Osal_MemCpy(buffer+indx, &included_start_handle, 2); + indx += 2; + + included_end_handle = htobs(included_end_handle); + Osal_MemCpy(buffer+indx, &included_end_handle, 2); + indx += 2; + + if(included_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } else { + uuid_len = 16; + } + + buffer[indx] = included_uuid_type; + indx++; + + Osal_MemCpy(buffer + indx, included_uuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INCLUDE_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *included_handle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[25]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + buffer[indx] = charValueLen; + indx++; + + buffer[indx] = charProperties; + indx++; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *charHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle) +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = descValueMaxLen; + indx++; + + buffer[indx] = descValueLen; + indx++; + + if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + Osal_MemCpy(buffer + indx, descValue, descValueLen); + indx += descValueLen; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = accPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR_DESC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *descHandle = btohs(resp.handle); + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = charValOffset; + indx++; + + buffer[indx] = charValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charValue, charValueLen); + indx += charValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_char_cp cp; + + cp.service_handle = htobs(servHandle); + cp.char_handle = htobs(charHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_CHAR; + rq.cparam = &cp; + rq.clen = GATT_DEL_CHAR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_service(uint16_t servHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_serv_cp cp; + + cp.service_handle = htobs(servHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_inc_serv_cp cp; + + cp.service_handle = htobs(servHandle); + cp.inc_serv_handle = htobs(includeServHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_INC_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_INC_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) +{ + struct hci_request rq; + uint8_t status; + gatt_set_evt_mask_cp cp; + + cp.evt_mask = htobs(event_mask); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_EVT_MASK; + rq.cparam = &cp; + rq.clen = GATT_SET_EVT_MASK_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_exchange_config_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_EXCHANGE_CONFIG; + rq.cparam = &cp; + rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) +{ + struct hci_request rq; + uint8_t status; + att_find_info_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_INFO_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_find_by_type_value_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + Osal_MemCpy(cp.uuid, uuid, 2); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_group_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_prepare_write_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.value_offset = htobs(value_offset); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) +{ + struct hci_request rq; + uint8_t status; + att_execute_write_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.execute = execute; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_prim_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_prim_service_by_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; + rq.cparam = &cp; + rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, + uint16_t end_service_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_find_included_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_service_handle); + cp.end_handle = htobs(end_service_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_of_serv_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_attr_handle = htobs(start_attr_handle); + cp.end_attr_handle = htobs(end_attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t charUuidType, + const uint8_t* charUuid) +{ + struct hci_request rq; + uint8_t status; + + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + start_handle = htobs(start_handle); + Osal_MemCpy(buffer + indx, &start_handle, 2); + indx += 2; + + end_handle = htobs(end_handle); + Osal_MemCpy(buffer + indx, &end_handle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == 0x01){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_descriptors_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.char_val_handle = htobs(char_val_handle); + cp.char_end_handle = htobs(char_end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_read_using_charac_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; + rq.cparam = &cp; + rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles) +{ + struct hci_request rq; + uint8_t status; + gatt_read_multiple_charac_val_cp cp; + + if(num_handles*2 > sizeof(cp.set_of_handles)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.num_handles = htobs(num_handles); + Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_long_charac_val_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; + rq.cparam = &cp; + rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_signed_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_confirm_indication_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_CONFIRM_INDICATION; + rq.cparam = &cp; + rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = write_status; + indx += 1; + + buffer[indx] = err_code; + indx += 1; + + buffer[indx] = att_val_len; + indx += 1; + + Osal_MemCpy(buffer + indx, att_val, att_val_len); + indx += att_val_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(uint16_t conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ALLOW_READ; + rq.cparam = &cp; + rq.clen = GATT_ALLOW_READ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission) +{ + struct hci_request rq; + gatt_set_security_permission_cp cp; + uint8_t status; + + cp.service_handle = htobs(service_handle); + cp.attr_handle = htobs(attr_handle); + cp.security_permission = security_permission; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; + rq.cparam = &cp; + rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + charDescHandle = htobs(charDescHandle); + Osal_MemCpy(buffer + indx, &charDescHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charDescValOffset, 2); + indx += 2; + + buffer[indx] = charDescValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); + indx += charDescValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_DESC_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_cp cp; + gatt_read_handle_val_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = btohs(rp.value_len); + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_offset_cp cp; + gatt_read_handle_val_offset_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rp.value_len; + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value) +{ + struct hci_request rq; + uint8_t status; + gatt_upd_char_val_ext_cp cp; + + if(value_length > sizeof(cp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.service_handle = htobs(service_handle); + cp.char_handle = htobs(char_handle); + cp.update_type = update_type; + cp.char_length = htobs(char_length); + cp.value_offset = htobs(value_offset); + cp.value_length = value_length; + Osal_MemCpy(cp.value, value, value_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL_EXT; + rq.cparam = &cp; + rq.clen = GATT_UPD_CHAR_VAL_EXT_CP_SIZE + value_length; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,266 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number) +{ + struct hci_request rq; + hal_get_fw_build_number_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_FW_BUILD_NUMBER; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *build_number = rp.build_number; + + return 0; +} + +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((len+2) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = offset; + indx++; + + buffer[indx] = len; + indx++; + + Osal_MemCpy(buffer + indx, val, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + hal_read_config_data_cp cp; + hal_read_config_data_rp rp; + + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_READ_CONFIG_DATA; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rq.rlen-1; + + Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) +{ + struct hci_request rq; + hal_set_tx_power_level_cp cp; + uint8_t status; + + cp.en_high_power = en_high_power; + cp.pa_level = pa_level; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets) +{ + struct hci_request rq; + hal_le_tx_test_packet_number_rp resp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_LE_TX_TEST_PACKET_NUMBER; + rq.rparam = &resp; + rq.rlen = sizeof(resp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *number_of_packets = btohl(resp.number_of_packets); + + return 0; +} + +tBleStatus aci_hal_device_standby(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_DEVICE_STANDBY; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_start(uint8_t rf_channel) +{ + struct hci_request rq; + hal_tone_start_cp cp; + uint8_t status; + + cp.rf_channel = rf_channel; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_START; + rq.cparam = &cp; + rq.clen = HAL_TONE_START_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_stop(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_STOP; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]) +{ + struct hci_request rq; + hal_get_link_status_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_LINK_STATUS; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(link_status,rp.link_status,sizeof(link_status)); + for(int i = 0; i < 8; i++) + conn_handle[i] = btohs(rp.conn_handle[i]); + + return 0; +} + +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot) +{ + struct hci_request rq; + hal_get_anchor_period_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_ANCHOR_PERIOD; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *anchor_period = btohl(rp.anchor_period); + *max_free_slot = btohl(rp.max_free_slot); + + return 0; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,117 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB05A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.min_ce_length = htobs(min_ce_length); + cp.max_ce_length = htobs(max_ce_length); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB04A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,269 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_updater_aci.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_updater_reboot(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_get_updater_version(uint8_t *version) +{ + struct hci_request rq; + get_updater_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_VERSION; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) +{ + struct hci_request rq; + get_updater_bufsize_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_BUFSIZE; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_reset_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = htobl(address); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_SECTOR; + rq.cparam = &cp; + rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_program_data_block(uint32_t address, + uint16_t len, + const uint8_t *data) +{ + struct hci_request rq; + uint8_t status; + updater_prog_data_block_cp cp; + + if( len > sizeof(cp.data)) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(len); + Osal_MemCpy(cp.data, data, len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_read_data_block(uint32_t address, + uint16_t data_len, + uint8_t *data) +{ + struct hci_request rq; + updater_read_data_block_cp cp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + + if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(data_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; + rq.rparam = buffer; + rq.rlen = data_len + 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + // First byte is status + Osal_MemCpy(data, buffer+1, data_len); + + return buffer[0]; +} + +tBleStatus aci_updater_calc_crc(uint32_t address, + uint8_t num_sectors, + uint32_t *crc) +{ + struct hci_request rq; + updater_calc_crc_cp cp; + updater_calc_crc_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + cp.address = htobl(address); + cp.num_sectors = num_sectors; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_CALC_CRC; + rq.cparam = &cp; + rq.clen = UPDATER_CALC_CRC_CP_SIZE; + rq.rparam = &resp; + rq.rlen = UPDATER_CALC_CRC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *crc = btohl(resp.crc); + + return resp.status; +} + +tBleStatus aci_updater_hw_version(uint8_t *version) +{ + struct hci_request rq; + updater_hw_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_HW_VERSION; + rq.rparam = &resp; + rq.rlen = UPDATER_HW_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,423 @@ + +#include "ble_hal.h" +#include "ble_hal_types.h" +#include "ble_status.h" +#include "bluenrg_aci.h" +#include "bluenrg_utils.h" +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "ble_osal.h" +#include "string.h" +#include "stm32_bluenrg_ble.h" + +#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 +#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 + +#define BASE_ADDRESS 0x10010000 + +#define FW_OFFSET (2*1024) // 2 KB +#define FW_OFFSET_MS 0 +#define FULL_STACK_SIZE (66*1024) // 66 KB +#define BOOTLOADER_SIZE (2*1024) // 2 kB +#define SECTOR_SIZE (2*1024) // 2 KB + +// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + +// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 +#define CRC_POLY 0x04C11DB7 // the poly without the x**32 + +#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC + +#define IFR_SIZE 192 +#define IFR_BASE_ADDRESS 0x10020000 +#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data + +#if BLUENRG_MS +#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET +#else +#define IFR_WRITE_OFFSET_BEGIN 0 +#endif + + +#define BLUE_FLAG_OFFSET 0x8C0 +#define MAX_ERASE_RETRIES 2 +#define MAX_WRITE_RETRIES 2 +#define MIN_WRITE_BLOCK_SIZE 4 +#define MAX_WRITE_BLOCK_SIZE 64 // 64 bytes +#define READ_BLOCK_SIZE 64 // 64 bytes + +#define RETRY_COMMAND(func, num_ret, error) \ +{ \ + uint8_t num_retries; \ + num_retries = 0; \ + error = 0; \ + while (num_retries++ < num_ret) { \ + if (func == BLE_STATUS_SUCCESS) \ + break; \ + if (num_retries == num_ret) \ + error = BLE_UTIL_ACI_ERROR; \ + } \ +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, + they are extended with 0xFF until sector size is reached +*/ +static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) +{ + uint32_t i, j, a1; + uint32_t crc, value; + + crc = 0; + for (i = 0; i < SECTOR_SIZE; i += 4) { + uint8_t *dataw = (uint8_t *) &value; + + dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; + dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; + dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; + dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; + + crc = crc ^ value; + for (j = 0; j < 32; j ++) { + a1 = (crc >> 31) & 0x1; + crc = (crc << 1) ^ (a1 * CRC_POLY); + } + } + + return crc; +} + +int program_device(const uint8_t *fw_image, uint32_t fw_size) +{ + uint8_t version, num_erase_retries, status, write_block_size; + uint32_t address; + uint32_t crc, crc2, crc_size; + uint32_t fw_offset = FW_OFFSET; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + if(aci_updater_hw_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version==0x31){ + // It does not contain bootloader inside first sector. It may contain code. + fw_offset = FW_OFFSET_MS; + } + + if (fw_size != FULL_STACK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + if (fw_size % MIN_WRITE_BLOCK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + + /*********************************************************************** + * Erase BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + /*********************************************************************** + * Erase and Program sectors + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE) { + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(BASE_ADDRESS + i); + for (int j=i; ((j<i+SECTOR_SIZE)&&(j<fw_size)); j += write_block_size) { + + write_block_size = MIN(fw_size-j, MAX_WRITE_BLOCK_SIZE); + + RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, write_block_size, fw_image+j), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + break; + } + if (status == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + } + + /*********************************************************************** + * Verify firmware + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE){ + address = BASE_ADDRESS + i; + if(aci_updater_calc_crc(address, 1, &crc)) + return BLE_UTIL_ACI_ERROR; + + crc_size = MIN(fw_size-i,SECTOR_SIZE); + + crc2 = updater_calc_crc(fw_image+i,crc_size); + if(crc!=crc2) + return BLE_UTIL_CRC_ERROR; + } + + /*********************************************************************** + * Write BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +int read_IFR(uint8_t *data) +{ + uint8_t version, offset; + tBleStatus ret; + + offset = 0; + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + /*********************************************************************** + * Reading last 3 IFR 64-byte blocks + ************************************************************************/ + for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(BASE_ADDRESS+i, READ_BLOCK_SIZE, (data+offset)); + offset += READ_BLOCK_SIZE; + if(ret) return BLE_UTIL_ACI_ERROR; + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; + +} + +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) +{ + IFR_config->stack_mode = data[0]; + IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); + IFR_config->master_sca = data[30]; + IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); + IFR_config->year = BCD_TO_INT(data[41]); + IFR_config->month = BCD_TO_INT(data[42]); + IFR_config->day = BCD_TO_INT(data[43]); +} + +int IFR_validate(IFR_config2_TypeDef *IFR_config) +{ +#if BLUENRG_MS + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) +#else + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) +#endif + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode + if(IFR_config->master_sca > 7) + return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->day > 31 || IFR_config->day < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + + return BLE_STATUS_SUCCESS; +} + +/* TODO: Function to generate data from given options. */ + +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) +{ + data[0] = IFR_config->stack_mode; + HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); + data[30] = IFR_config->master_sca; + HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); + data[41] = INT_TO_BCD(IFR_config->year); + data[42] = INT_TO_BCD(IFR_config->month); + data[43] = INT_TO_BCD(IFR_config->day); +} + + +int program_IFR(const IFR_config_TypeDef *ifr_image) +{ + uint8_t version, num_erase_retries; + tBleStatus ret; +#if BLUENRG_MS + const uint8_t *ifr_data = (uint8_t *)ifr_image; +#else + uint8_t ifr_data[SECTOR_SIZE]; +#endif + uint8_t hwVersion; + uint16_t fwVersion; + + if(getBlueNRGVersion(&hwVersion, &fwVersion)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + +#ifndef BLUENRG_MS + /*********************************************************************** + * READ IFR data + ************************************************************************/ + for(int i = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_data+i); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + } +#endif + + /*********************************************************************** + * Erase & Flashing IFR sectors + ************************************************************************/ +#ifndef BLUENRG_MS + Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); +#endif + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(IFR_BASE_ADDRESS); + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += MAX_WRITE_BLOCK_SIZE, j += MAX_WRITE_BLOCK_SIZE) { + RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, MAX_WRITE_BLOCK_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); + if (ret != BLE_STATUS_SUCCESS) + break; + } + if (ret == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + + /*********************************************************************** + * Verify IFR + ************************************************************************/ + { + uint8_t ifr_updated[READ_BLOCK_SIZE]; + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE, j += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ifr_data+j, READ_BLOCK_SIZE) != 0) + return BLE_UTIL_WRONG_VERIFY; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) +{ + uint8_t ifr_updated[READ_BLOCK_SIZE]; + uint8_t version, ret = BLE_STATUS_SUCCESS; + + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + for(int i = 0; i < IFR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, READ_BLOCK_SIZE) != 0) + { + ret = BLE_UTIL_WRONG_VERIFY; + break; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return ret; +} + +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) +{ + uint8_t status; + uint8_t hci_version, lmp_pal_version; + uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; + + status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, + &manufacturer_name, &lmp_pal_subversion); + + if (status == BLE_STATUS_SUCCESS) { + *hwVersion = hci_revision >> 8; + *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number + *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number + *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number + } + + return status; +} + +uint8_t getBlueNRGUpdaterVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(version)) + return BLE_UTIL_ACI_ERROR; + + if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_updater_hw_version(version)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t isHWBootloader_Patched(void) +{ + uint8_t status, version; + uint32_t crc, address = 0x10010000; + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); + if (status != BLE_STATUS_SUCCESS) + return 0; + + if (crc == BOOTLOADER_CRC_NOT_PATCHED) + return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +#include "ble_gp_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function sets a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * @param[in] t A pointer to the timer + * @param[in] interval The interval before the timer expires. + * + */ +void +Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +Timer_Expired(struct timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + tClockTime diff = (Clock_Time() - t->start) + 1; + return t->interval < diff; + +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +tClockTime +Timer_Remaining(struct timer *t) +{ + return t->start + t->interval - Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +#ifdef __DMA_LP__ + +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID) +{ + TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, + (pf_TIMER_TimerCallBack_t) timercb); + TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); + + return (BLE_STATUS_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) +{ + TIMER_Delete(timerID); + + return (BLE_STATUS_SUCCESS); +} + +#endif /* __DMA_LP__ */ +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,119 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Circular Linked List Implementation. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/****************************************************************************** + * Include Files +******************************************************************************/ +#include <ble_hal_types.h> +#include "ble_list.h" + +/****************************************************************************** + * Function Definitions +******************************************************************************/ +void list_init_head (tListNode * listHead) +{ + listHead->next = listHead; + listHead->prev = listHead; +} + +uint8_t list_is_empty (tListNode * listHead) +{ + return ((listHead->next == listHead)? TRUE:FALSE); +} + +void list_insert_head (tListNode * listHead, tListNode * node) +{ + node->next = listHead->next; + node->prev = listHead; + listHead->next = node; + (node->next)->prev = node; +} + + +void list_insert_tail (tListNode * listHead, tListNode * node) +{ + node->next = listHead; + node->prev = listHead->prev; + listHead->prev = node; + (node->prev)->next = node; +} + + +void list_remove_node (tListNode * node) +{ + (node->prev)->next = node->next; + (node->next)->prev = node->prev; +} + + +void list_remove_head (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->next; + list_remove_node (listHead->next); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_remove_tail (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->prev; + list_remove_node (listHead->prev); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_insert_node_after (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node->next; + node->prev = ref_node; + ref_node->next = node; + (node->next)->prev = node; +} + + +void list_insert_node_before (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node; + node->prev = ref_node->prev; + ref_node->prev = node; + (node->prev)->next = node; +} + + +int list_get_size (tListNode * listHead) +{ + int size = 0; + tListNode * temp = listHead->next; + while (temp != listHead) + { + size++; + temp = temp->next; + } + return (size); +} + +void list_get_next_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->next; +} + + +void list_get_prev_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->prev; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,72 @@ +/** +****************************************************************************** +* @file ble_osal.c +* @author AMS - HEA&RF BU / CL +* @version V1.0.0 +* @date 04-July-2014 +* @brief Implementation of OS abstraction layer functions used by the +* library. +****************************************************************************** +* @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> +#include <ble_osal.h> + + /** + * @brief Osal_MemCpy + * @param dest: Pointer to the destination buffer + * @param src : Pointer to the source buffer + * @param size: Number of bytes to copy from the source to the destination + * buffer + * @retval Pointer to the destination buffer + */ +void* Osal_MemCpy(void *dest, const void *src, unsigned int size) +{ + return(memcpy(dest,src,size)); +} + +/** + * @brief Osal_MemSet + * @param ptr : Pointer to block of memory to fill + * @param value: Value to assign to each byte of the memory block + * @param size : Number of bytes to be set to "value" + * @retval Pointer to the filled block of memory + */ +void* Osal_MemSet(void *ptr, int value, unsigned int size) +{ + return(memset(ptr,value,size)); +} + +/****************************************************************************** + * local Functions + *****************************************************************************/ + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ + +#include "ble_clock.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/wait_api.h" + #include "mbed-drivers/rtc_time.h" +#else + #include "wait_api.h" + #include "rtc_time.h" +#endif + +const uint32_t CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + //Not Used +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return clock(); +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,715 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file btle.cpp + * @author STMicroelectronics + * @brief Implementation BlueNRG Init and helper functions. + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + + +#include "btle.h" +#include "ble/Gap.h" +#include "ble/GapEvents.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" + +#include "bluenrg_targets.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* C File Includes ------------------------------------------------------------------*/ +#include <stdio.h> +#include <string.h> +#include "ble_hci.h" +#include "ble_hci_const.h" +#include "bluenrg_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" +#include "bluenrg_utils.h" + +#include "ble_hal_types.h" +#include "ble_hal.h" +#include "ble_gp_timer.h" +#include "ble_osal.h" +#include "ble_sm.h" +#include "ble_debug.h" + +#ifdef __cplusplus +} +#endif + +#define IDB04A1 0 +#define IDB05A1 1 + +/* See file 'bluenrg_targets.h' for details regarding the BLUENRG_STACK_MODE */ +#define STACK_MODE BLUENRG_STACK_MODE + +void HCI_Input(tHciDataPacket * hciReadPacket); + +uint16_t g_gap_service_handle = 0; +uint16_t g_appearance_char_handle = 0; +uint16_t g_device_name_char_handle = 0; +uint16_t g_preferred_connection_parameters_char_handle = 0; + +/* Private variables ---------------------------------------------------------*/ +volatile uint8_t set_connectable = 1; + +static char versionString[32]; +uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ + +/**************************************************************************/ +/*! + @brief Init the BTLE stack with the specified role + @returns void +*/ +/**************************************************************************/ +void btleInit(void) +{ + PRINTF("btleInit>>\n\r"); + + int ret; + uint8_t hwVersion; + uint16_t fwVersion; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* get the BlueNRG HW and FW versions */ + getBlueNRGVersion(&hwVersion, &fwVersion); + + /* + * Reset BlueNRG again otherwise we won't + * be able to change its MAC address. + * aci_hal_write_config_data() must be the first + * command after reset otherwise it will fail. + */ + BlueNRG_RST(); + + if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ + bnrg_expansion_board = IDB05A1; + } + + /* set BLE version string */ + setVersionString(hwVersion, fwVersion); + + if (bnrg_expansion_board == IDB05A1) { + uint8_t stackMode = STACK_MODE; + ret = aci_hal_write_config_data(CONFIG_DATA_MODE_OFFSET, + CONFIG_DATA_MODE_LEN, + &stackMode); + } + + ret = aci_gatt_init(); + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GATT_Init failed.\n"); + } + if (bnrg_expansion_board == IDB05A1) { + ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1, + 0, + 0x18, + &service_handle, + &dev_name_char_handle, + &appearance_char_handle); + } else { + // IDB04A1 is configured as peripheral by default + ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + } + + // read the default static address and inject it into the GAP object + { + Gap::Address_t BLE_address_BE = { 0 }; + uint8_t data_len_out; + aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS, BDADDR_SIZE, &data_len_out, BLE_address_BE); + // FIXME error handling of this function + BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE); + } + + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GAP_Init failed.\n"); + } + + //FIXME: Security and passkey set by default + ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, + OOB_AUTH_DATA_ABSENT, + NULL, + 7, + 16, + USE_FIXED_PIN_FOR_PAIRING, + 123456, + BONDING); + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Auth Req set failed.\n"); + } + + aci_hal_set_tx_power_level(1,4); + + g_gap_service_handle = service_handle; + g_appearance_char_handle = appearance_char_handle; + g_device_name_char_handle = dev_name_char_handle; + //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API + /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, + strlen(name), (tHalUint8 *)name);*/ + + signalEventsToProcess(); + // update the peripheral preferred conenction parameters handle + // This value is hardcoded at the moment. + g_preferred_connection_parameters_char_handle = 10; + + return; +} + +/**************************************************************************/ +/*! + @brief mbedOS + + @param[in] void + + @returns +*/ +/**************************************************************************/ +int btle_handler_pending = 0; + +void btle_handler(void) +{ + btle_handler_pending = 0; + BlueNRGGap::getInstance().Process(); + HCI_HandleSPI(); + HCI_Process(); +} + +/* set BLE Version string */ +void setVersionString(uint8_t hwVersion, uint16_t fwVersion) +{ + if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) { + snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u", + hwVersion>>4, (hwVersion&0x0F), + fwVersion>>8, (fwVersion&0x00F0)>>4); + } else { + snprintf(versionString, sizeof(versionString), "ST (unknown spec)"); + } +} + +/* get BLE Version string */ +const char* getVersionString(void) +{ + return versionString; +} + +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type) +{ + tBleStatus ret; + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + if(bnrg_expansion_board == IDB05A1) { + PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window); + PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type); + ret = aci_gap_start_observation_procedure(scan_interval, + scan_window, + scan_type, + own_address_type, + 0); // 1 to filter duplicates + } else { + ret = BLE_STATUS_INVALID_CID; + } + + return ret; + +} + +/*! + @brief Not Used + + @param[in] void + + @returns +*/ +void SPI_Poll(void) +{ + //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); + return; +} + +void Attribute_Modified_CB(evt_blue_aci *blue_evt) +{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t *att_data; + uint8_t offset; + + if (bnrg_expansion_board == IDB05A1) { + evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = evt->offset; + } else { + evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = 0; + } + + //Extract the GattCharacteristic from p_characteristics[] and find the properties mask + GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle); + if(p_char!=NULL) { + GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE; + PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]); + PRINTF("getProperties 0x%x\n\r",p_char->getProperties()); + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; + } + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; + } + PRINTF("currentHandle %d\n\r", currentHandle); + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && + currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { + + GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1; + + PRINTF("*****NOTIFICATION CASE\n\r"); + //Now Check if data written in Enable or Disable + if((uint16_t)att_data[0]==1) { + //PRINTF("Notify ENABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle); + } else { + //PRINTF("Notify DISABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle); + } + return; + } + + //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) && + currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) { + + PRINTF("*****WRITE CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = p_char->getValueAttribute().getHandle(); + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle); + //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + BlueNRGGattServer::getInstance().write( + p_char->getValueAttribute().getHandle(), + (uint8_t*)att_data, + data_length, + false + ); + } + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } else { + PRINTF("*****WRITE DESCRIPTOR CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = attr_handle; + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } + } + +} + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************************/ + /*! + @brief Handle HCI Stack Event + + @param[in] pckt + Event Packet sent by the stack to be decoded + + @returns + */ + /**************************************************************************/ + extern void HCI_Event_CB(void *pckt) { + hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; + hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; + + if(hci_pckt->type != HCI_EVENT_PKT) + return; + + switch(event_pckt->evt){ + + case EVT_DISCONN_COMPLETE: + { + PRINTF("EVT_DISCONN_COMPLETE\n"); + + evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data; + + if(BlueNRGGap::getInstance().getGapRole() == Gap::CENTRAL) { + BlueNRGGattClient::getInstance().removeGattConnectionClient(evt->handle, evt->reason); + } + + BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason); + } + break; + + case EVT_LE_META_EVENT: + { + PRINTF("EVT_LE_META_EVENT\n"); + + evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; + + switch(evt->subevent){ + + case EVT_LE_CONN_COMPLETE: + { + PRINTF("EVT_LE_CONN_COMPLETE\n"); + Gap::Address_t ownAddr; + Gap::AddressType_t ownAddrType; + BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr); + + Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + Gap::Role_t role; + + evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; + + BlueNRGGap::getInstance().setConnectionHandle(cc->handle); + BlueNRGGap::ConnectionParams_t connectionParams = { + /* minConnectionInterval = */ cc->interval, + /* maxConnectionInterval = */ cc->interval, + /* slaveLatency = */ cc->latency, + /* connectionSupervisionTimeout = */ cc->supervision_timeout + }; + + BlueNRGGap::getInstance().setConnectionInterval(cc->interval); + + switch (cc->peer_bdaddr_type) { + case PUBLIC_ADDR: + peerAddrType = BLEProtocol::AddressType::PUBLIC; + break; + case STATIC_RANDOM_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + break; + case RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE; + break; + case NON_RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE; + break; + } + //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role); + switch (cc->role) { + case 0: //master + role = Gap::CENTRAL; + BlueNRGGattClient::getInstance().createGattConnectionClient(cc->handle); + break; + case 1: + role = Gap::PERIPHERAL; + break; + default: + role = Gap::PERIPHERAL; + break; + } + + BlueNRGGap::getInstance().setGapRole(role); + + BlueNRGGap::getInstance().processConnectionEvent(cc->handle, + role, + peerAddrType, + cc->peer_bdaddr, + ownAddrType, + ownAddr, + &connectionParams); + } + break; + + case EVT_LE_ADVERTISING_REPORT: + PRINTF("EVT_LE_ADVERTISING_REPORT\n\r"); + /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */ + // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT) + // Formally the structure related to both events are identical except that for the ADV REPORT + // there is one more field (number of reports) which is not forwarded to upper layer. + // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT. + le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1); + PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + break; + } + } + break; + + case EVT_VENDOR: + { + evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; + //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode); + + switch(blue_evt->ecode){ + + case EVT_BLUE_GATT_WRITE_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_WRITE_PERMIT_REQ\r\n"); + evt_gatt_write_permit_req* write_req = (evt_gatt_write_permit_req*)blue_evt->data; + + // ask the local server if the write operation is authorized + uint8_t err_code = BlueNRGGattServer::getInstance().Write_Request_CB( + write_req->conn_handle, + write_req->attr_handle, + write_req->data_length, + write_req->data + ); + uint8_t write_status = err_code == 0 ? 0 : 1; + + // reply to the shield + aci_gatt_write_response( + write_req->conn_handle, + write_req->attr_handle, + write_status, + err_code, + write_req->data_length, + write_req->data + ); + } + break; + + case EVT_BLUE_GATT_READ_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r"); + evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle); + BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle); + } + break; + + case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: + { + PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r"); + /* this callback is invoked when a GATT attribute is modified + extract callback data and pass to suitable handler function */ + Attribute_Modified_CB(blue_evt); + } + break; + + //Any cases for Data Sent Notifications? + case EVT_BLUE_GATT_NOTIFICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_NOTIFICATION"); + break; + case EVT_BLUE_GATT_INDICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_INDICATION"); + break; + + case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r"); + evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_data_length, + pr->attribute_data_list); + } + break; + case EVT_BLUE_ATT_READ_BY_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r"); + evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle, + pr->event_data_length, + pr->handle_value_pair_length, + pr->handle_value_pair); + } + break; + case EVT_BLUE_ATT_READ_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_RESP\n\r"); + evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_value); + } + break; + case EVT_BLUE_ATT_EXEC_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle, + pr->event_data_length); + } + break; + case EVT_BLUE_ATT_PREPARE_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_handle, + pr->offset, + pr->part_attr_value); + } + break; + case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP: + { + PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r"); + evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle, + pr->event_data_length, + pr->attr_handle, + pr->attr_value); + } + break; + case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r"); + evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle, + pr->event_data_length, + pr->handles_info_list); + } + break; + case EVT_BLUE_ATT_FIND_INFORMATION_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r"); + evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle, + pr->event_data_length, + pr->format, + pr->handle_uuid_pair); + } + break; + case EVT_BLUE_GATT_PROCEDURE_COMPLETE: + { + evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code); + BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code); + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_REQ: + { + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_REQ\r\n"); + evt_l2cap_conn_upd_req *evt = (evt_l2cap_conn_upd_req*)blue_evt->data; + if(bnrg_expansion_board == IDB05A1) { + // we assume the application accepts the request from the slave + aci_l2cap_connection_parameter_update_response_IDB05A1(evt->conn_handle, + evt->interval_min, + evt->interval_max, + evt->slave_latency, + evt->timeout_mult, + CONN_L1, CONN_L2, + evt->identifier, + 0x0000); + } + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_RESP: + { + evt_l2cap_conn_upd_resp *evt = (evt_l2cap_conn_upd_resp*)blue_evt->data; + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_RESP code=0x%x, result=0x%x\r\n", evt->code, evt->result); + } + break; + + case EVT_LE_CONN_UPDATE_COMPLETE: + { + evt_le_connection_update_complete *evt = (evt_le_connection_update_complete*)blue_evt->data; + PRINTF("EVT_LE_CONN_UPDATE_COMPLETE status=0x%x\r\n", evt->status); + } + break; + + case EVT_BLUE_GAP_DEVICE_FOUND: + { + evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data; + PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + } + break; + + case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + { + evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data; + //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code); + + switch(pr->procedure_code) { + case GAP_OBSERVATION_PROC_IDB05A1: + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL); + break; + } + } + break; + } + } + break; + } + return ; + } + + +#ifdef __cplusplus +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,217 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.cpp + * @author CL + * @version V1.0.0 + * @date 15-June-2015 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRGGap.h" +#include "BlueNRGDevice.h" +#include "btle.h" + +// FIXME: find a better way to get the instance of the BlueNRG device +extern BlueNRGDevice bluenrgDeviceInstance; + + +//////////////////////////////////////// +// Start of C function wrappers +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32_bluenrg_ble.h" +#include "ble_debug.h" + + +void BlueNRG_RST(void) +{ + bluenrgDeviceInstance.reset(); +} + +uint8_t BlueNRG_DataPresent(void) +{ + return (bluenrgDeviceInstance.dataPresent()); +} + + +/** + * @brief This function is a utility to print the log time +* in the format HH:MM:SS:MSS (DK GUI time format) + * @param None + * @retval None + */ +void print_csv_time(void){ +#ifdef PRINT_CSV_FORMAT + uint32_t ms = 0;//ms_counter; + PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000); +#endif +} + +/** + * @brief Writes data to a serial interface. + * @param data1 : 1st buffer + * @param data2 : 2nd buffer + * @param n_bytes1: number of bytes in 1st buffer + * @param n_bytes2: number of bytes in 2nd buffer + * @retval None + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, + int32_t n_bytes2) +{ + struct timer t; + + Timer_Set(&t, CLOCK_SECOND/10); + +#ifdef PRINT_CSV_FORMAT + print_csv_time(); + for (int i=0; i<n_bytes1; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data1)[i]); + } + for (int i=0; i<n_bytes2; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data2)[i]); + } + PRINT_CSV("\n"); +#endif + + while(1){ + if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; + if(Timer_Expired(&t)){ + break; + } + } +} + + +/** + * @brief Activate internal bootloader using pin. + * @param None + * @retval None + */ +void BlueNRG_HW_Bootloader(void) +{ + // Reset BlueNRG SPI interface + BlueNRG_RST(); + + // Send an ACI command to reboot BlueNRG in bootloader mode + // The safest way to get in bootloader mode is keeping high + // the interrupt pin during reset, but this would require many + // changes to the current mbed driver + aci_updater_start(); +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size) +{ + int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size); + + return ret; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2); + + return ret; +} + +/** + * @brief Enable SPI IRQ. + * @param None + * @retval None + */ +void Enable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.enable_irq(); +} + +void signalEventsToProcess(void) { + if(btle_handler_pending == 0) { + btle_handler_pending = 1; + bluenrgDeviceInstance.signalEventsToProcess(BLE::DEFAULT_INSTANCE); + } +} + +/** + * @brief Disable SPI IRQ. + * @param None + * @retval None + */ +void Disable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.disable_irq(); +} + +/** + * @brief Clear Pending SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_IRQ(void) +{ +} + +/** + * @brief Clear EXTI (External Interrupt) line for SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_EXTI_Flag(void) +{ +} + + + + +#ifdef __cplusplus +} +#endif +// End of C function wrappers +//////////////////////////////////////// + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <ble_payload.h> + +Payload::Payload() { + stringLength = 0; + payloadUnitCount = 0; + payload = NULL; +} + +Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + stringLength = string_ength; + payloadUnitCount = 0; + payload = NULL; + + int index = 0; + while( index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + UnitPayload *obj = new UnitPayload[payloadUnitCount]; + int i=0; + int c=0; + int j,k; + + while(i<payloadUnitCount) + { + obj[i].length=tokenString[c]; + obj[i].id=tokenString[c+1]; + + obj[i].data = new uint8_t[obj[i].length]; + for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) + { + obj[i].data[k]=tokenString[j]; + + } + + c=c+obj[i].length+1; + i++; + + } + payload = obj; +} + +uint8_t Payload::getPayloadUnitCount() { + return payloadUnitCount; +} + +uint8_t Payload::getIDAtIndex(int index) { + return payload[index].get_id(); +} + +uint8_t Payload::getLengthAtIndex(int index) { + return payload[index].get_length(); +} + +uint8_t* Payload::getDataAtIndex(int index) { + return payload[index].get_data(); +} + +int8_t Payload::getInt8AtIndex(int index) { + uint8_t* str = payload[index].get_data(); + int8_t value = (int8_t)str[0]; + return value; +} + +uint16_t Payload::getUint16AtIndex(int index) { + uint16_t* str = (uint16_t*)payload[index].get_data(); + uint16_t value = str[0]; + return value; +} + +uint8_t* Payload::getSerializedAdDataAtIndex(int index) { + uint8_t length = payload[index].get_length(); + uint8_t* data = payload[index].get_data(); + uint8_t id = payload[index].get_id(); + uint8_t *serializedAdData = new uint8_t[length]; + + serializedAdData[0] = id; + for(int i=0; i<length-1; i++) { + serializedAdData[i+1] = data[i]; + } + return serializedAdData; +} + +Payload::~Payload() { + int i = 0; + + if(payload) { + while(i<payloadUnitCount) { + if(payload->data) { + delete[] payload->data; + payload->data = NULL; + } + } + delete[] payload; + payload = NULL; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,93 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ble_utils.h" + +/**************************************************************************/ +/*! + @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power + +*/ +/**************************************************************************/ +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(dBMLevel==-18) { + EN_HIGH_POWER = 0; + PA_LEVEL = 0; + } + else if(dBMLevel==-15) { + EN_HIGH_POWER = 0; + PA_LEVEL = 1; + } + else if(dBMLevel==-14) { + EN_HIGH_POWER = 1; + PA_LEVEL = 0; + } + else if(dBMLevel==-12) { + EN_HIGH_POWER = 0; + PA_LEVEL = 2; + } + else if(dBMLevel==-11) { + EN_HIGH_POWER = 1; + PA_LEVEL = 1; + } + else if(dBMLevel==-9) { + EN_HIGH_POWER = 0; + PA_LEVEL = 3; + } + else if(dBMLevel==-8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 2; + } + else if(dBMLevel==-6) { + EN_HIGH_POWER = 0; + PA_LEVEL = 4; + } + else if(dBMLevel==-5) { + EN_HIGH_POWER = 1; + PA_LEVEL = 3; + } + else if(dBMLevel==-2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 4; + } + else if(dBMLevel==0) { + EN_HIGH_POWER = 0; + PA_LEVEL = 6; + } + else if(dBMLevel==2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 5; + } + else if(dBMLevel==4) { + EN_HIGH_POWER = 1; + PA_LEVEL = 6; + } + else if(dBMLevel==5) { + EN_HIGH_POWER = 0; + PA_LEVEL = 7; + } + else if(dBMLevel==8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + else { + ret = ERR_INVALID_HCI_CMD_PARAMS; + } + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAP/source/main.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,526 @@ +/* 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 <events/mbed_events.h> +#include <mbed.h> +#include "ble/BLE.h" + +/** This example demonstrates all the basic setup required + * to advertise, scan and connect to other devices. + * + * It contains a single class that performs both scans and advertisements. + * + * The demonstrations happens in sequence, after each "mode" ends + * the demo jumps to the next mode to continue. There are several modes + * that show scanning and several showing advertising. These are configured + * according to the two arrays containing parameters. During scanning + * a connection will be made to a connectable device upon its discovery. + */ + +static const uint8_t DEVICE_NAME[] = "GAP_device"; + +/* Duration of each mode in milliseconds */ +static const size_t MODE_DURATION_MS = 6000; + +/* Time between each mode in milliseconds */ +static const size_t TIME_BETWEEN_MODES_MS = 2000; + +/* how long to wait before disconnecting in milliseconds */ +static const size_t CONNECTION_DURATION = 3000; + +typedef struct { + GapAdvertisingParams::AdvertisingType_t adv_type; + uint16_t interval; + uint16_t timeout; +} AdvModeParam_t; + +typedef struct { + uint16_t interval; + uint16_t window; + uint16_t timeout; + bool active; +} ScanModeParam_t; + +/** the entries in this array are used to configure our advertising + * parameters for each of the modes we use in our demo */ +static const AdvModeParam_t advertising_params[] = { + /* advertising type interval timeout */ + { GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, 40,/*ms*/ 3/*s*/}, + { GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED, 100, 4 }, + { GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED, 100, 0 } +}; + +/* when we cycle through all our advertising modes we will move to scanning modes */ + +/** the entries in this array are used to configure our scanning + * parameters for each of the modes we use in our demo */ +static const ScanModeParam_t scanning_params[] = { +/* interval window timeout active */ + { 4,/*ms*/ 4,/*ms*/ 0,/*s*/ false }, + { 160, 100, 3, false }, + { 160, 40, 0, true }, + { 500, 10, 0, false } +}; + +/* parameters to use when attempting to connect to maximise speed of connection */ +static const GapScanningParams connection_scan_params( + GapScanningParams::SCAN_INTERVAL_MAX, + GapScanningParams::SCAN_WINDOW_MAX, + 3, + false +); + +/* get number of items in our arrays */ +static const size_t SCAN_PARAM_SET_MAX = + sizeof(scanning_params) / sizeof(GapScanningParams); +static const size_t ADV_PARAM_SET_MAX = + sizeof(advertising_params) / sizeof(GapAdvertisingParams); + + +/** Demonstrate advertising, scanning and connecting + */ +class GAPDevice : private mbed::NonCopyable<GAPDevice> +{ +public: + GAPDevice() : + _ble(BLE::Instance()), + _led1(LED1, 0), + _set_index(0), + _is_in_scanning_mode(false), + _is_connecting(false), + _on_duration_end_id(0), + _scan_count(0) { }; + + ~GAPDevice() + { + if (_ble.hasInitialized()) { + _ble.shutdown(); + } + }; + + /** Start BLE interface initialisation */ + void run() + { + ble_error_t error; + + if (_ble.hasInitialized()) { + printf("Ble instance already initialised.\r\n"); + return; + } + + /* this will inform us off all events so we can schedule their handling + * using our event queue */ + _ble.onEventsToProcess( + makeFunctionPointer(this, &GAPDevice::schedule_ble_events) + ); + + /* handle timeouts, for example when connection attempts fail */ + _ble.gap().onTimeout( + makeFunctionPointer(this, &GAPDevice::on_timeout) + ); + + error = _ble.init(this, &GAPDevice::on_init_complete); + + if (error) { + printf("Error returned by BLE::init.\r\n"); + return; + } + + /* to show we're running we'll blink every 500ms */ + _event_queue.call_every(500, this, &GAPDevice::blink); + + /* this will not return until shutdown */ + _event_queue.dispatch_forever(); + }; + +private: + /** This is called when BLE interface is initialised and starts the first mode */ + void on_init_complete(BLE::InitializationCompleteCallbackContext *event) + { + if (event->error) { + printf("Error during the initialisation\r\n"); + return; + } + + /* print device address */ + Gap::AddressType_t addr_type; + Gap::Address_t addr; + _ble.gap().getAddress(&addr_type, addr); + printf("Device address: %02x:%02x:%02x:%02x:%02x:%02x\r\n", + addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + + /* all calls are serialised on the user thread through the event queue */ + _event_queue.call(this, &GAPDevice::demo_mode_start); + }; + + /** queue up start of the current demo mode */ + void demo_mode_start() + { + if (_is_in_scanning_mode) { + /* when scanning we want to connect to a peer device so we need to + * attach callbacks that are used by Gap to notify us of events */ + _ble.gap().onConnection(this, &GAPDevice::on_connect); + _ble.gap().onDisconnection(this, &GAPDevice::on_disconnect); + + _event_queue.call(this, &GAPDevice::scan); + } else { + _event_queue.call(this, &GAPDevice::advertise); + } + + /* for performance measurement keep track of duration of the demo mode */ + _demo_duration.start(); + /* keep track of our state */ + _is_connecting = false; + + /* queue up next demo mode */ + _on_duration_end_id = _event_queue.call_in( + MODE_DURATION_MS, this, &GAPDevice::on_duration_end + ); + + printf("\r\n"); + } + + /** Set up and start advertising */ + void advertise() + { + ble_error_t error; + GapAdvertisingData advertising_data; + + /* add advertising flags */ + advertising_data.addFlags(GapAdvertisingData::LE_GENERAL_DISCOVERABLE + | GapAdvertisingData::BREDR_NOT_SUPPORTED); + + /* add device name */ + advertising_data.addData( + GapAdvertisingData::COMPLETE_LOCAL_NAME, + DEVICE_NAME, + sizeof(DEVICE_NAME) + ); + + error = _ble.gap().setAdvertisingPayload(advertising_data); + + if (error) { + printf("Error during Gap::setAdvertisingPayload\r\n"); + return; + } + + /* set the advertising parameters according to currently selected set, + * see @AdvertisingType_t for explanation of modes */ + GapAdvertisingParams::AdvertisingType_t adv_type = + advertising_params[_set_index].adv_type; + + /* how many milliseconds between advertisements, lower interval + * increases the chances of being seen at the cost of more power */ + uint16_t interval = advertising_params[_set_index].interval; + + /* advertising will continue for this many seconds or until connected */ + uint16_t timeout = advertising_params[_set_index].timeout; + + _ble.gap().setAdvertisingType(adv_type); + _ble.gap().setAdvertisingInterval(interval); + _ble.gap().setAdvertisingTimeout(timeout); + + error = _ble.gap().startAdvertising(); + + if (error) { + printf("Error during Gap::startAdvertising.\r\n"); + return; + } + + printf("Advertising started (type: 0x%x, interval: %dms, timeout: %ds)\r\n", + adv_type, interval, timeout); + }; + + /** Set up and start scanning */ + void scan() + { + ble_error_t error; + + /* scanning happens repeatedly, interval is the number of milliseconds + * between each cycle of scanning */ + uint16_t interval = scanning_params[_set_index].interval; + + /* number of milliseconds we scan for each time we enter + * the scanning cycle after the interval set above */ + uint16_t window = scanning_params[_set_index].window; + + /* how long to repeat the cycles of scanning in seconds */ + uint16_t timeout = scanning_params[_set_index].timeout; + + /* active scanning will send a scan request to any scanable devices that + * we see advertising */ + bool active = scanning_params[_set_index].active; + + /* set the scanning parameters according to currently selected set */ + error = _ble.gap().setScanParams(interval, window, timeout, active); + + if (error) { + printf("Error during Gap::setScanParams\r\n"); + return; + } + + /* start scanning and attach a callback that will handle advertisements + * and scan requests responses */ + error = _ble.gap().startScan(this, &GAPDevice::on_scan); + + if (error) { + printf("Error during Gap::startScan\r\n"); + return; + } + + printf("Scanning started (interval: %dms, window: %dms, timeout: %ds).\r\n", + interval, window, timeout); + }; + + /** After a set duration this cycles to the next demo mode + * unless a connection happened first */ + void on_duration_end() + { + print_performance(); + + /* alloted time has elapsed, move to next demo mode */ + _event_queue.call(this, &GAPDevice::demo_mode_end); + }; + + /** Look at scan payload to find a peer device and connect to it */ + void on_scan(const Gap::AdvertisementCallbackParams_t *params) + { + /* keep track of scan events for performance reporting */ + _scan_count++; + + /* don't bother with analysing scan result if we're already connecting */ + if (_is_connecting) { + return; + } + + /* parse the advertising payload, looking for a discoverable device */ + for (uint8_t i = 0; i < params->advertisingDataLen; ++i) { + /* The advertising payload is a collection of key/value records where + * byte 0: length of the record excluding this byte + * byte 1: The key, it is the type of the data + * byte [2..N] The value. N is equal to byte0 - 1 */ + const uint8_t record_length = params->advertisingData[i]; + if (record_length == 0) { + continue; + } + const uint8_t type = params->advertisingData[i + 1]; + const uint8_t *value = params->advertisingData + i + 2; + + /* connect to a discoverable device */ + if ((type == GapAdvertisingData::FLAGS) + && (*value & GapAdvertisingData::LE_GENERAL_DISCOVERABLE)) { + + /* abort timeout as the mode will end on disconnection */ + _event_queue.cancel(_on_duration_end_id); + + printf("We found a connectable device\r\n"); + + ble_error_t error = _ble.gap().connect( + params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, + NULL, &connection_scan_params + ); + + if (error) { + printf("Error during Gap::connect\r\n"); + /* since no connection will be attempted end the mode */ + _event_queue.call(this, &GAPDevice::demo_mode_end); + return; + } + + /* we may have already scan events waiting + * to be processed so we need to remember + * that we are already connecting and ignore them */ + _is_connecting = true; + + return; + } + + i += record_length; + } + }; + + /** This is called by Gap to notify the application we connected, + * in our case it immediately disconnects */ + void on_connect(const Gap::ConnectionCallbackParams_t *connection_event) + { + print_performance(); + + printf("Connected in %dms\r\n", _demo_duration.read_ms()); + + /* cancel the connect timeout since we connected */ + _event_queue.cancel(_on_duration_end_id); + + _event_queue.call_in( + CONNECTION_DURATION, &_ble.gap(), &Gap::disconnect, Gap::REMOTE_USER_TERMINATED_CONNECTION + ); + }; + + /** This is called by Gap to notify the application we disconnected, + * in our case it calls demo_mode_end() to progress the demo */ + void on_disconnect(const Gap::DisconnectionCallbackParams_t *event) + { + printf("Disconnected\r\n"); + + /* we have successfully disconnected ending the demo, move to next mode */ + _event_queue.call(this, &GAPDevice::demo_mode_end); + }; + + /** called if timeout is reached during advertising, scanning + * or connection initiation */ + void on_timeout(const Gap::TimeoutSource_t source) + { + _demo_duration.stop(); + + switch (source) { + case Gap::TIMEOUT_SRC_ADVERTISING: + printf("Stopped advertising early due to timeout parameter\r\n"); + break; + case Gap::TIMEOUT_SRC_SCAN: + printf("Stopped scanning early due to timeout parameter\r\n"); + break; + case Gap::TIMEOUT_SRC_CONN: + printf("Failed to connect after scanning %d advertisements\r\n", _scan_count); + _event_queue.call(this, &GAPDevice::print_performance); + _event_queue.call(this, &GAPDevice::demo_mode_end); + break; + default: + printf("Unexpected timeout\r\n"); + break; + } + }; + + /** clean up after last run, cycle to the next mode and launch it */ + void demo_mode_end() + { + /* reset the demo ready for the next mode */ + _scan_count = 0; + _demo_duration.stop(); + _demo_duration.reset(); + + /* cycle through all demo modes */ + _set_index++; + + /* switch between advertising and scanning when we go + * through all the params in the array */ + if (_set_index >= (_is_in_scanning_mode? SCAN_PARAM_SET_MAX : ADV_PARAM_SET_MAX)) { + _set_index = 0; + _is_in_scanning_mode = !_is_in_scanning_mode; + } + + _ble.shutdown(); + _event_queue.break_dispatch(); + }; + + /** print some information about our radio activity */ + void print_performance() + { + /* measure time from mode start, may have been stopped by timeout */ + uint16_t duration = _demo_duration.read_ms(); + + if (_is_in_scanning_mode) { + /* convert ms into timeslots for accurate calculation as internally + * all durations are in timeslots (0.625ms) */ + uint16_t interval_ts = GapScanningParams::MSEC_TO_SCAN_DURATION_UNITS( + scanning_params[_set_index].interval + ); + uint16_t window_ts = GapScanningParams::MSEC_TO_SCAN_DURATION_UNITS( + scanning_params[_set_index].window + ); + uint16_t duration_ts = GapScanningParams::MSEC_TO_SCAN_DURATION_UNITS( + duration + ); + /* this is how long we scanned for in timeslots */ + uint16_t rx_ts = (duration_ts / interval_ts) * window_ts; + /* convert to milliseconds */ + uint16_t rx_ms = (rx_ts * GapScanningParams::UNIT_0_625_MS) / 1000; + + printf("We have scanned for %dms with an interval of %d" + " timeslot and a window of %d timeslots\r\n", + duration, interval_ts, window_ts); + + printf("We have been listening on the radio for at least %dms\r\n", rx_ms); + + } else /* advertising */ { + + /* convert ms into timeslots for accurate calculation as internally + * all durations are in timeslots (0.625ms) */ + uint16_t interval_ts = GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS( + advertising_params[_set_index].interval + ); + uint16_t duration_ts = GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS( + duration + ); + /* this is how many times we advertised */ + uint16_t events = duration_ts / interval_ts; + + printf("We have advertised for %dms" + " with an interval of %d timeslots\r\n", + duration, interval_ts); + + /* non-scannable and non-connectable advertising + * skips rx events saving on power consumption */ + if (advertising_params[_set_index].adv_type + == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { + printf("We created at least %d tx events\r\n", events); + } else { + printf("We created at least %d tx and rx events\r\n", events); + } + } + }; + + /** Schedule processing of events from the BLE middleware in the event queue. */ + void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) + { + _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents)); + }; + + /** Blink LED to show we're running */ + void blink(void) + { + _led1 = !_led1; + }; + +private: + BLE &_ble; + events::EventQueue _event_queue; + DigitalOut _led1; + + /* Keep track of our progress through demo modes */ + size_t _set_index; + bool _is_in_scanning_mode; + bool _is_connecting; + + /* Remember the call id of the function on _event_queue + * so we can cancel it if we need to end the mode early */ + int _on_duration_end_id; + + /* Measure performance of our advertising/scanning */ + Timer _demo_duration; + size_t _scan_count; +}; + +int main() +{ + GAPDevice gap_device; + + while (1) { + gap_device.run(); + wait_ms(TIME_BETWEEN_MODES_MS); + printf("\r\nStarting next GAP demo mode\r\n"); + }; + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/.mbed Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +ROOT=.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,87 @@ +# Button count over GAP + +This application shows how to use GAP to transmit a simple value to a disconnected peer listening for advertisement every time that a value is updated: + +1. The value is a count of how many times a button on the device was pressed (the code actually monitors the button's releases, not press downs). + +1. We transmit the value in the SERVICE_DATA field of the advertising payload. + +# Running the application + +## Requirements + +The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : + +- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. + +- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +### Porting this example on new boards + +This example requires a board with at least 1 button to work. While the pin name of the button is defined for the `NRF51_DK`, `NRF52_DK`, `K64F` and `NUCLEO_F401RE`, it is not specified for other boards. + +It is easy to add the button configuration for your board: +* Open the file named `mbed_app.json` at the root of this example. +* In the section `target_overides` add a new object named after your target if it doesn't exist. This object contain overridden parameters for your target. +* Override the property `ble_button_pin_name` in your target object. The value of the property should be equal to the pin name to use as a button. + +As an example, this is the JSON bit which has to be added in the `target_overrides` section of `mbed_app.json` for a `NUCLEO_F411RE` board. + +```json + "NUCLEO_F411RE": { + "ble_button_pin_name": "USER_BUTTON" + } +``` + +<span> **Note:** You can get more informations about the configuration system in the [documentation](https://github.com/ARMmbed/mbed-os/blob/master/docs/config_system.md)</span> + +<span> **Important:** If your target use an ST BLE shield, other parameters have to be overridden for your target. More information are available in the global [README](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md#targets-for-ble)</span> + + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Checking for success + +**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. + +1. Build the application and install it on your board as explained in the building instructions. + +1. Open the BLE scanner on your phone. + +1. Start a scan. + +  + + **figure 1** How to start scan using nRF Master Control Panel 4.0.5. + +1. Find your device; it should be named `GAPButton`; and look at the advertisement broadcasted by your device (there is no need to connect to your device). + +  + + **figure 2** Scan results using nRF Master Control Panel 4.0.5. + +1. The Service Data field of the advertisement packet broadcasted by your device reflects the button press count. The starting value is 0. + +  + + **figure 3** Initial state of the button using nRF Master Control Panel 4.0.5. + +1. Press the button on the device. + +  + + **figure 3** State after 1 button press using nRF Master Control Panel 4.0.5. + +1. The Service Data field value of the advertisement packet should change every time you press the button. + +  + + **figure 3** State after 6 button press using nRF Master Control Panel 4.0.5. + +## Note + +Since broadcasting is not reliable and your phone may scan intermittently, it is possible that your phone will miss button updates.
Binary file mbed-os-example-ble-master/BLE_GAPButton/img/discovery.png has changed
Binary file mbed-os-example-ble-master/BLE_GAPButton/img/first_press.png has changed
Binary file mbed-os-example-ble-master/BLE_GAPButton/img/initial_state.png has changed
Binary file mbed-os-example-ble-master/BLE_GAPButton/img/result.png has changed
Binary file mbed-os-example-ble-master/BLE_GAPButton/img/start_scan.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/mbed-os.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/mbed_app.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,35 @@ +{ + "config": { + "ble_button_pin_name": { + "help": "The pin name used as button in this application", + "macro_name": "BLE_BUTTON_PIN_NAME", + "required": true + } + }, + "target_overrides": { + "NRF51_DK": { + "ble_button_pin_name": "BUTTON1" + }, + "NRF52_DK": { + "ble_button_pin_name": "BUTTON1" + }, + "MTB_UBLOX_NINA_B1": { + "ble_button_pin_name": "BUTTON1" + }, + "K64F": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"], + "ble_button_pin_name": "SW2" + }, + "NUCLEO_F401RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"], + "ble_button_pin_name": "USER_BUTTON" + }, + "DISCO_L475VG_IOT01A": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"], + "ble_button_pin_name": "USER_BUTTON" + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,12 @@ +{ + "name": "ble-gapbutton", + "version": "0.0.1", + "bin": "./source", + "description": "BLE button that uses gap advertisement to broadcast its state.", + "author": "Liyou Zhou", + "license": "Apache-2.0", + "dependencies": { + "mbed-drivers": "*", + "ble": "^2.0.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/#b630517008bbe47592927cc8e5dfcd2e5b9de968
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/.gitignore Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,9 @@ +# vim temporary files +*.sw* + +# yotta files +build +yotta_modules +yotta_targets +.yotta.json +upload.tar.gz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,34 @@ +# BLE-X-NUCLEO-IDB0XA1 + +BLE_API wrapper Library for X-NUCLEO-IDB05A1 BlueNRG (Bluetooth Low Energy) Expansion Board + +## Introduction + +This firmware package implements the port of BLE_API to STMicroelectronics' [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) Bluetooth Low Energy Nucleo Expansion Board. + +### Arduino Connector Compatibility Warning + +X-NUCLEO-IDB05A1 is Arduino compatible with an exception: instead of using pin **D13** for the SPI clock, pin **D3** is used. +The default configuration for this library is having the SPI clock on pin **D3**. + +To be fully Arduino compatible, X-NUCLEO-IDB05A1 needs a small HW patch. + +For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor **R4** and instead soldering zero resistor **R6**. + +In case you patch your board, then you also have to configure this library to use pin **D13** to drive the SPI clock. To this aim you need to compile this driver with macro `BLUENRG_PIN_SPI_SCK=D13` defined. + +If you use pin **D13** for the SPI clock, please be aware that on STM32 Nucleo boards you may **not** drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin **D13**. + +Referring to the current list of tested platforms (see [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) page), the patch is required by [ST-Nucleo-F103RB](https://developer.mbed.org/platforms/ST-Nucleo-F103RB/); [ST-Nucleo-F302R8](https://developer.mbed.org/platforms/ST-Nucleo-F302R8/); [ST-Nucleo-F411RE](https://developer.mbed.org/platforms/ST-Nucleo-F411RE/); [ST-Nucleo-F446RE](https://developer.mbed.org/platforms/ST-Nucleo-F446RE/); and [FRDM-K64F](https://developer.mbed.org/platforms/FRDM-K64F/). + +### Firmware update + +For better performance and compatibility with latest mbed API, you should update firmware of X-NUCLEO-IDB05A1 component by using this simple [application](https://developer.mbed.org/teams/ST/code/BlueNRG-MS-Stack-Updater). + +### Driver configuration + +In order to use the BlueNRG-MS module together with other targets, you need to set the macros defined in file [bluenrg_targets.h](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/bluenrg/bluenrg_targets.h). Please, update the [mbed_lib.json](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/mbed_lib.json) to include the list of extra macros that configure the driver for your target. + +## Example Applications + +To run BLE example applications using X-NUCLEO-IDB05A1 Expansion Board based on mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli), please refer to section [Using ST shield on other targets](https://github.com/ARMmbed/mbed-os-example-ble#using-st-nucleo-shield-on-other-targets) in the official [mbed-os-example-ble](https://github.com/ARMmbed/mbed-os-example-ble) page.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.h + * @author STMicroelectronics + * @brief Header file for BLEDeviceInstanceBase based BlueNRGDevice + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_DEVICE_H__ +#define __BLUENRG_DEVICE_H__ + +#define BLUENRG +#define DEBUG_BLUENRG_USER + +#include "btle.h" + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "ble/BLEInstanceBase.h" +#include "ble/BLE.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" + + +class BlueNRGDevice : public BLEInstanceBase +{ + +public: + BlueNRGDevice(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, PinName irq); + virtual ~BlueNRGDevice(void); + + virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback); + virtual ble_error_t shutdown(void); + virtual const char *getVersion(void); + virtual Gap& getGap(); + virtual const Gap& getGap() const; + virtual GattServer& getGattServer(); + virtual const GattServer& getGattServer() const; + virtual void waitForEvent(void); + + virtual GattClient& getGattClient() { + return BlueNRGGattClient::getInstance(); + } + + virtual SecurityManager& getSecurityManager() { + return *sm; + } + + virtual const SecurityManager& getSecurityManager() const { + return *sm; + } + void reset(void); + virtual bool hasInitialized(void) const { + return isInitialized; + } + + uint8_t getUpdaterHardwareVersion(uint8_t *hw_version); + int updateFirmware(const uint8_t *fw_image, uint32_t fw_size); + bool dataPresent(); + int32_t spiRead(uint8_t *buffer, uint8_t buff_size); + int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2); + void disable_irq(); + void enable_irq(); + + virtual void processEvents(); + +private: + bool isInitialized; + + SPI spi_; + DigitalOut nCS_; + DigitalOut rst_; + InterruptIn irq_; + + //FIXME: TBI (by now just placeholders to let build + /*** betzw: placeholders ***/ + SecurityManager *sm; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ +#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ + +#include "ble/DiscoveredCharacteristic.h" + +class BlueNRGGattClient; /* forward declaration */ + +class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic { +public: + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + + void setLastHandle(GattAttribute::Handle_t lastHandleIn); +}; + +#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGGap.h + * @author STMicroelectronics + * @brief Header file for BlueNRG BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GAP_H__ +#define __BLUENRG_GAP_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/Gap.h" + +#define BLE_CONN_HANDLE_INVALID 0x0 +#define BDADDR_SIZE 6 + +#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020) +#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000) +#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0) + +// Scanning and Connection Params used by Central for creating connection +#define GAP_OBSERVATION_PROC (0x80) + +#define SCAN_P (0x0010) +#define SCAN_L (0x0010) +#define SUPERV_TIMEOUT (0xC80) +#define CONN_P(x) ((int)((x)/1.25f)) +#define CONN_L(x) ((int)((x)/0.625f)) +#define CONN_P1 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_P2 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_L1 (0x0008) +#define CONN_L2 (0x0008) +#define GUARD_INT 5 //msec +#define MIN_INT_CONN 0x0006 //=>7.5msec +#define MAX_INT_CONN 0x0C80 //=>4000msec +#define DEF_INT_CONN 0x0140 //=>400msec (default value for connection interval) + +/**************************************************************************/ +/*! + \brief + +*/ +/**************************************************************************/ +class BlueNRGGap : public Gap +{ +public: + static BlueNRGGap &getInstance() { + static BlueNRGGap m_instance; + return m_instance; + } + + enum Reason_t { + DEVICE_FOUND, + DISCOVERY_COMPLETE + }; + + /* Functions that must be implemented from Gap */ + virtual ble_error_t setAddress(addr_type_t type, const BLEProtocol::AddressBytes_t address); + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address); + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &); + virtual ble_error_t startAdvertising(const GapAdvertisingParams &); + virtual ble_error_t stopAdvertising(void); + virtual ble_error_t stopScan(); + virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);} + virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);} + virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);} + virtual ble_error_t disconnect(DisconnectionReason_t reason); + virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason); + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params); + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); + + virtual ble_error_t setDeviceName(const uint8_t *deviceName); + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); + virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance); + virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP); + + virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode); + virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode); + virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const; + virtual ScanningPolicyMode_t getScanningPolicyMode(void) const; + + virtual ble_error_t setTxPower(int8_t txPower); + virtual void getPermittedTxPowerValues(const int8_t **, size_t *); + + virtual ble_error_t connect(const Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams); + + virtual ble_error_t reset(void); + + void Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI); + ble_error_t createConnection(void); + + void setConnectionHandle(uint16_t con_handle); + uint16_t getConnectionHandle(void); + + bool getIsSetAddress(); + + // ADV timeout handling + Timeout& getAdvTimeout(void) { + return advTimeout; + } + uint8_t getAdvToFlag(void) { + return AdvToFlag; + } + void setAdvToFlag(void); + + // SCAN timeout handling + Timeout& getScanTimeout(void) { + return scanTimeout; + } + uint8_t getScanToFlag(void) { + return ScanToFlag; + } + void setScanToFlag(void); + + void Process(void); + + GapScanningParams* getScanningParams(void); + + virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams); + + void setConnectionInterval(uint16_t interval); + Gap::Role_t getGapRole(void); + void setGapRole(Gap::Role_t role); + +private: + uint16_t m_connectionHandle; + Role_t gapRole; + AddressType_t addr_type; + Address_t _peerAddr; + AddressType_t _peerAddrType; + uint8_t bdaddr[BDADDR_SIZE]; + bool _scanning; + bool _connecting; + bool isSetAddress; + uint8_t deviceAppearance[2]; + + // ADV timeout handling + Timeout advTimeout; + bool AdvToFlag; + + // SCAN timeout handling + Timeout scanTimeout; + bool ScanToFlag; + + static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) { + return (duration * 625) / 1000; + } + + uint16_t scanInterval; + uint16_t scanWindow; + uint16_t advInterval; + uint16_t slaveConnIntervMin; + uint16_t slaveConnIntervMax; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + void setAdvParameters(void); + void setConnectionParameters(void); + + Gap::AdvertisingPolicyMode_t advertisingPolicyMode; + Gap::ScanningPolicyMode_t scanningPolicyMode; + + Whitelist_t whitelistAddresses; + + ble_error_t updateAdvertisingData(void); + + BlueNRGGap() : AdvToFlag(false), ScanToFlag(false) { + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + addr_type = BLEProtocol::AddressType::RANDOM_STATIC; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + isSetAddress = false; + memset(deviceAppearance, 0, sizeof(deviceAppearance)); + } + + BlueNRGGap(BlueNRGGap const &); + void operator=(BlueNRGGap const &); + + GapAdvertisingData _advData; + GapAdvertisingData _scanResponse; +}; + +#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,157 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattClient.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CLIENT_H__ +#define __BLUENRG_GATT_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattConnectionClient.h" + +using namespace std; + +#define MAX_ACTIVE_CONNECTIONS 7 + +class BlueNRGGattClient : public GattClient +{ +public: + static BlueNRGGattClient &getInstance() { + static BlueNRGGattClient m_instance; + return m_instance; + } + + ble_error_t createGattConnectionClient(Gap::Handle_t connectionHandle); + ble_error_t removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason); + + /* Functions that must be implemented from GattClient */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + virtual bool isServiceDiscoveryActive(void) const; + virtual void terminateServiceDiscovery(void); + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback); + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + virtual ble_error_t write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + virtual ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + virtual ble_error_t reset(void); + + void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code); + + void primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(Gap::Handle_t connectionHandle); + + void serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length); + + +protected: + + BlueNRGGattClient(): _connectionPool() {}; + + ServiceDiscovery::TerminationCallback_t terminationCallback; + +private: + + BlueNRGGattClient(BlueNRGGattClient const &); + void operator=(BlueNRGGattClient const &); + + BlueNRGGattConnectionClient *_connectionPool[MAX_ACTIVE_CONNECTIONS]; + uint8_t _numConnections; + + BlueNRGGattConnectionClient * getGattConnectionClient(Gap::Handle_t connectionHandle); + +}; + +#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,185 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattConnectionClient.cpp + * @author STMicroelectronics + * @brief Header file for BlueNRGGattConnectionClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CONNECTION_CLIENT_H__ +#define __BLUENRG_GATT_CONNECTION_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" + +using namespace std; + +#define BLE_TOTAL_DISCOVERED_SERVICES 10 +#define BLE_TOTAL_DISCOVERED_CHARS 10 + +class BlueNRGGattConnectionClient +{ +public: + + enum { + GATT_IDLE, + GATT_SERVICE_DISCOVERY, + GATT_CHAR_DESC_DISCOVERY, + //GATT_CHARS_DISCOVERY_COMPLETE, + //GATT_DISCOVERY_TERMINATED, + GATT_READ_CHAR, + GATT_WRITE_CHAR + }; + + /* Functions that must be implemented from GattClient */ + ble_error_t launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + bool isServiceDiscoveryActive(void) const; + void terminateServiceDiscovery(void); + void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + } + ble_error_t read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + ble_error_t write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + ble_error_t reset(void); + + void gattProcedureCompleteCB(uint8_t error_code); + + void primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(void); + + void serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(uint8_t event_data_length); + +protected: + + BlueNRGGattConnectionClient(BlueNRGGattClient *gattClient, Gap::Handle_t connectionHandle): + discoveredService(), + discoveredChar(), + readCBParams(), + writeCBParams(), + _characteristic() { + + //PRINTF("BlueNRGGattConnectionClient construtor: connHandle=%d\n\r", connectionHandle); + + _gattClient = gattClient; + _connectionHandle = connectionHandle; + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + } + + ServiceDiscovery::ServiceCallback_t serviceDiscoveryCallback; + ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback; + ServiceDiscovery::TerminationCallback_t terminationCallback; + CharacteristicDescriptorDiscovery::DiscoveryCallback_t charDescDiscoveryCallback; + CharacteristicDescriptorDiscovery::TerminationCallback_t charDescTerminationCallback; + +private: + + BlueNRGGattConnectionClient(BlueNRGGattConnectionClient const &); + void operator=(BlueNRGGattConnectionClient const &); + ~BlueNRGGattConnectionClient() {}; + + BlueNRGGattClient *_gattClient; + + Gap::Handle_t _connectionHandle; + DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES]; + BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS]; + + GattReadCallbackParams readCBParams; + GattWriteCallbackParams writeCBParams; + + // The char for which the descriptor discovery has been launched + DiscoveredCharacteristic _characteristic; + + UUID _matchingServiceUUID; + UUID _matchingCharacteristicUUIDIn; + uint8_t _currentState; + uint8_t _numServices, _servIndex; + uint8_t _numChars; + uint8_t _numCharDesc; + + friend class BlueNRGGattClient; +}; + +#endif /* __BLUENRG_GATT_CONNECTION_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_SERVER_H__ +#define __BLUENRG_GATT_SERVER_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattService.h" +#include "ble/GattServer.h" +#include <vector> +#include <map> + +#define BLE_TOTAL_CHARACTERISTICS 10 + +using namespace std; + +class BlueNRGGattServer : public GattServer +{ +public: + static BlueNRGGattServer &getInstance() { + static BlueNRGGattServer m_instance; + return m_instance; + } + + enum HandleEnum_t { + CHAR_HANDLE = 0, + CHAR_VALUE_HANDLE, + CHAR_DESC_HANDLE + }; + + /* Functions that must be implemented from GattServer */ + virtual ble_error_t addService(GattService &); + virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t initializeGATTDatabase(void); + + virtual bool isOnDataReadAvailable() const { + return true; + } + + virtual ble_error_t reset(void); + + /* BlueNRG Functions */ + void eventCallback(void); + //void hwCallback(void *pckt); + ble_error_t Read_Request_CB(uint16_t attributeHandle); + uint8_t Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, + uint8_t data_length, const uint8_t* data + ); + GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle); + void HCIDataWrittenEvent(const GattWriteCallbackParams *params); + void HCIDataReadEvent(const GattReadCallbackParams *params); + void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle); + void HCIDataSentEvent(unsigned count); + +private: + + // compute the number of attribute record needed by a service + static uint16_t computeAttributesRecord(GattService& service); + + + static const int MAX_SERVICE_COUNT = 10; + uint8_t serviceCount; + uint8_t characteristicCount; + uint16_t servHandle, charHandle; + + std::map<uint16_t, uint16_t> bleCharHandleMap; // 1st argument is characteristic, 2nd argument is service + GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS]; + uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS]; + + BlueNRGGattServer() { + serviceCount = 0; + characteristicCount = 0; + }; + + BlueNRGGattServer(BlueNRGGattServer const &); + void operator=(BlueNRGGattServer const &); + + static const int CHAR_DESC_TYPE_16_BIT=0x01; + static const int CHAR_DESC_TYPE_128_BIT=0x02; + static const int CHAR_DESC_SECURITY_PERMISSION=0x00; + static const int CHAR_DESC_ACCESS_PERMISSION=0x03; + static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_CLOCK_H__ +#define __BLE_CLOCK_H__ + +#include <ble_hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __BLE_CLOCK_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file ble_debug.h + * @author CL + * @version V1.0.0 + * @date 04-July-2014 + * @brief This file defines print functions for debug purposes. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLE_DEBUG_H +#define __BLE_DEBUG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> + +/* Exported macro ------------------------------------------------------------*/ +//#define DEBUG +#ifdef DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Print the data travelling over the SPI in the .csv format for the GUI*/ +//#define PRINT_CSV_FORMAT +#ifdef PRINT_CSV_FORMAT +#include <stdio.h> +#define PRINT_CSV(...) printf(__VA_ARGS__) +#else +#define PRINT_CSV(...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __BLE_DEBUG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_gp_timer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : General purpose timer library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_GP_TIMER_H__ +#define __BLE_GP_TIMER_H__ + +#include "ble_clock.h" +#include "ble_status.h" +#ifdef __DMA_LP__ +#include "stm32xx_timerserver.h" +#endif /* __DMA_LP__ */ + +/** + * timer + * + * A structure that represents a timer. Use Timer_Set() to set the timer. + * + */ +struct timer { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + tClockTime start; + tClockTime interval; + +#endif +}; + +typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); + +/** + * Timer_Set + * + * @param[in] t Pointer to a timer structure + * @param[in] interval timeout value + * + * This function sets the timeout value of a timer. + * + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * Timer_Reset + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the time it previously expired. + * + */ +void Timer_Reset(struct timer *t); + +/** + * Timer_Restart + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the current time. + * + */ +void Timer_Restart(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns TRUE if timer is expired, FALSE otherwise. + * + */ +int Timer_Expired(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns the time needed for expiration. + * + * @return Time before timer's expiration. + */ +tClockTime Timer_Remaining(struct timer *t); + +#ifdef __DMA_LP__ +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID); + +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); +#endif /* __DMA_LP__ */ + +#endif /* __BLE_GP_TIMER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,108 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_H__ +#define __BLE_HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void signalEventsToProcess(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __BLE_HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_TYPES_H__ +#define __BLE_HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __BLE_HAL_TYPES_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,126 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.0, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_H_ +#define __BLE_HCI_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ble_hal_types.h" +#include "ble_link_layer.h" +#include <ble_list.h> + +#define HCI_READ_PACKET_SIZE 128 //71 + +/** + * Maximum payload of HCI commands that can be sent. Change this value if needed. + * This value can be up to 255. + */ +#define HCI_MAX_PAYLOAD_SIZE 128 + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_READ_PACKET_SIZE]; + uint8_t data_len; +} tHciDataPacket; + +struct hci_request { + uint16_t ogf; + uint16_t ocf; + int event; + void *cparam; + int clen; + void *rparam; + int rlen; +}; + +typedef enum +{ + BUSY, + AVAILABLE +} HCI_CMD_STATUS_t; + + +/** + * This function must be used to pass the packet received from the HCI + * interface to the BLE Stack HCI state machine. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * + */ +void HCI_Input(tHciDataPacket *hciReadPacket); + +/** + * Initialization function. Must be done before any data can be received from + * BLE controller. + */ +void HCI_Init(void); + +/** + * Callback used to pass events to application. + * + * @param[in] pckt The event. + * + */ +extern void HCI_Event_CB(void *pckt); + +/** + * Processing function that must be called after an event is received from + * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if + * necessary. +*/ +void HCI_Process(void); + +/** + * @brief Check if queue of HCI event is empty or not. + * @note This funtion can be used to check if the event queue from BlueNRG is empty. This + * is useful when checking if it is safe to go to sleep. + * @return TRUE if event queue is empty. FALSE otherwhise. + */ +BOOL HCI_Queue_Empty(void); +/** + * Iterrupt service routine that must be called when the BlueNRG + * reports a packet received or an event to the host through the + * BlueNRG interrupt line. + */ +#ifdef __DMA_LP__ +void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); +void HCI_Process_Notification_Request(void); +void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); +void HCI_Wait_For_Response(void); +#else +void HCI_Isr(void); +void HCI_HandleSPI(void); + +int hci_send_req(struct hci_request *r, BOOL async); +#endif /* __DMA_LP__ */ + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#ifdef __cplusplus +} +#endif + + +#endif /* __BLE_HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,548 @@ +/****************************************************************************** +* +* File Description +* --------------------- +* This file defines constants and functions for HCI layer. +* See Bluetooth Core v 4.0, Vol. 2, Part E. +* +*******************************************************************************/ + +#ifndef __HCI_INTERNAL_H_ +#define __HCI_INTERNAL_H_ + +#include "ble_compiler.h" +#include "ble_hal_types.h" +#include "ble_clock.h" +#include "ble_link_layer.h" +#include "ble_hci.h" + +#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) + + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +typedef __packed struct _hci_uart_pckt{ + uint8_t type; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef __packed struct _hci_command_hdr{ + uint16_t opcode; /* OCF & OGF */ + uint8_t plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef __packed struct _hci_event_pckt{ + uint8_t evt; + uint8_t plen; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef __packed struct _hci_acl_hdr{ + uint16_t handle; /* Handle & Flags(PB, BC) */ + uint16_t dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef __packed struct _disconnect_cp{ + uint16_t handle; + uint8_t reason; +} PACKED disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 + +#define OCF_SET_EVENT_MASK 0x0001 +#define OCF_RESET 0x0003 + +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D +typedef __packed struct _read_transmit_power_level_cp{ + uint16_t handle; + uint8_t type; +} PACKED read_transmit_power_level_cp; +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 +typedef __packed struct _read_transmit_power_level_rp{ + uint8_t status; + uint16_t handle; + int8_t level; +} PACKED read_transmit_power_level_rp; +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 + +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 +#define OCF_HOST_BUFFER_SIZE 0x0033 +#define OCF_HOST_NUM_COMP_PKTS 0x0035 + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef __packed struct _read_local_version_rp{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t manufacturer_name; + uint16_t lmp_pal_subversion; +} PACKED read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_COMMANDS 0x0002 +#define OCF_READ_LOCAL_FEATURES 0x0003 + +#define OCF_READ_BD_ADDR 0x0009 +typedef __packed struct _read_bd_addr_rp{ + uint8_t status; + tBDAddr bdaddr; +} PACKED read_bd_addr_rp; +#define READ_BD_ADDR_RP_SIZE 7 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +#define OCF_READ_RSSI 0x0005 +typedef __packed struct _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef __packed struct _read_rssi_rp{ + uint8_t status; + uint16_t handle; + int8_t rssi; +} PACKED read_rssi_rp; +#define READ_RSSI_RP_SIZE 4 + + +/* LE commands */ +#define OGF_LE_CTL 0x08 + +#define OCF_LE_SET_EVENT_MASK 0x0001 +typedef __packed struct _le_set_event_mask_cp{ + uint8_t mask[8]; +} PACKED le_set_event_mask_cp; +#define LE_SET_EVENT_MASK_CP_SIZE 8 + +#define OCF_LE_READ_BUFFER_SIZE 0x0002 +typedef __packed struct _le_read_buffer_size_rp{ + uint8_t status; + uint16_t pkt_len; + uint8_t max_pkt; +} PACKED le_read_buffer_size_rp; +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 + +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 +typedef __packed struct _le_read_local_supported_features_rp{ + uint8_t status; + uint8_t features[8]; +} PACKED le_read_local_supported_features_rp; +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 + +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 +typedef __packed struct _le_set_random_address_cp{ + tBDAddr bdaddr; +} PACKED le_set_random_address_cp; +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 + +#define OCF_LE_SET_ADV_PARAMETERS 0x0006 +typedef __packed struct _le_set_adv_parameters_cp{ + uint16_t min_interval; + uint16_t max_interval; + uint8_t advtype; + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint8_t chan_map; + uint8_t filter; +} PACKED le_set_adv_parameters_cp; +#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 + +#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 +typedef __packed struct _le_read_adv_channel_tx_power_rp{ + uint8_t status; + int8_t level; +} PACKED le_read_adv_channel_tx_power_rp; +#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 + +#define OCF_LE_SET_ADV_DATA 0x0008 +typedef __packed struct _le_set_adv_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_adv_data_cp; +#define LE_SET_ADV_DATA_CP_SIZE 32 + +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 +typedef __packed struct _le_set_scan_response_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_scan_response_data_cp; +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 + +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A +typedef __packed struct _le_set_advertise_enable_cp{ + uint8_t enable; +} PACKED le_set_advertise_enable_cp; +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 + +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B +typedef __packed struct _le_set_scan_parameters_cp{ + uint8_t type; + uint16_t interval; + uint16_t window; + uint8_t own_bdaddr_type; + uint8_t filter; +} PACKED le_set_scan_parameters_cp; +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 + +#define OCF_LE_SET_SCAN_ENABLE 0x000C +typedef __packed struct _le_set_scan_enable_cp{ + uint8_t enable; + uint8_t filter_dup; +} PACKED le_set_scan_enable_cp; +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 + +#define OCF_LE_CREATE_CONN 0x000D +typedef __packed struct _le_create_connection_cp{ + uint16_t interval; + uint16_t window; + uint8_t initiator_filter; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_create_connection_cp; +#define LE_CREATE_CONN_CP_SIZE 25 + +#define OCF_LE_CREATE_CONN_CANCEL 0x000E + +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F +typedef __packed struct _le_read_white_list_size_rp{ + uint8_t status; + uint8_t size; +} PACKED le_read_white_list_size_rp; +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 + +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 +typedef __packed struct _le_add_device_to_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_add_device_to_white_list_cp; +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 +typedef __packed struct _le_remove_device_from_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_remove_device_from_white_list_cp; +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_CONN_UPDATE 0x0013 +typedef __packed struct _le_connection_update_cp{ + uint16_t handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_connection_update_cp; +#define LE_CONN_UPDATE_CP_SIZE 14 + +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 +typedef __packed struct _le_set_host_channel_classification_cp{ + uint8_t map[5]; +} PACKED le_set_host_channel_classification_cp; +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 + +#define OCF_LE_READ_CHANNEL_MAP 0x0015 +typedef __packed struct _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef __packed struct _le_read_channel_map_rp{ + uint8_t status; + uint16_t handle; + uint8_t map[5]; +} PACKED le_read_channel_map_rp; +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 + +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 +typedef __packed struct _le_read_remote_used_features_cp{ + uint16_t handle; +} PACKED le_read_remote_used_features_cp; +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 + +#define OCF_LE_ENCRYPT 0x0017 +typedef __packed struct _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef __packed struct _le_encrypt_rp{ + uint8_t status; + uint8_t encdata[16]; +} PACKED le_encrypt_rp; +#define LE_ENCRYPT_RP_SIZE 17 + +#define OCF_LE_RAND 0x0018 +typedef __packed struct _le_rand_rp{ + uint8_t status; + uint8_t random[8]; +} PACKED le_rand_rp; +#define LE_RAND_RP_SIZE 9 + +#define OCF_LE_START_ENCRYPTION 0x0019 +typedef __packed struct _le_start_encryption_cp{ + uint16_t handle; + uint8_t random[8]; + uint16_t diversifier; + uint8_t key[16]; +} PACKED le_start_encryption_cp; +#define LE_START_ENCRYPTION_CP_SIZE 28 + +#define OCF_LE_LTK_REPLY 0x001A +typedef __packed struct _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef __packed struct _le_ltk_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_reply_rp; +#define LE_LTK_REPLY_RP_SIZE 3 + +#define OCF_LE_LTK_NEG_REPLY 0x001B +typedef __packed struct _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef __packed struct _le_ltk_neg_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_neg_reply_rp; +#define LE_LTK_NEG_REPLY_RP_SIZE 3 + +#define OCF_LE_READ_SUPPORTED_STATES 0x001C +typedef __packed struct _le_read_supported_states_rp{ + uint8_t status; + uint8_t states[8]; +} PACKED le_read_supported_states_rp; +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 + +#define OCF_LE_RECEIVER_TEST 0x001D +typedef __packed struct _le_receiver_test_cp{ + uint8_t frequency; +} PACKED le_receiver_test_cp; +#define LE_RECEIVER_TEST_CP_SIZE 1 + +#define OCF_LE_TRANSMITTER_TEST 0x001E +typedef __packed struct _le_transmitter_test_cp{ + uint8_t frequency; + uint8_t length; + uint8_t payload; +} PACKED le_transmitter_test_cp; +#define LE_TRANSMITTER_TEST_CP_SIZE 3 + +#define OCF_LE_TEST_END 0x001F +typedef __packed struct _le_test_end_rp{ + uint8_t status; + uint16_t num_pkts; +} PACKED le_test_end_rp; +#define LE_TEST_END_RP_SIZE 3 + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3f + + +/*------------- Events -------------*/ +#define EVT_CONN_COMPLETE 0x03 +typedef __packed struct _evt_conn_complete{ + uint8_t status; + uint16_t handle; + tBDAddr bdaddr; + uint8_t link_type; + uint8_t encr_mode; +} PACKED evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef __packed struct _evt_disconn_complete{ + uint8_t status; + uint16_t handle; + uint8_t reason; +} PACKED evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef __packed struct _evt_encrypt_change{ + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} PACKED evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C + +#define EVT_CMD_COMPLETE 0x0E +typedef __packed struct _evt_cmd_complete{ + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef __packed struct _evt_cmd_status{ + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef __packed struct _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef __packed struct _evt_num_comp_pkts{ + uint8_t num_hndl; + /* variable length part */ +} PACKED evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +/* variable length part of evt_num_comp_pkts. */ +typedef __packed struct _evt_num_comp_pkts_param{ + uint16_t hndl; + uint16_t num_comp_pkts; +} PACKED evt_num_comp_pkts_param; +#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 + +#define EVT_DATA_BUFFER_OVERFLOW 0x1A +typedef __packed struct _evt_data_buffer_overflow{ + uint8_t link_type; +} PACKED evt_data_buffer_overflow; +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 + +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef __packed struct _evt_encryption_key_refresh_complete{ + uint8_t status; + uint16_t handle; +} PACKED evt_encryption_key_refresh_complete; +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 + +#define EVT_LE_META_EVENT 0x3E +typedef __packed struct _evt_le_meta_event{ + uint8_t subevent; + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef __packed struct _evt_le_connection_complete{ + uint8_t status; + uint16_t handle; + uint8_t role; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; +} PACKED evt_le_connection_complete; +#define EVT_LE_CONN_COMPLETE_SIZE 18 + +#define EVT_LE_ADVERTISING_REPORT 0x02 +typedef __packed struct _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t data_length; + uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef __packed struct _evt_le_connection_update_complete{ + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; +} PACKED evt_le_connection_update_complete; +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 + +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +typedef __packed struct _evt_le_read_remote_used_features_complete{ + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} PACKED evt_le_read_remote_used_features_complete; +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 + +#define EVT_LE_LTK_REQUEST 0x05 +typedef __packed struct _evt_le_long_term_key_request{ + uint16_t handle; + uint8_t random[8]; + uint16_t ediv; +} PACKED evt_le_long_term_key_request; +#define EVT_LE_LTK_REQUEST_SIZE 12 + +/** +* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, +* application can use @ref evt_blue_aci structure to parse the packet. +*/ +#define EVT_VENDOR 0xFF + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + + + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); + +typedef enum { + WAITING_TYPE, + WAITING_OPCODE1, + WAITING_OPCODE2, + WAITING_EVENT_CODE, + WAITING_HANDLE, + WAITING_HANDLE_FLAG, + WAITING_PARAM_LEN, + WAITING_DATA_LEN1, + WAITING_DATA_LEN2, + WAITING_PAYLOAD +}hci_state; + +typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); + +/* HCI library functions. */ + +int hci_send_req(struct hci_request *r, BOOL async); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,170 @@ +/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +* File Name : ble_hci_le.h +* Author : AMG RF FW team +* Version : V1.1.0 +* Date : 18-July-2016 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.1, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_LE_H_ +#define __BLE_HCI_LE_H_ + +#include "ble_hal_types.h" +#include "ble_link_layer.h" + +/** + * @defgroup HCI_Error_codes HCI Error codes + * @{ + */ +#define HCI_UNKNOWN_COMMAND 0x01 +#define HCI_NO_CONNECTION 0x02 +#define HCI_HARDWARE_FAILURE 0x03 +#define HCI_PAGE_TIMEOUT 0x04 +#define HCI_AUTHENTICATION_FAILURE 0x05 +#define HCI_PIN_OR_KEY_MISSING 0x06 +#define HCI_MEMORY_FULL 0x07 +#define HCI_CONNECTION_TIMEOUT 0x08 +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a +#define HCI_ACL_CONNECTION_EXISTS 0x0b +#define HCI_COMMAND_DISALLOWED 0x0c +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d +#define HCI_REJECTED_SECURITY 0x0e +#define HCI_REJECTED_PERSONAL 0x0f +#define HCI_HOST_TIMEOUT 0x10 +#define HCI_UNSUPPORTED_FEATURE 0x11 +#define HCI_INVALID_PARAMETERS 0x12 +#define HCI_OE_USER_ENDED_CONNECTION 0x13 +#define HCI_OE_LOW_RESOURCES 0x14 +#define HCI_OE_POWER_OFF 0x15 +#define HCI_CONNECTION_TERMINATED 0x16 +#define HCI_REPEATED_ATTEMPTS 0x17 +#define HCI_PAIRING_NOT_ALLOWED 0x18 +#define HCI_UNKNOWN_LMP_PDU 0x19 +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a +#define HCI_SCO_OFFSET_REJECTED 0x1b +#define HCI_SCO_INTERVAL_REJECTED 0x1c +#define HCI_AIR_MODE_REJECTED 0x1d +#define HCI_INVALID_LMP_PARAMETERS 0x1e +#define HCI_UNSPECIFIED_ERROR 0x1f +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 +#define HCI_UNIT_LINK_KEY_USED 0x26 +#define HCI_QOS_NOT_SUPPORTED 0x27 +#define HCI_INSTANT_PASSED 0x28 +#define HCI_PAIRING_NOT_SUPPORTED 0x29 +#define HCI_TRANSACTION_COLLISION 0x2a +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c +#define HCI_QOS_REJECTED 0x2d +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e +#define HCI_INSUFFICIENT_SECURITY 0x2f +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 +#define HCI_ROLE_SWITCH_PENDING 0x32 +#define HCI_SLOT_VIOLATION 0x34 +#define HCI_ROLE_SWITCH_FAILED 0x35 +#define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 +#define HCI_CONN_REJ_NO_CH_FOUND 0x39 +#define HCI_CONTROLLER_BUSY 0x3A +#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B +#define HCI_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_CONN_TERM_MIC_FAIL 0x3D +#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E +#define HCI_MAC_CONN_FAILED 0x3F +/** + * @} + */ + + +/* + * HCI library functions. + * Each function returns 0 in case of success, otherwise one of the error codes. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(uint8_t enable); + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter); + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter); + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); + +int hci_le_rand(uint8_t random_number[8]); + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); + +int hci_acl_data(const uint8_t * data, uint16_t len); + +int hci_le_set_random_address(tBDAddr bdaddr); + +int hci_read_bd_addr(tBDAddr bdaddr); + +int hci_le_read_white_list_size(uint8_t *size); + +int hci_le_clear_white_list(); + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); + +int hci_le_ltk_request_reply(uint8_t key[16]); + +int hci_le_ltk_request_neg_reply(); + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); + +int hci_le_create_connection_cancel(void); + +int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level); + +int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi); + +int hci_le_read_local_supported_features(uint8_t *features); + +int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); + +int hci_le_read_supported_states(uint8_t states[8]); + +int hci_le_receiver_test(uint8_t frequency); + +int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); + +int hci_le_test_end(uint16_t *num_pkts); + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion); + + + +#endif /* __BLE_HCI_LE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,161 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_link_layer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's link layer. It contains +* definition of functions for link layer, most of which are +* mapped to HCI commands. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef _BLE_LINK_LAYER_H +#define _BLE_LINK_LAYER_H + +#include <ble_status.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + *@name Advertising filter + *Advertising policy for filtering (white list related) + *@{ + */ +#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ +#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ +/** + * @} + */ + + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef uint8_t tBDAddr[6]; + + +/** + *@name Bluetooth address types + * Bluetooth address types + *@{ + */ +#define PUBLIC_ADDR (0) +#define RANDOM_ADDR (1) +#define STATIC_RANDOM_ADDR (1) +#define RESOLVABLE_PRIVATE_ADDR (2) +#define NON_RESOLVABLE_PRIVATE_ADDR (3) +/** + * @} + */ + +/** + *@name Directed advertising types + * Type of advertising during directed advertising + *@{ + */ +#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) +#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) +/** + * @} + */ + +/** + * @name Advertising type + * @{ + */ + +/** + * undirected scannable and connectable + */ +#define ADV_IND (0x00) + +/** + * directed non scannable + */ +#define ADV_DIRECT_IND (0x01) + +/** + * scannable non connectable + */ +#define ADV_SCAN_IND (0x02) + +/** + * non-connectable and no scan response + */ +#define ADV_NONCONN_IND (0x03) + +/** + * scan response + */ +#define SCAN_RSP (0x04) + +/** + * @} + */ + +/* 0X05-0XFF RESERVED */ + +/** + * @name Advertising ranges + * @{ + */ + +/** + * lowest allowed interval value for connectable types(20ms)..multiple of 625us + */ +#define ADV_INTERVAL_LOWEST_CONN (0X0020) + +/** + * highest allowed interval value (10.24s)..multiple of 625us. + */ +#define ADV_INTERVAL_HIGHEST (0X4000) + +/** + * lowest allowed interval value for non connectable types + * (100ms)..multiple of 625us. + */ +#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) + +/** + * @} + */ + +/** + * @name Advertising channels + * @{ + */ +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 +/** + * @} + */ + +/** + * @name Scan_types Scan types + * @{ + */ +#define PASSIVE_SCAN 0 +#define ACTIVE_SCAN 1 +/** + * @} + */ + +/** + * @} + */ + + +#endif /* _BLE_LINK_LAYER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,47 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for linked list library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef _BLE_LIST_H_ +#define _BLE_LIST_H_ + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +uint8_t list_is_empty (tListNode * listHead); + +void list_insert_head (tListNode * listHead, tListNode * node); + +void list_insert_tail (tListNode * listHead, tListNode * node); + +void list_remove_node (tListNode * node); + +void list_remove_head (tListNode * listHead, tListNode ** node ); + +void list_remove_tail (tListNode * listHead, tListNode ** node ); + +void list_insert_node_after (tListNode * node, tListNode * ref_node); + +void list_insert_node_before (tListNode * node, tListNode * ref_node); + +int list_get_size (tListNode * listHead); + +void list_get_next_node (tListNode * ref_node, tListNode ** node); + +void list_get_prev_node (tListNode * ref_node, tListNode ** node); + +#endif /* _BLE_LIST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_OSAL_H__ +#define __BLE_OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __BLE_OSAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,158 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_sm.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's security manager. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_SM_H__ +#define __BLE_SM_H__ + +/****************************************************************************** +* Macros +*****************************************************************************/ + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/* IO capabilities */ +/** + * @anchor IO_capabilities + * @name IO capabilities + * @{ + */ +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define IO_CAP_KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) +/** + * @} + */ + +/** + * @anchor Auth_req + * @name Authentication requirements + * @{ + */ +#define BONDING (0x01) +#define NO_BONDING (0x00) +/** + * @} + */ + +/** + * @anchor MITM_req + * @name MITM protection requirements + * @{ + */ +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor OOB_Data + * @name Out-Of-Band data + * @{ + */ +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) +/** + * @} + */ + +/** + * @anchor Author_req + * @name Authorization requirements + * @{ + */ +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor Conn_authorization + * @name Connection authorization + * @{ + */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) +/** + * @} + */ + +/** + * @anchor Use_fixed_pin + * @name Use fixed pin + * @{ + */ +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +/** + * @} + */ + +/** + * @anchor link_security_status + * @name Link security status + * @{ + */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) +/** + * @} + */ + +/** + * @anchor SMP_pairing_failed_codes + * @name SMP pairing failed reason codes + * @{ + */ +#define PASSKEY_ENTRY_FAILED (0x01) +#define OOB_NOT_AVAILABLE (0x02) +#define AUTH_REQ_CANNOT_BE_MET (0x03) +#define CONFIRM_VALUE_FAILED (0x04) +#define PAIRING_NOT_SUPPORTED (0x05) +#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) +#define CMD_NOT_SUPPORTED (0x07) +#define UNSPECIFIED_REASON (0x08) +#define VERY_EARLY_NEXT_ATTEMPT (0x09) +#define SM_INVALID_PARAMS (0x0A) +/** + * @} + */ + +/** + * @anchor pairing_failed_codes + * @name Pairing failed error codes + * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event + * @{ + */ +#define SM_PAIRING_SUCCESS (0x00) +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,188 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_status.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file with BLE Stack status codes. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_STATUS_H__ +#define __BLE_STATUS_H__ + +#include <ble_hal_types.h> + +/** @addtogroup Middlewares + * @{ + */ + +/** @defgroup ST + * @{ + */ + +/** @defgroup SimpleBlueNRG_HCI + * @{ + */ + +/** @defgroup ble_status Bluetooth Status/Error Codes + * @{ + */ + +typedef uint8_t tBleStatus; + +/* Error Codes as specified by the specification + * according to the spec the error codes range + * from 0x00 to 0x3F + */ +/** + * @name Standard error codes + * @brief Standard error codes. See Core v 4.1, Vol. 2, part D. + * @{ + */ +#define ERR_CMD_SUCCESS (0x00) +#define BLE_STATUS_SUCCESS (0x00) +#define ERR_UNKNOWN_HCI_COMMAND (0x01) +#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) + +#define ERR_AUTH_FAILURE (0x05) +#define ERR_PIN_OR_KEY_MISSING (0x06) +#define ERR_MEM_CAPACITY_EXCEEDED (0x07) +#define ERR_CONNECTION_TIMEOUT (0x08) + +#define ERR_COMMAND_DISALLOWED (0x0C) + +#define ERR_UNSUPPORTED_FEATURE (0x11) +#define ERR_INVALID_HCI_CMD_PARAMS (0x12) +#define ERR_RMT_USR_TERM_CONN (0x13) +#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) +#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) +#define ERR_LOCAL_HOST_TERM_CONN (0x16) + +#define ERR_UNSUPP_RMT_FEATURE (0x1A) + +#define ERR_INVALID_LMP_PARAM (0x1E) +#define ERR_UNSPECIFIED_ERROR (0x1F) + +#define ERR_LL_RESP_TIMEOUT (0x22) +#define ERR_LMP_PDU_NOT_ALLOWED (0x24) + +#define ERR_INSTANT_PASSED (0x28) + +#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) +#define ERR_CONTROLLER_BUSY (0x3A) + +#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) + +#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) + +#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) + + +/** + * @} + */ +/** + * @name Vendor-specific error codes + * @brief Error codes defined by ST related to BlueNRG stack + * @{ + */ +/** + * The command cannot be executed due to the current state of the device. + */ +#define BLE_STATUS_FAILED (0x41) +/** + * Some parameters are invalid. + */ +#define BLE_STATUS_INVALID_PARAMS (0x42) +/** + * It is not allowed to start the procedure (e.g. another the procedure is ongoing + * or cannot be started on the given handle). + */ +#define BLE_STATUS_NOT_ALLOWED (0x46) +/** + * Unexpected error. + */ +#define BLE_STATUS_ERROR (0x47) +#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) + +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +#define BLE_STATUS_INVALID_CID (0x50) + +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) +#define BLE_STATUS_IRK_NOT_FOUND (0x5B) +#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) +#define BLE_STATUS_SEC_DB_FULL (0x5D) +#define BLE_STATUS_DEV_NOT_BONDED (0x5E) +#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) + +#define BLE_STATUS_INVALID_HANDLE (0x60) +#define BLE_STATUS_INVALID_PARAMETER (0x61) +#define BLE_STATUS_OUT_OF_HANDLE (0x62) +#define BLE_STATUS_INVALID_OPERATION (0x63) +#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) +#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) +#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) + +/** + * Returned when no valid slots are available (e.g. when there are no available state machines). + */ +#define BLE_STATUS_NO_VALID_SLOT (0x82) + +/** + * Returned when a scan window shorter than minimum allowed value has been requested (i.e. 2ms) + */ + +#define BLE_STATUS_SCAN_WINDOW_SHORT (0x83) +/** + * Returned when the maximum requested interval to be allocated is shorter then the current + * anchor period and a there is no submultiple for the current anchor period that is between + * the minimum and the maximum requested intervals. + */ + +#define BLE_STATUS_NEW_INTERVAL_FAILED (0x84) +/** + * Returned when the maximum requested interval to be allocated is greater than the current anchor + * period and there is no multiple of the anchor period that is between the minimum and the maximum + * requested intervals. + */ + +#define BLE_STATUS_INTERVAL_TOO_LARGE (0x85) +/** + * Returned when the current anchor period or a new one can be found that is compatible to the + * interval range requested by the new slot but the maximum available length that can be allocated is + * less than the minimum requested slot length. + */ + +#define BLE_STATUS_LENGTH_FAILED (0x86) +/** + * @} + */ + +/** + * @name Library Error Codes + * @brief Error codes defined by ST related to MCU library. + * @{ + */ +#define BLE_STATUS_TIMEOUT (0xFF) +#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) +#define BLE_STATUS_NULL_PARAM (0xF1) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,813 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci_const.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with ACI definitions for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_CONST_H_ +#define __BLUENRG_ACI_CONST_H_ + +#include "ble_compiler.h" +#include "ble_link_layer.h" +#include "ble_hci_const.h" +#include "bluenrg_gatt_server.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define OCF_HAL_GET_FW_BUILD_NUMBER 0x0000 +typedef __packed struct _hal_get_fw_build_number_rp{ + uint8_t status; + uint16_t build_number; +} PACKED hal_get_fw_build_number_rp; +#define HAL_GET_FW_BUILD_NUMBER_RP_SIZE 3 +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +#define OCF_HAL_READ_CONFIG_DATA 0x000D +typedef __packed struct _hal_read_config_data_cp{ + uint8_t offset; +} PACKED hal_read_config_data_cp; +#define HAL_READ_CONFIG_DATA_RP_SIZE 1 +typedef __packed struct _hal_read_config_data_rp{ + uint8_t status; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE]; +} PACKED hal_read_config_data_rp; + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef __packed struct _hal_set_tx_power_level_cp{ + uint8_t en_high_power; + uint8_t pa_level; +} PACKED hal_set_tx_power_level_cp; +#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 + +#define OCF_HAL_DEVICE_STANDBY 0x0013 + +#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014 +typedef __packed struct _hal_le_tx_test_packet_number_rp{ + uint8_t status; + uint32_t number_of_packets; +} PACKED hal_le_tx_test_packet_number_rp; + +#define OCF_HAL_TONE_START 0x0015 +typedef __packed struct _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_HAL_TONE_STOP 0x0016 +#define OCF_HAL_GET_LINK_STATUS 0x0017 +typedef __packed struct _hal_get_link_status_rp{ + uint8_t status; + uint8_t link_status[8]; + uint16_t conn_handle[8]; +} PACKED hal_get_link_status_rp; + +#define OCF_HAL_GET_ANCHOR_PERIOD 0x0019 +typedef __packed struct _hal_get_anchor_period_rp{ + uint8_t status; + uint32_t anchor_period; + uint32_t max_free_slot; +} PACKED hal_get_anchor_period_rp; + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef __packed struct _get_updater_version_rp{ + uint8_t status; + uint8_t version; +} PACKED get_updater_version_rp; +#define GET_UPDATER_VERSION_RP_SIZE 2 + +#define OCF_GET_UPDATER_BUFSIZE 0x0023 +typedef __packed struct _get_updater_bufsize_rp{ + uint8_t status; + uint8_t buffer_size; +} PACKED get_updater_bufsize_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 + +#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 + +#define OCF_UPDATER_ERASE_SECTOR 0x0026 +typedef __packed struct _updater_erase_sector_cp{ + uint32_t address; +} PACKED updater_erase_sector_cp; +#define UPDATER_ERASE_SECTOR_CP_SIZE 4 + +#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 +#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_prog_data_block_cp{ + uint32_t address; + uint16_t data_len; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; +} PACKED updater_prog_data_block_cp; + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef __packed struct _updater_read_data_block_cp{ + uint32_t address; + uint16_t data_len; +} PACKED updater_read_data_block_cp; +#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[VARIABLE_SIZE]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef __packed struct _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef __packed struct _updater_calc_crc_rp{ + uint8_t status; + uint32_t crc; +} PACKED updater_calc_crc_rp; +#define UPDATER_CALC_CRC_RP_SIZE 5 + +#define OCF_UPDATER_HW_VERSION 0x002A +typedef __packed struct _updater_hw_version_rp{ + uint8_t status; + uint8_t version; +} PACKED updater_hw_version_rp; +#define UPDATER_HW_VERSION_RP_SIZE 2 + +#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 + +#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 + +#define OCF_GAP_SET_DISCOVERABLE 0x0083 + +#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 +typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ + uint8_t own_bdaddr_type; + uint8_t directed_adv_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint16_t adv_interv_min; + uint16_t adv_interv_max; +} PACKED gap_set_direct_conectable_cp_IDB05A1; + +typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB04A1; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef __packed struct _gap_set_io_capability_cp{ + uint8_t io_capability; +} PACKED gap_set_io_capability_cp; +#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 + +#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 +typedef __packed struct _gap_set_auth_requirement_cp{ + uint8_t mitm_mode; + uint8_t oob_enable; + uint8_t oob_data[16]; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t bonding_mode; +} PACKED gap_set_auth_requirement_cp; +#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 + +#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 +typedef __packed struct _gap_set_author_requirement_cp{ + uint16_t conn_handle; + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef __packed struct _gap_passkey_response_cp{ + uint16_t conn_handle; + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef __packed struct _gap_authorization_response_cp{ + uint16_t conn_handle; + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 + +#define OCF_GAP_INIT 0x008A +typedef __packed struct _gap_init_cp_IDB05A1{ + uint8_t role; + uint8_t privacy_enabled; + uint8_t device_name_char_len; +} PACKED gap_init_cp_IDB05A1; +#define GAP_INIT_CP_SIZE_IDB05A1 3 + +typedef __packed struct _gap_init_cp_IDB04A1{ + uint8_t role; +} PACKED gap_init_cp_IDB04A1; +#define GAP_INIT_CP_SIZE_IDB04A1 1 +typedef __packed struct _gap_init_rp{ + uint8_t status; + uint16_t service_handle; + uint16_t dev_name_char_handle; + uint16_t appearance_char_handle; +} PACKED gap_init_rp; +#define GAP_INIT_RP_SIZE 7 + +#define OCF_GAP_SET_NON_CONNECTABLE 0x008B +typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ + uint8_t advertising_event_type; + uint8_t own_address_type; +#endif +} PACKED gap_set_non_connectable_cp_IDB05A1; + +typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp_IDB04A1; + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef __packed struct _gap_set_undirected_connectable_cp{ + uint8_t adv_filter_policy; + uint8_t own_addr_type; +} PACKED gap_set_undirected_connectable_cp; +#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 + +#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D +typedef __packed struct _gap_slave_security_request_cp{ + uint16_t conn_handle; + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef __packed struct _gap_delete_ad_type_cp{ + uint8_t ad_type; +} PACKED gap_delete_ad_type_cp; +#define GAP_DELETE_AD_TYPE_CP_SIZE 1 + +#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 +typedef __packed struct _gap_get_security_level_rp{ + uint8_t status; + uint8_t mitm_protection; + uint8_t bonding; + uint8_t oob_data; + uint8_t passkey_required; +} PACKED gap_get_security_level_rp; +#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 + +#define OCF_GAP_SET_EVT_MASK 0x0091 +typedef __packed struct _gap_set_evt_mask_cp{ + uint16_t evt_mask; +} PACKED gap_set_evt_mask_cp; +#define GAP_SET_EVT_MASK_CP_SIZE 2 + +#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 + +#define OCF_GAP_TERMINATE 0x0093 +typedef __packed struct _gap_terminate_cp{ + uint16_t handle; + uint8_t reason; +} PACKED gap_terminate_cp; +#define GAP_TERMINATE_CP_SIZE 3 + +#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 + +#define OCF_GAP_ALLOW_REBOND_DB 0x0095 + +typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ + uint16_t conn_handle; +} PACKED gap_allow_rebond_cp_IDB05A1; + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef __packed struct _gap_start_limited_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_limited_discovery_proc_cp; +#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 +typedef __packed struct _gap_start_general_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_general_discovery_proc_cp; +#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 +typedef __packed struct _gap_start_name_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_name_discovery_proc_cp; +#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 + +#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 + +#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; + +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t use_reconn_addr; + tBDAddr reconn_addr; +} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; + +#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B +#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 +typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t num_whitelist_entries; + uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; +} PACKED gap_start_selective_conn_establish_proc_cp; + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef __packed struct _gap_create_connection_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_create_connection_cp; +#define GAP_CREATE_CONNECTION_CP_SIZE 24 + +#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D + +#define OCF_GAP_START_CONNECTION_UPDATE 0x009E +typedef __packed struct _gap_start_connection_update_cp{ + uint16_t conn_handle; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_connection_update_cp; +#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 + +#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F +typedef __packed struct _gap_send_pairing_request_cp{ + uint16_t conn_handle; + uint8_t force_rebond; +} PACKED gap_send_pairing_request_cp; +#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 + +#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 +typedef __packed struct _gap_resolve_private_address_cp{ + tBDAddr address; +} PACKED gap_resolve_private_address_cp; +#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 +typedef __packed struct _gap_resolve_private_address_rp{ + uint8_t status; + tBDAddr address; +} PACKED gap_resolve_private_address_rp; + +#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 +#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 +typedef __packed struct _gap_set_broadcast_mode_cp{ + uint16_t adv_interv_min; + uint16_t adv_interv_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; +} PACKED gap_set_broadcast_mode_cp; + +#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 +typedef __packed struct _gap_start_observation_proc_cp{ + uint16_t scan_interval; + uint16_t scan_window; + uint8_t scan_type; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_observation_proc_cp; + +#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 +typedef __packed struct _gap_get_bonded_devices_rp{ + uint8_t status; + uint8_t num_addr; + uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; +} PACKED gap_get_bonded_devices_rp; + +#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 +typedef __packed struct _gap_is_device_bonded_cp{ + uint8_t peer_address_type; + tBDAddr peer_address; +} PACKED gap_is_device_bonded_cp; + + +#define OCF_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef __packed struct _gatt_add_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_serv_rp; +#define GATT_ADD_SERV_RP_SIZE 3 + +#define OCF_GATT_INCLUDE_SERV 0x0103 +typedef __packed struct _gatt_include_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_include_serv_rp; +#define GATT_INCLUDE_SERV_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR 0x0104 +typedef __packed struct _gatt_add_char_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_rp; +#define GATT_ADD_CHAR_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR_DESC 0x0105 +typedef __packed struct _gatt_add_char_desc_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_desc_rp; +#define GATT_ADD_CHAR_DESC_RP_SIZE 3 + +#define OCF_GATT_UPD_CHAR_VAL 0x0106 + +#define OCF_GATT_DEL_CHAR 0x0107 +typedef __packed struct _gatt_del_char_cp{ + uint16_t service_handle; + uint16_t char_handle; +} PACKED gatt_del_char_cp; +#define GATT_DEL_CHAR_CP_SIZE 4 + +#define OCF_GATT_DEL_SERV 0x0108 +typedef __packed struct _gatt_del_serv_cp{ + uint16_t service_handle; +} PACKED gatt_del_serv_cp; +#define GATT_DEL_SERV_CP_SIZE 2 + +#define OCF_GATT_DEL_INC_SERV 0x0109 +typedef __packed struct _gatt_del_inc_serv_cp{ + uint16_t service_handle; + uint16_t inc_serv_handle; +} PACKED gatt_del_inc_serv_cp; +#define GATT_DEL_INC_SERV_CP_SIZE 4 + +#define OCF_GATT_SET_EVT_MASK 0x010A +typedef __packed struct _gatt_set_evt_mask_cp{ + uint32_t evt_mask; +} PACKED gatt_set_evt_mask_cp; +#define GATT_SET_EVT_MASK_CP_SIZE 4 + +#define OCF_GATT_EXCHANGE_CONFIG 0x010B +typedef __packed struct _gatt_exchange_config_cp{ + uint16_t conn_handle; +} PACKED gatt_exchange_config_cp; +#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 + +#define OCF_ATT_FIND_INFO_REQ 0x010C +typedef __packed struct _att_find_info_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED att_find_info_req_cp; +#define ATT_FIND_INFO_REQ_CP_SIZE 6 + +#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D +#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 +typedef __packed struct _att_find_by_type_value_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[2]; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU - 7]; +} PACKED att_find_by_type_value_req_cp; + +#define OCF_ATT_READ_BY_TYPE_REQ 0x010E +#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_type_req_cp; + +#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F +#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_group_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_group_type_req_cp; + +#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 +#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val +typedef __packed struct _att_prepare_write_req_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t value_offset; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU-5]; +} PACKED att_prepare_write_req_cp; + +#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 +typedef __packed struct _att_execute_write_req_cp{ + uint16_t conn_handle; + uint8_t execute; +} PACKED att_execute_write_req_cp; +#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 + +#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 +typedef __packed struct _gatt_disc_all_prim_serivces_cp{ + uint16_t conn_handle; +} PACKED gatt_disc_all_prim_services_cp; +#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 + +#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 +typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ + uint16_t conn_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_disc_prim_service_by_uuid_cp; +#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid + +#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 +typedef __packed struct _gatt_disc_find_included_services_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED gatt_find_included_services_cp; +#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 + +#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 +typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ + uint16_t conn_handle; + uint16_t start_attr_handle; + uint16_t end_attr_handle; +} PACKED gatt_disc_all_charac_of_serv_cp; +#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 + +#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 + +#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ + uint16_t conn_handle; + uint16_t char_val_handle; + uint16_t char_end_handle; +} PACKED gatt_disc_all_charac_descriptors_cp; +#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 + +#define OCF_GATT_READ_CHARAC_VAL 0x0118 +typedef __packed struct _gatt_read_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_val_cp; +#define GATT_READ_CHARAC_VAL_CP_SIZE 4 + +#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 +typedef __packed struct _gatt_read_using_charac_uuid_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_read_using_charac_uuid_cp; +#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID + +#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A +typedef __packed struct _gatt_read_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_val_cp; +#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 + +#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B +#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles +typedef __packed struct _gatt_read_multiple_charac_val_cp{ + uint16_t conn_handle; + uint8_t num_handles; + uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_read_multiple_charac_val_cp; + +#define OCF_GATT_WRITE_CHAR_VALUE 0x011C + +#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D +#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_write_long_charac_val_cp; + +#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E +#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_charac_reliable_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; +} PACKED gatt_write_charac_reliable_cp; + +#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F +#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; +} PACKED gatt_write_long_charac_desc_cp; + +#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 +typedef __packed struct _gatt_read_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_desc_cp; +#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 + +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 +typedef __packed struct _gatt_read_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_desc_cp; +#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 +#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 3]; +} PACKED gatt_write_without_resp_cp; + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 +#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_signed_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 13]; +} PACKED gatt_signed_write_without_resp_cp; + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 +typedef __packed struct _gatt_confirm_indication_cp{ + uint16_t conn_handle; +} PACKED gatt_confirm_indication_cp; +#define GATT_CONFIRM_INDICATION_CP_SIZE 2 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef __packed struct _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 +typedef __packed struct _gatt_set_security_permission_cp{ + uint16_t service_handle; + uint16_t attr_handle; + uint8_t security_permission; +} PACKED gatt_set_security_permission_cp; +#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_GATT_READ_HANDLE_VALUE 0x012A +typedef __packed struct _gatt_read_handle_val_cp{ + uint16_t attr_handle; +} PACKED gatt_read_handle_val_cp; +#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 +typedef __packed struct _gatt_read_handle_val_rp{ + uint8_t status; + uint16_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; +} PACKED gatt_read_handle_val_rp; + +#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B +typedef __packed struct _gatt_read_handle_val_offset_cp{ + uint16_t attr_handle; + uint8_t offset; +} PACKED gatt_read_handle_val_offset_cp; +#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 +typedef __packed struct _gatt_read_handle_val_offset_rp{ + uint8_t status; + uint8_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; +} PACKED gatt_read_handle_val_offset_rp; + +#define OCF_GATT_UPD_CHAR_VAL_EXT 0x012C +#define GATT_UPD_CHAR_VAL_EXT_CP_SIZE 10 // without value +typedef __packed struct _gatt_upd_char_val_ext_cp{ + uint16_t service_handle; + uint16_t char_handle; + uint8_t update_type; + uint16_t char_length; + uint16_t value_offset; + uint8_t value_length; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_UPD_CHAR_VAL_EXT_CP_SIZE]; +} PACKED gatt_upd_char_val_ext_cp; + +#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 +typedef __packed struct _l2cap_conn_param_update_req_cp{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_update_req_cp; +#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 + +#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint16_t min_ce_length; + uint16_t max_ce_length; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; + +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; + +/** + * @defgroup BlueNRG_Events BlueNRG events (vendor specific) + * @{ + */ + +/** + * Vendor specific event for BlueNRG. + */ +typedef __packed struct _evt_blue_aci{ + uint16_t ecode; /**< One of the BlueNRG event codes. */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_blue_aci; + + +/** + * @} + */ + +#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gap.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GAP layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BNRG_GAP_H__ +#define __BNRG_GAP_H__ + +#include <ble_link_layer.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + * @name GAP UUIDs + * @{ + */ +#define GAP_SERVICE_UUID (0x1800) +#define DEVICE_NAME_UUID (0x2A00) +#define APPEARANCE_UUID (0x2A01) +#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) +#define RECONNECTION_ADDR_UUID (0x2A03) +#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) +/** + * @} + */ + +/** + * @name Characteristic value lengths + * @{ + */ +#define DEVICE_NAME_CHARACTERISTIC_LEN (8) +#define APPEARANCE_CHARACTERISTIC_LEN (2) +#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) +#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) +#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) +/** + * @} + */ + +/*------------- AD types for adv data and scan response data ----------------*/ + +/** + * @defgroup AD_Types AD Types + * @brief AD Types + * @{ + */ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +/** + * @anchor Flags_AD_Type_bits + * @name Flags AD Type bits + * @brief Bits in Flags AD Type + * @{ + */ +#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) +#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) +#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) +#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) +#define FLAG_BIT_LE_BR_EDR_HOST (0x10) +/** + * @} + */ + +/** + * @name Service UUID AD types + * @{ + */ +#define AD_TYPE_16_BIT_SERV_UUID (0x02) +#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) +#define AD_TYPE_32_BIT_SERV_UUID (0x04) +#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) +#define AD_TYPE_128_BIT_SERV_UUID (0x06) +#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) +/** + * @} + */ + +/* LOCAL NAME AD types */ +/** + * @name Local name AD types + * @{ + */ +#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) +#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) +/** + * @} + */ + +/* TX power level AD type*/ +#define AD_TYPE_TX_POWER_LEVEL (0x0A) + +/* Class of device */ +#define AD_TYPE_CLASS_OF_DEVICE (0x0D) + +/* security manager TK value AD type */ +#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) + +/* security manager OOB flags */ +#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) + +/* slave connection interval AD type */ +#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) + +/* service solicitation UUID list Ad types*/ +/** + * @name Service solicitation UUID list AD types + * @{ + */ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) +#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) +/** + * @} + */ + +/* service data AD type */ +#define AD_TYPE_SERVICE_DATA (0x16) + +/* manufaturer specific data AD type */ +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/* appearance AD type */ +#define AD_TYPE_APPEARANCE (0x19) + +/* advertising interval AD type */ +#define AD_TYPE_ADVERTISING_INTERVAL (0x1A) + +/** + * @} + */ + +#define MAX_ADV_DATA_LEN (31) + +#define DEVICE_NAME_LEN (7) +#define BD_ADDR_SIZE (6) + +/** + * @name Privacy flag values + * @{ + */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) +/** + * @} + */ + +/** + * @name Intervals + * Intervals in terms of 625 micro sec + * @{ + */ +#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ +#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ +#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ +#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ +#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ +#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ +#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ +#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ +/** + * @} + */ + +/** + * @name Timeout values + * @{ + */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ +/** + * @} + */ + +/** + * @anchor gap_roles + * @name GAP Roles + * @{ +*/ +#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) +#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) + +#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) +#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) +/** + * @} + */ + +/** + * @anchor gap_procedure_codes + * @name GAP procedure codes + * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event + * and aci_gap_terminate_gap_procedure() command. + * @{ + */ +#define GAP_LIMITED_DISCOVERY_PROC (0x01) +#define GAP_GENERAL_DISCOVERY_PROC (0x02) +#define GAP_NAME_DISCOVERY_PROC (0x04) +#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) +#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) +#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) +#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) +#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1231 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gap_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GAP_ACI_H__ +#define __BLUENRG_GAP_ACI_H__ + +/** + *@addtogroup GAP GAP + *@brief GAP layer. + *@{ + */ + +/** + *@defgroup GAP_Functions GAP functions + *@brief API for GAP layer. + *@{ + */ + +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". + * @param privacy_enabled Enable (1) or disable (0) privacy. + * @param device_name_char_len Length of the device name characteristic + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, + uint8_t device_name_char_len, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Privacy Flag (peripheral role only) + * @li Reconnection Address (peripheral role only) + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB04A1(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); + +/** + * @brief Set the Device in non-discoverable mode. + * @note This command will disable the LL advertising. + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_discoverable(void); + +/** + * @brief Put the device in limited discoverable mode + * (as defined in GAP specification volume 3, section 9.2.3). + * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. + * The advertising can be disabled at any time by issuing + * aci_gap_set_non_discoverable() command. + * The AdvIntervMin and AdvIntervMax parameters are optional. If both + * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). + * Host can set the Local Name, a Service UUID list and the Slave Connection + * Minimum and Maximum. If provided, these data will be inserted into the + * advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() + * separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following + * standard AD types: + * @li AD Flags + * @li TX Power Level + * + * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates + * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. + * + * Example: + * @code + * + * #define ADV_INTERVAL_MIN_MS 100 + * #define ADV_INTERVAL_MAX_MS 200 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, + * (ADV_INTERVAL_MAX_MS*1000)/0.625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * sizeof(serviceUUIDList), serviceUUIDList, + * 0, 0); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 250 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 500 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg NO_WHITE_LIST_USE + * @arg WHITE_LIST_FOR_ONLY_SCAN + * @arg WHITE_LIST_FOR_ONLY_CONN + * @arg WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +/** + * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4). + * @note The device will be discoverable until the Host issue Aci_Gap_Set_Non_Discoverable command. + * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses + * the default values for advertising intervals (1.28 s and 2.56 s respectively for IDB04A1). + * When using connectable undirected advertising events:\n + * @li Adv_Interval_Min = 30 ms + * @li Adv_Interval_Max = 60 ms + * \nWhen using non-connectable advertising events or scannable undirected advertising events:\n + * @li Adv_Interval_Min = 100 ms + * @li Adv_Interval_Max = 150 ms + * Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided, + * these data will be inserted into the advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following standard AD types: + * @li AD Flags + * @li TX Power Level + * + * Usage example: + * + * @code + * + * #define ADV_INTERVAL_MIN_MS 800 + * #define ADV_INTERVAL_MAX_MS 900 + * #define CONN_INTERVAL_MIN_MS 100 + * #define CONN_INTERVAL_MAX_MS 300 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625, + * (ADV_INTERVAL_MAX_MS*1000)/625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * 0, NULL, + * (CONN_INTERVAL_MIN_MS*1000)/1250, + * (CONN_INTERVAL_MAX_MS*1000)/1250); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 1.28 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 2.56 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ONLY_SCAN + * @arg @ref WHITE_LIST_FOR_ONLY_CONN + * @arg @ref WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); + +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @param adv_interv_min Minimum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @param adv_interv_max Maximum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max); +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); + +/** + * @brief Set the IO capabilities of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param io_capability One of the allowed codes for IO Capability: + * @arg @ref IO_CAP_DISPLAY_ONLY + * @arg @ref IO_CAP_DISPLAY_YES_NO + * @arg @ref IO_CAP_KEYBOARD_ONLY + * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT + * @arg @ref IO_CAP_KEYBOARD_DISPLAY + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_io_capability(uint8_t io_capability); + +/** + * @brief Set the authentication requirements for the device. + * @note If the oob_enable is set to 0, oob_data will be ignored. + * This command has to be given only when the device is not in a connected state. + * @param mitm_mode MITM mode: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @param oob_enable If OOB data are present or not: + * @arg @ref OOB_AUTH_DATA_ABSENT + * @arg @ref OOB_AUTH_DATA_PRESENT + * @param oob_data Out-Of-Band data + * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process + * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process + * @param use_fixed_pin If application wants to use a fixed pin or not: + * @arg @ref USE_FIXED_PIN_FOR_PAIRING + * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING + * If a fixed pin is not used, it has to be provided by the application with + * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will + * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is + * accepted. + * @param bonding_mode One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode); + /** + * @brief Set the authorization requirements of the device. + * @note This command has to be given when connected to a device if authorization is required to access services + * which require authorization. + * @param conn_handle Handle of the connection. + * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required + * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables + * the authorization requirement in the device and when a remote device + * tries to read/write a characeristic with authorization requirements, the stack will + * send back an error response with "Insufficient authorization" error code. + * After pairing is complete a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event + * will be sent to the Host. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); + +/** + * @brief Provide the pass key that will be used during pairing. + * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param conn_handle Connection handle + * @param passkey Pass key that will be used during the pairing process. Must be a number between + * 0 and 999999. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); + +/** + * @brief Authorize a device to access attributes. + * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. + * + * @param conn_handle Connection handle + * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) + * @arg @ref CONNECTION_REJECTED : Reject (reject connection) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); + +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @param own_address_type If Privacy is disabled, then the peripheral address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the peripheral address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); + +/** + * @brief Put the device into undirected connectable mode. + * @note If privacy is enabled in the device, a resolvable private address is generated and used + * as the advertiser's address. If not, the address of the type specified in own_addr_type + * is used for advertising. + * @param own_addr_type Type of our address used during advertising: + * if BLUENRG (IDB04A1) + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * else if BLUENRG_MS (IDB05A1) + * If Privacy is disabled: + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled: + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_filter_policy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ALL + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); + +/** + * @brief Send a slave security request to the master. + * @note This command has to be issued to notify the master of the security requirements of the slave. + * The master may encrypt the link, initiate the pairing procedure, or reject the request. + * @param conn_handle Connection handle + * @param bonding One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @param mitm_protection If MITM protection is required or not: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); + +/** + * @brief Update advertising data. + * @note This command can be used to update the advertising data for a particular AD type. + * If the AD type specified does not exist, then it is added to the advertising data. + * If the overall advertising data length is more than 31 octets after the update, then + * the command is rejected and the old data is retained. + * @param AdvLen Length of AdvData array + * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification + * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. + * Example + * @code + * tBleStatus ret; + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; + * + * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * 8, local_name, 3, serviceUUIDList, 0, 0); + * ret = aci_gap_update_adv_data(5, manuf_data); + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); + +/** + * @brief Delete an AD Type + * @note This command can be used to delete the specified AD type from the advertisement data if + * present. + * @param ad_type One of the allowed AD types (see @ref AD_Types) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); + +/** + * @brief Get the current security settings + * @note This command can be used to get the current security settings of the device. + * @param mitm_protection @arg 0: Not required + * @arg 1: Required + * @param bonding @arg 0: No bonding mode + * @arg 1: Bonding mode + * @param oob_data @arg 0: Data absent + * @arg 1: Data present + * @param passkey_required @arg 0: Not required + * @arg 1: Fixed pin is present which is being used + * @arg 2: Passkey required for pairing. An event will be generated + * when required. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required); + +/** + * @brief Add addresses of bonded devices into the controller's whitelist. + * @note The command will return an error if there are no devices in the database or if it was unable + * to add the device into the whitelist. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_configure_whitelist(void); + +/** + * @brief Terminate a connection. + * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. + * @param conn_handle Connection handle + * @param reason Reason for requesting disconnection. The error code can be any of ones as specified + * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); + +/** + * @brief Clear the security database. + * @note All the devices in the security database will be removed. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_clear_security_database(void); + +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @param conn_handle + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB04A1(void); + +/** + * @brief Start the limited discovery procedure. + * @note The controller is commanded to start active scanning. When this procedure is started, + * only the devices in limited discoverable mode are returned to the upper layers. + * The procedure is terminated when either the upper layers issue a command to terminate the + * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code + * set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated + * due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC. + * The device found when the procedure is ongoing is returned to the upper layers through the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the general discovery procedure. + * @note The controller is commanded to start active scanning. The procedure is terminated when + * either the upper layers issue a command to terminate the procedure by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC + * or a timeout happens. When the procedure is terminated due to any of the above reasons, + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to + * @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to + * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the name discovery procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. Once a connection is established, GATT procedure is started to read the + * device name characteristic. When the read is completed (successfully or unsuccessfully), + * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also + * contains the name of the device if the device name was read successfully. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Start the auto connection establishment procedure. + * @note The devices specified are added to the white list of the controller and a LE_Create_Connection + * call will be made to the controller by GAP with the initiator filter policy set to + * use whitelist to determine which advertiser to connect to. When a command is issued to + * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the + * controller by GAP. + * The procedure is terminated when either a connection is successfully established with one of + * the specified devices in the white list or the procedure is explicitly terminated by issuing + * the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start a general connection establishment procedure. + * @note The host enables scanning in the controller with the scanner filter policy set + * to accept all advertising packets and from the scanning results all the devices + * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * The upper layer then has to select one of the devices to which it wants to connect + * by issuing the command aci_gap_create_connection(). The procedure is terminated + * when a connection is established or the upper layer terminates the procedure by + * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates); +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); + +/** + * @brief Start a selective connection establishment procedure. + * @note The GAP adds the specified device addresses into white list and enables scanning in + * the controller with the scanner filter policy set to accept packets only from + * devices in whitelist. All the devices found are sent to the upper layer by the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the + * devices to which it wants to connect by issuing the command aci_gap_create_connection(). + * On completion of the procedure a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated + * with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * The procedure is terminated when a connection is established or the upper layer terminates + * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure + * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start the direct connection establishment procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. The procedure can be terminated explicitly by the upper layer by issuing + * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the + * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller + * by GAP. + * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can + * be explicitly terminated by the upper layer by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is + * returned with the procedure code set to the corresponding procedure. + * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes"). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); + +/** + * @brief Start the connection parameter update procedure. + * @note Allowed by the Central to update the connection parameter of the specified connection. + * A Link Layer Connection Update procedure is started on the controller. + * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to + * the upper layer. + * @param conn_handle Handle of the connection for which the update procedure has to be started. + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Send a pairing request. + * @note Send the SM pairing request to start a pairing process from a Central. The authentication + * requirements and IO capabilities should be set before issuing this command using + * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). + * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. + * @param conn_handle Handle of the connection for which the pairing request has to be sent. + * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded + * @arg 0x01: Pairing request will be sent even if the device was previously bonded + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param[in] address Address to be resolved. + * @param[out] actual_address The public or static random address of the peer device, distributed during pairing phase. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); + +/** + * @brief This command gets the list of bonded devices. + * @note It returns the number of addresses and the corresponding address types and values. + * Example: + * @code + * tBleStatus ret; + * uint8_t num_devices = 0; + * uint8_t device_list[12*7]; + * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); + * for(int i = 0; i < num_devices; i+=7){ + * uint8_t addr_type = device_list[i]; + * uint8_t addr = device_list[i+1]; + * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); + * } + * @endcode + * + * @param[out] num_devices The number of bonded devices. + * @param[out] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address + * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. + * @param device_list_size Maximum size of the device_list buffer used to return the device list. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); + +/** + * @brief Puts the device into broadcast mode + * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address + * as specified in the own_addr_type parameter of the command. + * @param adv_interv_min Minimum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_interv_max Maximum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param own_addr_type If Privacy is disabled, the broadcaster address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the broadcaster address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_data_length Length of the advertising data in the advertising packet + * @param adv_data Advertising data used by the device while advertising + * @param num_whitelist_entries Number of devices to be added to whitelist + * @param addr_array It will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Starts an observation procedure, when the device is in Observer role. + * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer + * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth + * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. + * The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. + * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param own_address_type If Privacy is disabled, then the scanner address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the scanner address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates); + +/** + * @brief The command finds whether a device is bonded. + * @note If the device is using a resolvable private address and it has been bonded, then the command will return + * BLE_STATUS_SUCCESS. + * @param peer_address_type The address type of the peer device + * @arg @ref PUBLIC_ADDR. + * @arg @ref RANDOM_ADDR. + * @param peer_address Address used by the peer device while advertising. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address); + + +/** + * @} + */ + +/** + * @defgroup GAP_Events GAP events + * @{ + */ + +/** + * This event is generated by the controller when the limited discoverable + * mode ends due to timeout (180 seconds). No parameters in the event. + */ +#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) + + +/** + * This event is generated when the pairing process has completed successfully + * or a pairing procedure timeout has occurred or the pairing has failed. + * This is to notify the application that we have paired with a remote device + * so that it can take further actions or to notify that a timeout has occurred + * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. + */ +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +typedef __packed struct _evt_gap_pairing_cmplt{ + uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ + /** + * 0x00: Pairing Success. Pairing with a remote device was successful\n + * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n + * 0x02: Pairing Failed. The pairing failed with the remote device. + */ + uint8_t status; +} PACKED evt_gap_pairing_cmplt; + + +/** + * This event is generated by the Security manager to the application when a pass key is required for pairing. + * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. + * See @ref _evt_gap_pass_key_req. + */ +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +typedef __packed struct _evt_gap_pass_key_req{ + uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ +} PACKED evt_gap_pass_key_req; + + +/** + * This event is generated by the Security manager to the application when the application + * has set that authorization is required for reading/writing of attributes. This event will + * be generated as soon as the pairing is complete. When this event is received, + * aci_gap_authorization_response() command should be used by the application. + * See @ref _evt_gap_author_req. + */ +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +typedef __packed struct _evt_gap_author_req{ + uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ +} PACKED evt_gap_author_req; + +/** + * This event is generated when the slave security request is successfully sent to the master. + * No parameters for this event. + */ +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) + +/** + * This event is generated on the slave when a aci_gap_slave_security_request() is called to reestablish the bond + * with a master but the master has lost the bond. When this event is received, the upper layer has to issue the + * command aci_gap_allow_rebond() in order to allow the slave to continue the pairing process with the master. + * On the master this event is raised when aci_gap_send_pairing_request() is called to reestablish a bond with a slave + * but the slave has lost the bond. In order to create a new bond the master has to launch aci_gap_send_pairing_request() + * with force_rebond set to 1. + * No parameters for this event + */ +#define EVT_BLUE_GAP_BOND_LOST (0X0405) + +/** + * The event is given by the GAP layer to the upper layers when a device is discovered during scanning + * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. + */ +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef __packed struct _evt_gap_device_found{ + uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ + uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ + tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ + uint8_t data_length; /**< Length of advertising or scan response data. */ + uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ +} PACKED evt_gap_device_found; + +/** + * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated + * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. + */ +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef __packed struct _evt_gap_procedure_complete{ + uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ + /** + * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed + * due to authentication requirements). + */ + uint8_t status; + /** + * Procedure specific data.\n + * @li For Name Discovery Procedure:\n + * the name of the peer device if the procedure completed successfully. + * @li For General Connection Establishment Procedure:\n + * The reconnection address written to the peripheral device if the peripheral is privacy enabled + */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_gap_procedure_complete; + +/** + * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral + * is not able to resolve the private address of the peer device after connecting to it. + */ +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) +typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ + uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ +} PACKED evt_gap_addr_not_resolved_IDB05A1; +/** + * This event is raised when the reconnection address is generated during the general connection + * establishment procedure. The same address is set into the peer device also as a part of the general + * connection establishment procedure. In order to make use of the reconnection address the next time + * while connecting to the bonded peripheral, the application needs to use this reconnection address + * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() + * and aci_gap_start_auto_conn_establish_proc(). + */ +#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) +typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ + uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ +} PACKED evt_gap_reconnection_addr_IDB04A1; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1128 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GATT_ACI_H__ +#define __BLUENRG_GATT_ACI_H__ + +#include "bluenrg_gatt_server.h" + +/** + *@addtogroup GATT GATT + *@brief GATT layer. + *@{ + */ + +/** + *@defgroup GATT_Functions GATT functions + *@brief API for GATT layer. + *@{ + */ + +/** + * @brief Initialize the GATT layer for server and client roles. + * @note It adds also the GATT service with Service Changed Characteristic. + * Until this command is issued the GATT channel will not process any commands + * even if the connection is opened. This command has to be given + * before using any of the GAP features. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_init(void); + +/** + * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs + * to reserve the handle ranges for this service using max_attr_records parameter. This + * parameter specifies the maximum number of attribute records that can be added to this + * service (including the service attribute, include attribute, characteristic attribute, + * characteristic value attribute and characteristic descriptor attribute). Handle of the + * created service is returned. + * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors + * are allocated from the attribute pool. + * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field + * @param service_type Primary or secondary service. See @ref Service_type "Service Type". + * @param max_attr_records Maximum number of attribute records that can be added to this service + * (including the service declaration itself) + * @param[out] serviceHandle Handle of the Service. When this service is added to the service, + * a handle is allocated by the server to this service. Server also + * allocates a range of handles for this service from serviceHandle to + * <serviceHandle + max_attr_records>. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, + const uint8_t* service_uuid, + uint8_t service_type, + uint8_t max_attr_records, + uint16_t *serviceHandle); + +/** + * @brief Include a service given by included_start_handle and included_end_handle to another service + * given by service_handle. Attribute server creates an INCLUDE definition attribute and return + * the handle of this attribute in included_handle. + * @param service_handle Handle of the service to which another service has to be included + * @param included_start_handle Start Handle of the service which has to be included in service + * @param included_end_handle End Handle of the service which has to be included in service + * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". + * @param[in] included_uuid 16-bit or 128-bit UUID. + * @param[out] included_handle Handle of the include declaration. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle); + +/** + * @brief Add a characteristic to a service. + * @param serviceHandle Handle of the service to which the characteristic has to be added. + * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param charUuid 16-bit or 128-bit UUID. + * @param charValueLen Maximum length of the characteristic value. + * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, + * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". + * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @arg GATT_DONT_NOTIFY_EVENTS + * @arg GATT_NOTIFY_ATTRIBUTE_WRITE + * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP + * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. + * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client + * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE + * properties. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle); + +/** + * Add a characteristic descriptor to a service. + * @param serviceHandle Handle of the service to which the characteristic belongs + * @param charHandle Handle of the characteristic to which description has to be added. + * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG + * (Well_known_UUIDs) or a user-defined one. + * @param descValueMaxLen The maximum length of the descriptor value + * @param descValueLen Current Length of the characteristic descriptor value + * @param[in] descValue Value of the characteristic description + * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". + * @arg ATTR_NO_ACCESS + * @arg ATTR_ACCESS_READ_ONLY + * @arg ATTR_ACCESS_WRITE_REQ_ONLY + * @arg ATTR_ACCESS_READ_WRITE + * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE + * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param[out] descHandle Handle of the Characteristic Descriptor. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle); + +/** + * @brief Update a characteristic value in a service. + * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. The command is queued into the + * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, + * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or + * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate + * than what is allowed by the link. Throughput on BLE link depends on connection interval and + * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() + * for more info on how to suggest new connection parameters from a slave). If the application does not + * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function + * returns @ref BLE_STATUS_SUCCESS or any other error code.\n + * Example:\n + * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some + * notifications will be lost. + * @code + * tBleStatus Free_Fall_Notify(void) + * { + * uint8_t val; + * tBleStatus ret; + * + * val = 0x01; + * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); + * + * if (ret != BLE_STATUS_SUCCESS){ + * PRINTF("Error while updating FFall characteristic.\n") ; + * return BLE_STATUS_ERROR ; + * } + * return BLE_STATUS_SUCCESS; + * } + * @endcode + * Here if BlueNRG buffer become full, the application try again to send the notification. + * @code + * struct timer t; + * Timer_Set(&t, CLOCK_SECOND*10); + * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ + * // Radio is busy (buffer full). + * if(Timer_Expired(&t)) + * break; + * } + * @endcode + * + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic + * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, + * and the attribute value is of variable length, then the length of the attribute will + * be set to the charValueLen. If the charValOffset is set to a value greater than 0, + * then the length of the attribute will be set to the maximum length as specified for + * the attribute while adding the characteristic. + * @param charValueLen Length of the characteristic value in octets + * @param[in] charValue Characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue); +/** + * @brief Delete the specified characteristic from the service. + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); + +/** + * @brief Delete the specified service from the GATT server database. + * @param servHandle Handle of the service to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_service(uint16_t servHandle); + +/** + * @brief Delete the Include definition from the service. + * @param servHandle Handle of the service to which Include definition belongs + * @param includeServHandle Handle of the Included definition to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); + +/** + * @brief Perform an ATT MTU exchange procedure. + * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP + * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated + * to indicate the end of the procedure. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); + +/** + * @brief Send a @a Find @a Information @a Request. + * @note This command is used to obtain the mapping of attribute handles with their associated + * types. The responses of the procedure are given through the + * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by + * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range of attributes to be discovered on the server + * @param end_handle Ending handle of the range of attributes to be discovered on the server + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send a @a Find @a By @a Type @a Value @a Request + * @note The Find By Type Value Request is used to obtain the handles of attributes that + * have a given 16-bit UUID attribute type and a given attribute value. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid 2 octet UUID to find (little-endian) + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). + * @param attr_val Attribute value to find + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send a @a Read @a By @a Type @a Request + * @note The Read By Type Request is used to obtain the values of attributes where the attribute type + * is known but the handle is not known. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Read @a By @a Group @a Type @a Request + * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute + * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping + * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Prepare @a Write @a Request + * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param attr_handle The handle of the attribute to be written + * @param value_offset The offset of the first octet to be written + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). + * @param attr_val The value of the attribute to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send an @a Execute @a Write @a Request + * @note The Execute Write Request is used to request the server to write or cancel the write of all the + * prepared values currently held in the prepare queue from this client. + * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param execute @arg 0x00 Cancel all prepared writes + * @arg 0x01 Immediately write all pending prepared values. + * @return Value indicating success or error code. + */ +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); + +/** + * @brief This command will start the GATT client procedure to discover all primary services on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +/** + * @brief Start the procedure to discover the primary services of the specified UUID on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to find all included services. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle Start handle of the service + * @param end_handle End handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Start the procedure to discover all the characteristics of a given service. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_attr_handle Start attribute handle of the service + * @param end_attr_handle End attribute handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +/** + * @brief Start the procedure to discover all the characteristics specified by a UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Start attribute handle of the service + * @param end_handle End attribute handle of the service + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); + +/** + * @brief Start the procedure to discover all characteristic descriptors on the server. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. + * @param conn_handle Connection handle for which the command is given. + * @param char_val_handle Starting handle of the characteristic + * @param char_end_handle End handle of the characteristic + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +/** + * @brief Start the procedure to read the attribute value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to read all the characteristics specified by the UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range to be searched + * @param end_handle End handle of the range to be searched + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start a procedure to read multiple characteristic values from a server. + * @note This sub-procedure is used to read multiple Characteristic Values from a server when the + * client knows the Characteristic Value Handles. + * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param num_handles The number of handles for which the value has to be read + * @param set_of_handles The handles for which the attribute value has to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles); + +/** + * @brief Start the procedure to write a characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to write a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start the procedure to write a characteristic reliably. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to write a long characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP + * event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic descriptor + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start the procedure to write a characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to read the descriptor specified. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the descriptor to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to write a characteristic value without waiting for any response from the server. + * @note No events are generated after this command is executed. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 3) + * @param[in] attr_val Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start a signed write without response from the server. + * @note The procedure i used to write a characteristic value with an authentication signature without waiting + * for any response from the server. It cannot be used when the link is encrypted. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 13). + * @param attr_val Value to be written + * @return Value indicating success or error code + */ +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Confirm an indication + * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); + +/** + * @brief Allow or reject a write request from a client. + * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, + * then the status has to be set to 1 and the error code has to be set to the error code that has to be + * passed to the client. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n + * 0x01: The value cannot be written to the attribute specified by the attr_handle. + * @param err_code The error code that has to be passed to the client in case the write has to be rejected. + * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val); + +/** + * @brief Allow the GATT server to send a response to a read request from a client. + * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ + * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response + * can be sent to the client. So if the application wishes to update any of the attributes before + * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value + * and then give this command. The application should perform the required operations within 30 seconds, + * otherwise the GATT procedure will go to timeout. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_allow_read(uint16_t conn_handle); + +/** + * @brief Set the security permission for the attribute handle specified. + * @note Currently the setting of security permission is allowed only for client configuration descriptor. + * @param service_handle Handle of the service which contains the attribute whose security + * permission has to be modified. + * @param attr_handle Handle of the attribute whose security permission has to be modified. + * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission); + +/** + * @brief This command sets the value of the descriptor specified by charDescHandle. + * @param servHandle Handle of the service which contains the descriptor. + * @param charHandle Handle of the characteristic which contains the descriptor. + * @param charDescHandle Handle of the descriptor whose value has to be set. + * @param charDescValOffset Offset from which the descriptor value has to be updated. + * @param charDescValueLen Length of the descriptor value + * @param[in] charDescValue descriptor value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue); + +/** + * @brief Reads the value of the attribute handle specified from the local GATT database. + * @param attr_handle Handle of the attribute to read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + + /** + * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. + * @param attr_handle Handle of the attribute to read + * @param offset Offset from which the value needs to be read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); +/** + * @brief Update the value of a characteristic and sends notifications or indications. + * @note This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute + * up to 512 bytes and indicate selectively the generation of indications and notifications. + * @param service_handle Handle of the service to which the characteristic belongs. + * @param char_handle Handle of the characteristic + * @param update_type Bitmask that controls generation of notifications and indications. It can be a combination + * @arg @ref NOTIFICATION (0x01): send notification, if enabled. + * @arg @ref INDICATION (0x02): send indication, if enabled. + * If set to 0 no notifications or indications are sent. + * @param char_length Total length of the characteristic value. In case of a variable size characteristic, + * this field specifies the new length of the characteristic value after the update; + * in case of fixed length characteristic this field is ignored. + * @param value_offset The offset from which the attribute value has to be updated + * @param value_length Length of the value to be updated + * @param[out] value Updated characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value); + +/** + * @} + */ + + +/** + * @defgroup GATT_Events GATT events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** + * This event (if enabled, see @ref Gatt_Event_Mask "Gatt Event Mask") is raised to the application + * by the GATT server when a client modifies any attribute on the server, as consequence of one of + * the following GATT procedures: + * @li write without response + * @li signed write without response + * @li write characteristic value + * @li write long characteristic value + * @li reliable write. + * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. + */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint16_t offset; /**< Offset from which the write has been performed by the peer device */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB05A1; + +typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB04A1; + +/** + * This event is generated by the client/server to the application on a GATT timeout (30 seconds). + * See @ref _evt_gatt_procedure_timeout. + */ +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +typedef __packed struct _evt_gatt_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ +} PACKED evt_gatt_procedure_timeout; + +/** + * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). + * See @ref _evt_att_exchange_mtu_resp. + */ +#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) +typedef __packed struct _evt_att_exchange_mtu_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data (always 1). */ + uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ +} PACKED evt_att_exchange_mtu_resp; + +/** + * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and + * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. + */ +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef __packed struct _evt_att_find_information_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ + /** + * A sequence of handle-uuid pairs.\n + * @li if format=1, each pair is:\n + * [2 octets for handle, 2 octets for UUIDs] \n + * @li if format=2, each pair is:\n + * [2 octets for handle, 16 octets for UUIDs] + */ + uint8_t handle_uuid_pair[VARIABLE_SIZE]; +} PACKED evt_att_find_information_resp; + +/** + * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See + * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. + */ +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +typedef __packed struct _evt_att_find_by_type_val_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + /** + * Handles Information List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] + */ + uint8_t handles_info_list[VARIABLE_SIZE]; +} PACKED evt_att_find_by_type_val_resp; + +/** + * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and + * aci_gatt_disc_all_charac_of_serv(). + * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. + */ +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef __packed struct _evt_att_read_by_type_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ + /** + * Attribute Data List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] + */ + uint8_t handle_value_pair[VARIABLE_SIZE]; +} PACKED evt_att_read_by_type_resp; + +/** + * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). + * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. + */ +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +typedef __packed struct _evt_att_read_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ +} PACKED evt_att_read_resp; + +/** + * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). + * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. + */ +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +typedef __packed struct _evt_att_read_blob_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ +} PACKED evt_att_read_blob_resp; + +/** + * This event is generated in response to a @a Read @a Multiple @a Request. + * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. + */ +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +typedef __packed struct _evt_att_read_mult_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ +} PACKED evt_att_read_mult_resp; + +/** + * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). + * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. + */ +#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) +typedef __packed struct _evt_att_read_by_group_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_data_length; /**< The size of each Attribute Data. */ + /** + * A list of Attribute Data where the attribute data is composed by: + * @li 2 octets for Attribute Handle + * @li 2 octets for End Group Handle + * @li (attribute_data_length - 4) octets for Attribute Value + */ + uint8_t attribute_data_list[VARIABLE_SIZE]; +} PACKED evt_att_read_by_group_resp; + +/** + * This event is generated in response to a @a Prepare @a Write @a Request. + * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. + */ +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +typedef __packed struct _evt_att_prepare_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attribute_handle; /**< The handle of the attribute to be written. */ + uint16_t offset; /**< The offset of the first octet to be written. */ + uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ +} PACKED evt_att_prepare_write_resp; + +/** + * This event is generated in response to an @a Execute @a Write @a Request. + * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. + */ +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +typedef __packed struct _evt_att_exec_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Always 0. */ +} PACKED evt_att_exec_write_resp; + +/** + * This event is generated when an indication is received from the server. + * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. + */ +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +typedef __packed struct _evt_gatt_indication{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_indication; + +/** + * This event is generated when a notification is received from the server. + * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. + */ +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef __packed struct _evt_gatt_notification{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_attr_notification; + +/** + * This event is generated when a GATT client procedure completes either with error or successfully. + * See @ref _evt_gatt_procedure_complete. + */ +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef __packed struct _evt_gatt_procedure_complete{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ + uint8_t data_length; /**< Length of error_code field (always 1). */ + /** + * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). + */ + uint8_t error_code; +} PACKED evt_gatt_procedure_complete; + +/** + * This event is generated when an Error Response is received from the server. The error response can be given + * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended + * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. + */ +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +typedef __packed struct _evt_gatt_error_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t req_opcode; /**< The request that generated this error response. */ + uint16_t attr_handle; /**< The attribute handle that generated this error response. */ + uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ +} PACKED evt_gatt_error_resp; + +/** + * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using + * Characteristic UUID" procedure. + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. + */ +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + /** + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. + */ + uint8_t attr_value[VARIABLE_SIZE]; +} PACKED evt_gatt_disc_read_char_by_uuid_resp; + +/** + * This event is given to the application when a write request, write command or signed write command + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * If the write is rejected by the application, then the value of the attribute will not be modified. + * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. + * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef __packed struct _evt_gatt_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_write_permit_req; + +/** + * This event is given to the application when a read request or read blob request is received by the server + * from the client. This event will be given to the application only if the event bit for this event generation + * is set when the characteristic was added. + * On receiving this event, the application can update the value of the handle if it desires and when done + * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef __packed struct _evt_gatt_read_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ + uint8_t data_length; /**< Length of offset field. */ + uint16_t offset; /**< Contains the offset from which the read has been requested */ +} PACKED evt_gatt_read_permit_req; + +/** + * This event is given to the application when a read multiple request or read by type request is received + * by the server from the client. This event will be given to the application only if the event bit for this + * event generation is set when the characteristic was added. + * On receiving this event, the application can update the values of the handles if it desires and when done + * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_multi_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) +typedef __packed struct _evt_gatt_read_multi_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ +} PACKED evt_gatt_read_multi_permit_req; + +/** + * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2). + * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES. + * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value(). + * See @ref evt_gatt_tx_pool_vailable. + * + */ +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE (0x0C16) +typedef __packed struct _evt_gatt_tx_pool_available{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t available_buffers; /**< Length of data field. */ +} PACKED evt_gatt_tx_pool_available; + +/** + * This event is raised on the server when the client confirms the reception of an indication. + */ +#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT (0x0C17) +typedef __packed struct _evt_gatt_server_confirmation{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ +} PACKED evt_gatt_server_confirmation; +/** + * This event is given to the application when a prepare write request + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * Based on the response from the application, the attribute value will be modified by the stack. + * If the write is rejected by the application, then the value of the attribute will not be modified + * and an error response will be sent to the client, with the error code as specified by the application. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ (0x0C18) +typedef __packed struct _evt_gatt_prepare_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint16_t offset; /**< The offset from which the prepare write has been requested */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_prepare_write_permit_req; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,229 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gatt_server.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GATT server layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BNRG_GATT_SERVER_H__ +#define __BNRG_GATT_SERVER_H__ + +#include "ble_compiler.h" +#include "ble_status.h" + +/** + *@addtogroup GATT GATT + *@{ + */ + +/** + * @anchor Well-Known_UUIDs + * @name Well-Known UUIDs + * @{ + */ +#define PRIMARY_SERVICE_UUID (0x2800) +#define SECONDARY_SERVICE_UUID (0x2801) +#define INCLUDE_SERVICE_UUID (0x2802) +#define CHARACTERISTIC_UUID (0x2803) +#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) +#define CHAR_USER_DESC_UUID (0x2901) +#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) +#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) +#define CHAR_FORMAT_DESC_UUID (0x2904) +#define CHAR_AGGR_FMT_DESC_UUID (0x2905) +#define GATT_SERVICE_UUID (0x1801) +#define GAP_SERVICE_UUID (0x1800) +#define SERVICE_CHANGED_UUID (0x2A05) +/** + * @} + */ + +/** + * @anchor Access_permissions + * @name Access permissions + * Access permissions for an attribute + * @{ + */ +#define ATTR_NO_ACCESS (0x00) +#define ATTR_ACCESS_READ_ONLY (0x01) +#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) +#define ATTR_ACCESS_READ_WRITE (0x03) +#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) +#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) +/** + * Allows all write procedures + */ +#define ATTR_ACCESS_WRITE_ANY (0x0E) +/** + * @} + */ + +/** + * @anchor Char_properties + * @name Characteristic properties. + * @{ + */ +#define CHAR_PROP_BROADCAST (0x01) +#define CHAR_PROP_READ (0x02) +#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) +#define CHAR_PROP_WRITE (0x08) +#define CHAR_PROP_NOTIFY (0x10) +#define CHAR_PROP_INDICATE (0x20) +#define CHAR_PROP_SIGNED_WRITE (0x40) +#define CHAR_PROP_EXT (0x80) +/** + * @} + */ + + +/** + * @anchor Security_permissions + * @name Security permissions for an attribute. + * @{ + */ +#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ +#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ +#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ +#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ +/** + * @} + */ + +/** + * @anchor UUID_Types + * @name Type of UUID (16 bit or 128 bit). + * @{ + */ +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) +/** + * @} + */ + +/** + * @anchor Service_type + * @name Type of service (primary or secondary) + * @{ + */ +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) +/** + * @} + */ + +/** + * @anchor Gatt_Event_Mask + * @name Gatt Event Mask + * Type of event generated by GATT server + * @{ + */ +#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ +#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. + An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ +#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd + or a signed write cmd are received by the server for this attribute. + An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ +#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is + received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ +/** + * @} + */ + +/** + * @name Type of characteristic length + * See aci_gatt_add_char() + * @{ + */ +#define CHAR_VALUE_LEN_CONSTANT (0x00) +#define CHAR_VALUE_LEN_VARIABLE (0x01) +/** + * @} + */ + + +/** + * @name Encryption key size + * @{ + */ +/** + * Minimum encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Maximum encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) +/** + * @} + */ + +/** + * @name Characteristic Presentation Format + * @{ + */ +typedef __packed struct _charactFormat { + uint8_t format; + int8_t exp; + uint16_t unit; + uint8_t name_space; + uint16_t desc; +} PACKED charactFormat; + +/** + * @} + */ + +/** + * @name Format + * @{ + */ +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F +/** + * @} + */ + +/** + * @name Unit + * @{ + */ +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 +/** + * @} + */ + + +/** + * ATT MTU size + */ +#define ATT_MTU (23) + +/** + * @} + */ + + /** + * @name Update type of aci_gatt_upd_char_val_ext(). + * @{ + */ + +#define NOTIFICATION 1 +#define INDICATION 2 + +#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,385 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hal_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with HCI commands for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_HAL_ACI_H__ +#define __BLUENRG_HAL_ACI_H__ + +/** + *@addtogroup HAL HAL + *@brief Hardware Abstraction Layer. + *@{ + */ + +/** + * @defgroup HAL_Functions HAL functions + * @brief API for BlueNRG HAL layer. + * @{ + */ + +/** + * @brief This command retrieves the buid number of the firmware. + * @param[out] build_number Build number identifying the firmware release. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number); + +/** + * @brief This command writes a value to a low level configure data structure. + * @note It is useful to setup directly some low level parameters for the system at runtime. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * + * @param len Length of data to be written + * @param[out] val Data to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val); + +/** + * @brief This command requests the value in the low level configure data structure. + * The number of read bytes changes for different Offset. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * @param data_len Length of the data buffer + * @param[out] data_len_out_p length of the data returned by the read. + * @param[out] data Read data + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data); + +/** + * @brief This command sets the TX power level of the BlueNRG. + * @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines + * the output power level (dBm). + * When the system starts up or reboots, the default TX power level will be used, which is + * the maximum value of 8dBm. Once this command is given, the output power will be changed + * instantly, regardless if there is Bluetooth communication going on or not. For example, + * for debugging purpose, the BlueNRG can be set to advertise all the time and use this + * command to observe the signal strength changing. The system will keep the last received + * TX power level from the command, i.e. the 2nd command overwrites the previous TX power + * level. The new TX power level remains until another Set TX Power command, or the system + * reboots.\n + * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the + * right value, depending on the selected hardware configuration for the RF network: + * normal mode or high power mode. + * @param pa_level Can be from 0 to 7. Set the PA level value. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +/** + * @brief This command returns the number of packets sent in Direct Test Mode. + * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets + * have been transmitted. This command can be used to check how many packets have been sent + * during the Direct TX test.\n + * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again. + * The counter is not cleared until the next Direct TX test starts. + * @param[out] number_of_packets Number of packets sent during the last Direct TX test. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets); + +/** + * @brief Put the device in standby mode. + * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the + * device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode, + * the device can still wake up itself with the internal timer. But in standby mode, this timer is + * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command + * sent via SPI bus. + * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code + * ERR_COMMAND_DISALLOWED will be returned. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_device_standby(void); + +/** + * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. + * @note The frequency sine wave at the specific channel may be used for test purpose only. + * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. + * This command shouldn't be used when normal Bluetooth activities are ongoing. + * The tone should be stopped by aci_hal_tone_stop() command. + * + * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the + * channel central frequency minus 250 kHz. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +/** + * This command is used to stop the previously started aci_hal_tone_start() command. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_stop(void); + +/** + * @brief This command returns the status of all the connections. + * @note This command returns the status of the 8 Bluetooth low energy links managed by the device. + * @param[out] link_status Array of link status (8 links). See @ref Link_Status. + * @param[out] conn_handle Array of connection handles for each link. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]); + +/** + * @brief This command returns the anchor period and the largest available slot. + * @note This command returns information about the anchor period to help application in selecting + * slot timings when operating in multi-link scenarios. + * @param anchor_period Current anchor period (multiple of 0.625 ms). + * @param max_free_slot Maximum available time (multiple of 0.625 ms) that can be allocated for a new slot. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot); + +/** + * @} + */ + +/** + * @defgroup HAL_Events HAL events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_HAL_INITIALIZED (0x0001) +typedef __packed struct _evt_hal_initialized{ + uint8_t reason_code; /**< Reset reason. See @ref Reset_Reasons */ +} PACKED evt_hal_initialized; + +/** + * This event is generated when an overflow occurs in the event queue read by the external microcontroller. + * This is normally caused when the external microcontroller does not read pending events. + * The returned bitmap indicates which event has been lost. Please note that one bit set to 1 indicates one or + * more occurrences of the particular events. The event EVT_BLUE_HAL_EVENTS_LOST cannot be lost and it will + * be inserted in the event queue as soon as a position is freed in the event queue. This event should not + * happen under normal operating condition where external microcontroller promptly reads events signaled by + * IRQ pin. It is provided to detected unexpected behavior of the external microcontroller or to allow + * application to recover situations where critical events are lost. + */ +#define EVT_BLUE_HAL_EVENTS_LOST_IDB05A1 (0x0002) +typedef __packed struct _evt_hal_events_lost{ + uint8_t lost_events[8]; /**< Bitmap of lost events. Each bit indicates one or more occurrences of the specific event. See @ref Lost_Events */ +} PACKED evt_hal_events_lost_IDB05A1; + + +/** + * This event is given to the application after the @ref ACI_BLUE_INITIALIZED_EVENT + * when a system crash is detected. This events returns system crash information for debugging purposes. + * Information reported are useful to understand the root cause of the crash. + */ +#define EVT_BLUE_HAL_CRASH_INFO_IDB05A1 (0x0003) +typedef __packed struct _evt_hal_crash_info{ + uint8_t crash_type; /**< Type of crash: Assert failed (0), NMI Fault (1), Hard Fault (2) */ + uint32_t sp; /**< SP register */ + uint32_t r0; /**< R0 register */ + uint32_t r1; /**< R1 register */ + uint32_t r2; /**< R2 register */ + uint32_t r3; /**< R3 register */ + uint32_t r12; /**< R12 register */ + uint32_t lr; /**< LR register */ + uint32_t pc; /**< PC register */ + uint32_t xpsr; /**< xPSR register */ + uint8_t debug_data_len; /**< length of debug_data field */ + uint8_t debug_data[VARIABLE_SIZE]; /**< Debug data */ +} PACKED evt_hal_crash_info_IDB05A1; + + +/** + * @} + */ + + +/** + * @anchor Reset_Reasons + * @name Reset Reasons + * See @ref EVT_BLUE_HAL_INITIALIZED. + * @{ + */ +#define RESET_NORMAL 1 /**< Normal startup. */ +#define RESET_UPDATER_ACI 2 /**< Updater mode entered with ACI command */ +#define RESET_UPDATER_BAD_FLAG 3 /**< Updater mode entered due to a bad BLUE flag */ +#define RESET_UPDATER_PIN 4 /**< Updater mode entered with IRQ pin */ +#define RESET_WATCHDOG 5 /**< Reset caused by watchdog */ +#define RESET_LOCKUP 6 /**< Reset due to lockup */ +#define RESET_BROWNOUT 7 /**< Brownout reset */ +#define RESET_CRASH 8 /**< Reset caused by a crash (NMI or Hard Fault) */ +#define RESET_ECC_ERR 9 /**< Reset caused by an ECC error */ +/** + * @} + */ + + +/** + * @defgroup Config_vals Offsets and lengths for configuration values. + * @brief Offsets and lengths for configuration values. + * See aci_hal_write_config_data(). + * @{ + */ + +/** + * @name Configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ +#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ +#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ +#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ +#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. + It can be written only if aci_hal_write_config_data() is the first command after reset. */ +#define CONFIG_DATA_RANDOM_ADDRESS (0x80) /**< Stored static random address. Read-only. */ + +/** + * Select the BlueNRG mode configurations.\n + * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) + * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) + * @li Mode 3: master/slave, 8 connections, RAM1 and RAM2. + * @li Mode 4: master/slave, 4 connections, RAM1 and RAM2 simultaneous scanning and advertising. + */ +#define CONFIG_DATA_MODE_OFFSET (0x2D) + +#define CONFIG_DATA_WATCHDOG_DISABLE (0x2F) /**< Set to 1 to disable watchdog. It is enabled by default. */ +/** + * @} + */ + +/** + * @name Length for configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_LEN (6) +#define CONFIG_DATA_DIV_LEN (2) +#define CONFIG_DATA_ER_LEN (16) +#define CONFIG_DATA_IR_LEN (16) +#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) +#define CONFIG_DATA_MODE_LEN (1) +#define CONFIG_DATA_WATCHDOG_DISABLE_LEN (1) +/** + * @} + */ + +/** + * @anchor Link_Status + * @name Status of the link + * See @ref aci_hal_get_link_status(). + * @{ + */ +#define STATUS_IDLE 0 +#define STATUS_ADVERTISING 1 +#define STATUS_CONNECTED_AS_SLAVE 2 +#define STATUS_SCANNING 3 +#define STATUS_CONNECTED_AS_MASTER 5 +#define STATUS_TX_TEST 6 +#define STATUS_RX_TEST 7 +/** + * @} + */ + +/** + * @} + */ + + /** + * @anchor Lost_Events + * @name Lost events bitmap + * See @ref EVT_BLUE_HAL_EVENTS_LOST. + * @{ + */ +#define EVT_DISCONN_COMPLETE_BIT 0 +#define EVT_ENCRYPT_CHANGE_BIT 1 +#define EVT_READ_REMOTE_VERSION_COMPLETE_BIT 2 +#define EVT_CMD_COMPLETE_BIT 3 +#define EVT_CMD_STATUS_BIT 4 +#define EVT_HARDWARE_ERROR_BIT 5 +#define EVT_NUM_COMP_PKTS_BIT 6 +#define EVT_ENCRYPTION_KEY_REFRESH_BIT 7 +#define EVT_BLUE_HAL_INITIALIZED_BIT 8 +#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE_BIT 9 +#define EVT_BLUE_GAP_PAIRING_CMPLT_BIT 10 +#define EVT_BLUE_GAP_PASS_KEY_REQUEST_BIT 11 +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST_BIT 12 +#define EVT_BLUE_GAP_SECURITY_REQ_INITIATED_BIT 13 +#define EVT_BLUE_GAP_BOND_LOST_BIT 14 +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE_BIT 15 +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_BIT 16 +#define EVT_BLUE_L2CAP_CONN_UPDATE_RESP_BIT 17 +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT_BIT 18 +#define EVT_BLUE_L2CAP_CONN_UPDATE_REQ_BIT 19 +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_BIT 20 +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT_BIT 21 +#define EVT_BLUE_EXCHANGE_MTU_RESP_BIT 22 +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP_BIT 23 +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP_BIT 24 +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP_BIT 25 +#define EVT_BLUE_ATT_READ_RESP_BIT 26 +#define EVT_BLUE_ATT_READ_BLOB_RESP_BIT 27 +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP_BIT 28 +#define EVT_BLUE_ATT_READ_BY_GROUP_RESP_BIT 29 +#define EVT_BLUE_ATT_WRITE_RESP_BIT 30 +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP_BIT 31 +#define EVT_BLUE_ATT_EXEC_WRITE_RESP_BIT 32 +#define EVT_BLUE_GATT_INDICATION_BIT 33 +#define EVT_BLUE_GATT_NOTIFICATION_BIT 34 +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE_BIT 35 +#define EVT_BLUE_GATT_ERROR_RESP_BIT 36 +#define EVT_BLUE_GATT_DISC_READ_CHARAC_BY_UUID_RESP_BIT 37 +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ_BIT 38 +#define EVT_BLUE_GATT_READ_PERMIT_REQ_BIT 39 +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ_BIT 40 +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_BIT 41 +#define EVT_BLUE_GATT_SERVER_RX_CONFIRMATION_BIT 42 +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ_BIT 43 +#define EVT_LL_CONNECTION_COMPLETE_BIT 44 +#define EVT_LL_ADVERTISING_REPORT_BIT 45 +#define EVT_LL_CONNECTION_UPDATE_COMPLETE_BIT 46 +#define EVT_LL_READ_REMOTE_USED_FEATURES_BIT 47 +#define EVT_LL_LTK_REQUEST_BIT 48 +/** + * @} + */ + +/** + * @name Hardware error event codes + * See @ref EVT_HARDWARE_ERROR. + * @{ + */ +/** + * Error on the SPI bus has been detected, most likely caused by incorrect SPI configuration on the external micro-controller. + */ +#define SPI_FRAMING_ERROR 0 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define RADIO_STATE_ERROR 1 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define TIMER_OVERRUN_ERROR 2 + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,166 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_l2cap_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with L2CAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_L2CAP_ACI_H__ +#define __BLUENRG_L2CAP_ACI_H__ + +/** + *@addtogroup L2CAP L2CAP + *@brief L2CAP layer. + *@{ + */ + +/** + *@defgroup L2CAP_Functions L2CAP functions + *@brief API for L2CAP layer. + *@{ + */ + +/** + * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. + * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request + * (accepts or rejects). + * @param conn_handle Connection handle on which the connection parameter update request has to be sent. + * @param interval_min Defines minimum value for the connection event interval in the following manner: + * connIntervalMin = interval_min x 1.25ms + * @param interval_max Defines maximum value for the connection event interval in the following manner: + * connIntervalMax = interval_max x 1.25ms + * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). + * @param timeout_multiplier Defines connection timeout parameter in the following manner: + * timeout_multiplier x 10ms. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier); +/** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param min_ce_length Minimum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_ce_length Maximum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept); + /** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept); + +/** + * @} + */ + +/** + * @defgroup L2CAP_Events L2CAP events + * @{ + */ + +/** + * This event is generated when the master responds to the L2CAP connection update request packet. + * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. + */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef __packed struct _evt_l2cap_conn_upd_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ +/** + * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. + * @li 0x01 in case of Command Reject. + */ + uint8_t code; + uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ + uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ +/** + * Result code (parameters accepted or rejected) in case of Connection Parameter Update + * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). + */ + uint16_t result; +} PACKED evt_l2cap_conn_upd_resp; + +/** + * This event is generated when the master does not respond to the connection update request + * within 30 seconds. + */ +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) +typedef __packed struct _evt_l2cap_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */ +} PACKED evt_l2cap_procedure_timeout; + +/** + * The event is given by the L2CAP layer when a connection update request is received from the slave. + * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). + */ +#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) +typedef __packed struct _evt_l2cap_conn_upd_req{ +/** + * Handle of the connection for which the connection update request has been received. + * The same handle has to be returned while responding to the event with the command + * aci_l2cap_connection_parameter_update_response(). + */ + uint16_t conn_handle; + uint8_t event_data_length; /**< Length of following data. */ +/** + * This is the identifier which associates the request to the + * response. The same identifier has to be returned by the upper + * layer in the command aci_l2cap_connection_parameter_update_response(). + */ + uint8_t identifier; + uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ + uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ +} PACKED evt_l2cap_conn_upd_req; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_updater_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with updater commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_UPDATER_ACI_H__ +#define __BLUENRG_UPDATER_ACI_H__ + +#include <ble_compiler.h> + +/** + * @defgroup Updater Updater + * @brief Updater. + * @{ + */ + +/** + * @defgroup Updater_Functions Updater functions + * @brief API for BlueNRG Updater. + * @{ + */ + +tBleStatus aci_updater_start(void); + +tBleStatus aci_updater_reboot(void); + +tBleStatus aci_get_updater_version(uint8_t *version); + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); + +tBleStatus aci_erase_blue_flag(void); + +tBleStatus aci_reset_blue_flag(void); + +tBleStatus aci_updater_erase_sector(uint32_t address); + +tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); + +tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); + +tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); + +tBleStatus aci_updater_hw_version(uint8_t *version); + +/** + * @} + */ + +/** + * @defgroup Updater_Events Updater events + * @{ + */ +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_INITIALIZED (0x0001) +typedef __packed struct _evt_blue_initialized{ + uint8_t reason_code; +} PACKED evt_blue_initialized; +/** + * @} + */ + +/** + * @} + */ + + + +#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,204 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_utils.h +* Author : AMS - VMA, RF Application Team +* Version : V1.0.1 +* Date : 03-October-2014 +* Description : Header file for BlueNRG utility functions +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + * @file bluenrg_utils.h + * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description + * + * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> +**/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLUENRG_UTILS_H +#define __BLUENRG_UTILS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ble_hal_types.h" +#include "ble_compiler.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct{ + uint8_t stack_mode; + uint8_t day; + uint8_t month; + uint8_t year; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint16_t hs_startup_time; /* In system time units*/ +} IFR_config2_TypeDef; + +/** + * Structure inside IFR for configuration options. + */ +typedef __packed struct{ + uint8_t cold_ana_act_config_table[64]; + uint8_t hot_ana_config_table[64]; + uint8_t stack_mode; + uint8_t gpio_config; + uint8_t rsrvd1[2]; + uint32_t rsrvd2[3]; + uint32_t max_conn_event_time; + uint32_t ls_crystal_period; + uint32_t ls_crystal_freq; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint8_t rsrvd3; + uint16_t hs_startup_time; /* In system time units*/ + uint8_t rsrvd4[2]; + uint32_t uid; + uint8_t rsrvd5; + uint8_t year; + uint8_t month; + uint8_t day; + uint32_t unused[5]; +} PACKED IFR_config_TypeDef; + +/* Exported constants --------------------------------------------------------*/ +extern const IFR_config_TypeDef IFR_config; + +/* Exported macros -----------------------------------------------------------*/ +#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)+1) +#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) + +/* Convert 2 digit BCD number to an integer */ +#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) + +/* Convert 2 digit number to a BCD number */ +#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) + +/** + * Return values + */ +#define BLE_UTIL_SUCCESS 0 +#define BLE_UTIL_UNSUPPORTED_VERSION 1 +#define BLE_UTIL_WRONG_IMAGE_SIZE 2 +#define BLE_UTIL_ACI_ERROR 3 +#define BLE_UTIL_CRC_ERROR 4 +#define BLE_UTIL_PARSE_ERROR 5 +#define BLE_UTIL_WRONG_VERIFY 6 + +/* Exported functions ------------------------------------------------------- */ +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int program_device(const uint8_t *fw_image, uint32_t fw_size); + +/** + * @brief Read raw data from IFR (3 64-bytes blocks). + * @param data Pointer to the buffer that will contain the read data. + * Its size must be 192 bytes. This data can be parsed by + * parse_IFR_data_config(). + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION) + */ +int read_IFR(uint8_t data[192]); + +/** + * @brief Verify raw data from IFR (3 64-bytes blocks). + * @param ifr_data Pointer to the buffer that will contain the data to verify. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) + */ +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); + +/** + * @brief Program raw data to IFR (3 64-bytes blocks). + * @param ifr_image Pointer to the buffer that will contain the data to program. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful + */ +int program_IFR(const IFR_config_TypeDef *ifr_image); + +/** + * @brief Parse IFR raw data. + * @param data Pointer to the raw data: last 64 bytes read from IFR sector. + * @param IFR_config Data structure that will be filled with parsed data. + * @retval None + */ +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); + +/** + * @brief Check for the correctness of parsed data. + * @param IFR_config Data structure filled with parsed data. + * @retval int It returns 0 if successful, or PARSE_ERROR in case data is + * not correct. + */ +int IFR_validate(IFR_config2_TypeDef *IFR_config); + +/** + * @brief Modify IFR data. (Last 64-bytes block). + * @param IFR_config Structure that contains the new parameters inside the + * IFR configuration data. + * @note It is highly recommended to parse the IFR configuration from + * a working IFR block (this should be done with parse_IFR_data_config()). + * Then it is possible to write the new parameters inside the IFR_config + * structure. + * @param data Pointer to the buffer that contains the original data. It + * will be modified according to the new data in the IFR_config + * structure. Then this data must be written in the last + * 64-byte block in the IFR. + * Its size must be 64 bytes. + * @retval None + */ +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); + +/** + * @brief Get BlueNRG hardware and firmware version + * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). + * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN + * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. + * @retval Status of the call + */ +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); + +/** + * @brief Get BlueNRG updater version + * @param version This parameter returns the updater version. If the updadter version is 0x03 + * the chip has the updater old, needs to update the bootloader. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterVersion(uint8_t *version); + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version); + +/** + * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on + * the HW bootloader related to the 32 MHz external crystal oscillator. + * @retval TRUE if the HW bootloader is already patched, FALSE otherwise + */ +uint8_t isHWBootloader_Patched(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__BLUENRG_UTILS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file bluenrg_targets.h + * @author AST / EST + * @version V0.0.1 + * @date 24-July-2015 + * @brief This header file is intended to manage the differences between + * the different supported base-boards which might mount the + * X_NUCLEO_IDB0XA1 BlueNRG BLE Expansion Board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent from recursive inclusion --------------------------------*/ +#ifndef _BLUENRG_TARGETS_H_ +#define _BLUENRG_TARGETS_H_ + +#if !defined(BLUENRG_PIN_SPI_MOSI) +#define BLUENRG_PIN_SPI_MOSI (D11) +#endif +#if !defined(BLUENRG_PIN_SPI_MISO) +#define BLUENRG_PIN_SPI_MISO (D12) +#endif +#if !defined(BLUENRG_PIN_SPI_nCS) +#define BLUENRG_PIN_SPI_nCS (A1) +#endif +#if !defined(BLUENRG_PIN_SPI_RESET) +#define BLUENRG_PIN_SPI_RESET (D7) +#endif +#if !defined(BLUENRG_PIN_SPI_IRQ) +#define BLUENRG_PIN_SPI_IRQ (A0) +#endif + +/* NOTE: Refer to README for further details regarding BLUENRG_PIN_SPI_SCK */ +#if !defined(BLUENRG_PIN_SPI_SCK) +#define BLUENRG_PIN_SPI_SCK (D3) +#endif + +/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv) + * Mode 0x01: slave or master, 1 connection + * Mode 0x02: slave or master, 1 connection + * Mode 0x03: master/slave, 8 connections + * Mode 0x04: master/slave, 4 connections (simultaneous scanning and advertising) + * Check Table 285 of + * BlueNRG-MS Bluetooth LE stack application command interface (ACI) User Manual (UM1865) at st.com + */ +#if !defined(BLUENRG_STACK_MODE) +#define BLUENRG_STACK_MODE (0x04) +#endif + +#endif // _BLUENRG_TARGTES_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef _BTLE_H_ +#define _BTLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "bluenrg_aci.h" +#include "ble_hci_const.h" +#include "bluenrg_hal_aci.h" +#include "stm32_bluenrg_ble.h" +#include "bluenrg_gap.h" +#include "bluenrg_gatt_server.h" + +extern uint16_t g_gap_service_handle; +extern uint16_t g_appearance_char_handle; +extern uint16_t g_device_name_char_handle; +extern uint16_t g_preferred_connection_parameters_char_handle; + +void btleInit(void); +void SPI_Poll(void); +void User_Process(void); +void setConnectable(void); +void setVersionString(uint8_t hwVersion, uint16_t fwVersion); +const char* getVersionString(void); +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type); + + +extern int btle_handler_pending; +extern void btle_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.h + * @author CL + * @version V1.0.1 + * @date 15-June-2014 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_BLUENRG_BLE_H +#define __STM32_BLUENRG_BLE_H + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdint.h> +#include "ble_gp_timer.h" +#include "ble_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup X-NUCLEO-IDB04A1 + * @{ + */ + +/** @addtogroup STM32_BLUENRG_BLE + * @{ + */ + +/** @defgroup STM32_BLUENRG_BLE_Exported_Functions + * @{ + */ + +// FIXME: add prototypes for BlueNRG here +void BlueNRG_RST(void); +uint8_t BlueNRG_DataPresent(void); +void BlueNRG_HW_Bootloader(void); +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size); +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, + uint8_t Nb_bytes1, + uint8_t Nb_bytes2); +void Clear_SPI_EXTI_Flag(void); + +void print_csv_time(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_BLUENRG_BLE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_debug.h" + +#ifndef __PAYLOAD_H__ +#define __PAYLOAD_H__ + +class UnitPayload +{ +public: + uint8_t length; + uint8_t id; + uint8_t *data; + uint8_t *idptr; + + + + void set_length(uint8_t l) { + length=l; + } + + void set_id(uint8_t i) { + id=i; + } + + void set_data(uint8_t* data1) { + for(int j=0;j<length;j++) + { + data[j]=data1[j]; + } + } + + uint8_t get_length() { + return length; + } + + uint8_t get_id() { + return id; + } + + uint8_t* get_data() { + return data; + } + +}; + +class Payload { + UnitPayload *payload; + int stringLength; + int payloadUnitCount; + +public: + Payload(const uint8_t *tokenString, uint8_t string_ength); + Payload(); + ~Payload(); + uint8_t getPayloadUnitCount(); + + uint8_t getIDAtIndex(int index); + uint8_t getLengthAtIndex(int index); + uint8_t* getDataAtIndex(int index); + int8_t getInt8AtIndex(int index); + uint16_t getUint16AtIndex(int index); + uint8_t* getSerializedAdDataAtIndex(int index); +}; + + +class PayloadUnit { +private: + uint8_t* lenPtr; + uint8_t* adTypePtr; + uint8_t* dataPtr; + +public: + PayloadUnit() { + lenPtr = NULL; + adTypePtr = NULL; + dataPtr = NULL; + } + + PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { + lenPtr = len; + adTypePtr = adType; + dataPtr = data; + } + + void setLenPtr(uint8_t *len) { + lenPtr = len; + } + + void setAdTypePtr(uint8_t *adType) { + adTypePtr = adType; + } + + void setDataPtr(uint8_t *data) { + dataPtr = data; + } + + uint8_t* getLenPtr() { + return lenPtr; + } + + uint8_t* getAdTypePtr() { + return adTypePtr; + } + + uint8_t* getDataPtr() { + return dataPtr; + } + + void printDataAsHex() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("0x%x ", dataPtr[i]); + } + PRINTF("\n"); + } + + void printDataAsString() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("%c", dataPtr[i]); + } + PRINTF("\n"); + } + +}; + +class PayloadPtr { +private: + PayloadUnit *unit; + int payloadUnitCount; +public: + PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + int stringLength = string_ength; + payloadUnitCount = 0; + + int index = 0; + while(index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + // allocate memory to unit + unit = new PayloadUnit[payloadUnitCount]; + int i = 0; + int nextUnitOffset = 0; + + while(i<payloadUnitCount) { + unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); + unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); + unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); + + nextUnitOffset += *unit[i].getLenPtr()+1; + i++; + + } + } + + PayloadUnit getUnitAtIndex(int index) { + return unit[index]; + } + + int getPayloadUnitCount() { return payloadUnitCount; } + + ~PayloadPtr() { + if(unit) delete[] unit; + + unit = NULL; + } +}; + +#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include "ble_status.h" +#include "ble_hal_types.h" + +#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do {\ + uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ + }while(0) + + +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); + +#endif // __UTIL_H__ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/mbed_lib.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "bluenrg", + "target_overrides": { + "K64F": { + "target.macros_add": ["BLUENRG_PIN_SPI_SCK=D13"] + }, + "DISCO_L475VG_IOT01A": { + "target.macros_add": ["BLUENRG_PIN_SPI_MOSI=PC_12", + "BLUENRG_PIN_SPI_MISO=PC_11", + "BLUENRG_PIN_SPI_nCS=PD_13", + "BLUENRG_PIN_SPI_RESET=PA_8", + "BLUENRG_PIN_SPI_IRQ=PE_6", + "BLUENRG_PIN_SPI_SCK=PC_10"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,37 @@ +{ + "name": "x-nucleo-idb0xa1", + "version": "2.2.0", + "description": "ST driver for the mbed BLE API.", + "keywords": [ + "expansion", + "board", + "x-nucleo", + "nucleo", + "ST", + "STM", + "Bluetooth", + "BLE" + ], + "author": "Andrea Palmieri", + "repository": { + "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git", + "type": "git" + }, + "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "extraIncludes": [ + "x-nucleo-idb0xa1", + "x-nucleo-idb0xa1/utils", + "x-nucleo-idb0xa1/platform", + "x-nucleo-idb0xa1/bluenrg-hci" + ], + "dependencies": { + "mbed-drivers": ">=0.11.3", + "ble": "^2.7.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,474 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.cpp + * @author STMicroelectronics + * @brief Implementation of BLEDeviceInstanceBase + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGDevice + * @brief BlueNRG BLE_API Device Adaptation + * @{ + */ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGDevice.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" + +#include "btle.h" +#include "ble_utils.h" +#include "ble_osal.h" + +#include "ble_debug.h" +#include "stm32_bluenrg_ble.h" + +extern "C" { + #include "ble_hci.h" + #include "bluenrg_utils.h" +} + +#define HEADER_SIZE 5 +#define MAX_BUFFER_SIZE 255 + +/** + * The singleton which represents the BlueNRG transport for the BLEDevice. + * + * See file 'bluenrg_targets.h' for details regarding the peripheral pins used! + */ +#include "bluenrg_targets.h" + +BlueNRGDevice bluenrgDeviceInstance(BLUENRG_PIN_SPI_MOSI, + BLUENRG_PIN_SPI_MISO, + BLUENRG_PIN_SPI_SCK, + BLUENRG_PIN_SPI_nCS, + BLUENRG_PIN_SPI_RESET, + BLUENRG_PIN_SPI_IRQ); + +/** +* BLE-API requires an implementation of the following function in order to +* obtain its transport handle. +*/ +BLEInstanceBase * +createBLEInstance(void) +{ + return (&bluenrgDeviceInstance); +} + +/**************************************************************************/ +/** + @brief Constructor + * @param mosi mbed pin to use for MOSI line of SPI interface + * @param miso mbed pin to use for MISO line of SPI interface + * @param sck mbed pin to use for SCK line of SPI interface + * @param cs mbed pin to use for not chip select line of SPI interface + * @param rst mbed pin to use for BlueNRG reset + * @param irq mbed pin for BlueNRG IRQ +*/ +/**************************************************************************/ +BlueNRGDevice::BlueNRGDevice(PinName mosi, + PinName miso, + PinName sck, + PinName cs, + PinName rst, + PinName irq) : + isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq) +{ + // Setup the spi for 8 bit data, low clock polarity, + // 1-edge phase, with an 8MHz clock rate + spi_.format(8, 0); + spi_.frequency(8000000); + + // Deselect the BlueNRG chip by keeping its nCS signal high + nCS_ = 1; + + wait_us(500); + + // Prepare communication between the host and the BlueNRG SPI interface + HCI_Init(); + + // Set the interrupt handler for the device + irq_.mode(PullDown); // set irq mode + irq_.rise(&HCI_Isr); +} + +/**************************************************************************/ +/** + @brief Destructor +*/ +/**************************************************************************/ +BlueNRGDevice::~BlueNRGDevice(void) +{ +} + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param hw_version The HW version is written to this parameter + * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise + */ +uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version) +{ + uint8_t status; + + status = getBlueNRGUpdaterHWVersion(hw_version); + + return (status); +} + +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns BLE_STATUS_SUCCESS on success, or a number + * not equal to 0 in case of error + * (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size) +{ + int status = program_device(fw_image, fw_size); + + return (status); +} + + +/** + * @brief Initialises anything required to start using BLE + * @param[in] instanceID + * The ID of the instance to initialize. + * @param[in] callback + * A callback for when initialization completes for a BLE + * instance. This is an optional parameter set to NULL when not + * supplied. + * + * @return BLE_ERROR_NONE if the initialization procedure was started + * successfully. + */ +ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback) +{ + if (isInitialized) { + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_ALREADY_INITIALIZED + }; + callback.call(&context); + return BLE_ERROR_ALREADY_INITIALIZED; + } + + // Init the BlueNRG/BlueNRG-MS stack + btleInit(); + + isInitialized = true; + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_NONE + }; + callback.call(&context); + + return BLE_ERROR_NONE; +} + + +/** + @brief Resets the BLE HW, removing any existing services and + characteristics + @param[in] void + @returns void +*/ +void BlueNRGDevice::reset(void) +{ + /* Reset BlueNRG SPI interface. Hold reset line to 0 for 1500us */ + rst_ = 0; + wait_us(1500); + rst_ = 1; + + /* Wait for the radio to come back up */ + wait_us(5000); +} + +/*! + @brief Wait for any BLE Event like BLE Connection, Read Request etc. + @param[in] void + @returns char * +*/ +void BlueNRGDevice::waitForEvent(void) +{ + bool must_return = false; + + do { + bluenrgDeviceInstance.processEvents(); + + if(must_return) return; + + __WFE(); /* it is recommended that SEVONPEND in the + System Control Register is NOT set */ + must_return = true; /* after returning from WFE we must guarantee + that conrol is given back to main loop before next WFE */ + } while(true); + +} + +/*! + @brief get GAP version + @brief Get the BLE stack version information + @param[in] void + @returns char * + @returns char * +*/ +const char *BlueNRGDevice::getVersion(void) +{ + return getVersionString(); +} + +/**************************************************************************/ +/*! + @brief get reference to GAP object + @param[in] void + @returns Gap& +*/ +/**************************************************************************/ +Gap &BlueNRGDevice::getGap() +{ + return BlueNRGGap::getInstance(); +} + +const Gap &BlueNRGDevice::getGap() const +{ + return BlueNRGGap::getInstance(); +} + +/**************************************************************************/ +/*! + @brief get reference to GATT server object + @param[in] void + @returns GattServer& +*/ +/**************************************************************************/ +GattServer &BlueNRGDevice::getGattServer() +{ + return BlueNRGGattServer::getInstance(); +} + +const GattServer &BlueNRGDevice::getGattServer() const +{ + return BlueNRGGattServer::getInstance(); +} + +/**************************************************************************/ +/*! + @brief shut down the BLE device + @param[out] error if any +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::shutdown(void) { + PRINTF("BlueNRGDevice::reset\n"); + + if (!isInitialized) { + return BLE_ERROR_INITIALIZATION_INCOMPLETE; + } + + /* Reset the BlueNRG device first */ + reset(); + + /* Shutdown the BLE API and BlueNRG glue code */ + ble_error_t error; + + /* GattServer instance */ + error = BlueNRGGattServer::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* GattClient instance */ + error = BlueNRGGattClient::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* Gap instance */ + error = BlueNRGGap::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + isInitialized = false; + + PRINTF("BlueNRGDevice::reset complete\n"); + return BLE_ERROR_NONE; + +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size) +{ + uint16_t byte_count; + uint8_t len = 0; + uint8_t char_ff = 0xff; + volatile uint8_t read_char; + + uint8_t i = 0; + volatile uint8_t tmpreg; + + uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00}; + uint8_t header_slave[HEADER_SIZE]; + + /* Select the chip */ + nCS_ = 0; + + /* Read the header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = (uint8_t)(tmpreg); + } + + if (header_slave[0] == 0x02) { + /* device is ready */ + byte_count = (header_slave[4]<<8)|header_slave[3]; + + if (byte_count > 0) { + + /* avoid to read more data that size of the buffer */ + if (byte_count > buff_size){ + byte_count = buff_size; + } + + for (len = 0; len < byte_count; len++){ + read_char = spi_.write(char_ff); + buffer[len] = read_char; + } + } + } + /* Release CS line to deselect the chip */ + nCS_ = 1; + + // Add a small delay to give time to the BlueNRG to set the IRQ pin low + // to avoid a useless SPI read at the end of the transaction + for(volatile int i = 0; i < 2; i++)__NOP(); + +#ifdef PRINT_CSV_FORMAT + if (len > 0) { + print_csv_time(); + for (int i=0; i<len; i++) { + PRINT_CSV(" %02x", buffer[i]); + } + PRINT_CSV("\n"); + } +#endif + + return len; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRGDevice::spiWrite(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t result = 0; + uint32_t i; + volatile uint8_t tmpreg; + + unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00}; + + disable_irq(); + + /* CS reset */ + nCS_ = 0; + + /* Exchange header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = tmpreg; + } + + if (header_slave[0] == 0x02) { + /* SPI is ready */ + if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { + + /* Buffer is big enough */ + for (i = 0; i < Nb_bytes1; i++) { + spi_.write(*(data1 + i)); + } + for (i = 0; i < Nb_bytes2; i++) { + spi_.write(*(data2 + i)); + } + } else { + /* Buffer is too small */ + result = -2; + } + } else { + /* SPI is not ready */ + result = -1; + } + + /* Release CS line */ + //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); + nCS_ = 1; + + enable_irq(); + + return result; +} + +bool BlueNRGDevice::dataPresent() +{ + return (irq_ == 1); +} + +void BlueNRGDevice::disable_irq() +{ + irq_.disable_irq(); +} + +void BlueNRGDevice::enable_irq() +{ + irq_.enable_irq(); +} + +void BlueNRGDevice::processEvents() { + btle_handler(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,68 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattClient.h" + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + uuid = uuidIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + + void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) { + lastHandle = lastHandleIn; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1477 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file BlueNRGGap.cpp + * @author STMicroelectronics + * @brief Implementation of BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGap + * @brief BlueNRG BLE_API GAP Adaptation + * @{ + */ + +#include "BlueNRGDevice.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_payload.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/* + * Utility to process GAP specific events (e.g., Advertising timeout) + */ +void BlueNRGGap::Process(void) +{ + if(AdvToFlag) { + AdvToFlag = false; + stopAdvertising(); + } + + if(ScanToFlag) { + ScanToFlag = false; + stopScan(); + } +} + +/**************************************************************************/ +/*! + @brief Sets the advertising parameters and payload for the device. + Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API + + @params[in] advData + The primary advertising data payload + @params[in] scanResponse + The optional Scan Response payload if the advertising + type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED + in \ref GapAdveritinngParams + + @returns \ref ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @retval BLE_ERROR_BUFFER_OVERFLOW + The proposed action would cause a buffer overflow. All + advertising payloads must be <= 31 bytes, for example. + + @retval BLE_ERROR_NOT_IMPLEMENTED + A feature was requested that is not yet supported in the + nRF51 firmware or hardware. + + @retval BLE_ERROR_PARAM_OUT_OF_RANGE + One of the proposed values is outside the valid range. + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) +{ + PRINTF("BlueNRGGap::setAdvertisingData\n\r"); + /* Make sure we don't exceed the advertising payload length */ + if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + PRINTF("Exceeded the advertising payload length\n\r"); + return BLE_ERROR_BUFFER_OVERFLOW; + } + + /* Make sure we have a payload! */ + if (advData.getPayloadLen() != 0) { + PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); + + /* Align the GAP Service Appearance Char value coherently + This setting is duplicate (see below GapAdvertisingData::APPEARANCE) + since BLE API has an overloaded function for appearance + */ + STORE_LE_16(deviceAppearance, advData.getAppearance()); + setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0])); + + + for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { + loadPtr.getUnitAtIndex(index); + + PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); + PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); + + switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { + /**< TX Power Level (in dBm) */ + case GapAdvertisingData::TX_POWER_LEVEL: + { + PRINTF("Advertising type: TX_POWER_LEVEL\n\r"); + int8_t enHighPower = 0; + int8_t paLevel = 0; + + int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); + tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); +#ifdef DEBUG + PRINTF("dbm=%d, ret=%d\n\r", dbm, ret); + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); +#endif + if(ret == BLE_STATUS_SUCCESS) { + aci_hal_set_tx_power_level(enHighPower, paLevel); + } + break; + } + /**< Appearance */ + case GapAdvertisingData::APPEARANCE: + { + PRINTF("Advertising type: APPEARANCE\n\r"); + + GapAdvertisingData::Appearance appearanceP; + memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2); + + PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]); + /* Align the GAP Service Appearance Char value coherently */ + setAppearance(appearanceP); + break; + } + + } // end switch + + } //end for + + } + + // update the advertising data in the shield if advertising is running + if (state.advertising == 1) { + tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS != ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload()); + if (ret) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + } + + _advData = advData; + _scanResponse = scanResponse; + + return BLE_ERROR_NONE; +} + +/* + * Utility to set ADV timeout flag + */ +void BlueNRGGap::setAdvToFlag(void) { + AdvToFlag = true; + signalEventsToProcess(); +} + +/* + * ADV timeout callback + */ +#ifdef AST_FOR_MBED_OS +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().stopAdvertising(); +} +#else +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().setAdvToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getAdvTimeout(); + t.detach(); /* disable the callback from the timeout */ +} +#endif /* AST_FOR_MBED_OS */ + +/* + * Utility to set SCAN timeout flag + */ +void BlueNRGGap::setScanToFlag(void) { + ScanToFlag = true; + signalEventsToProcess(); +} + +static void scanTimeoutCB(void) +{ + BlueNRGGap::getInstance().setScanToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getScanTimeout(); + t.detach(); /* disable the callback from the timeout */ +} + +/**************************************************************************/ +/*! + @brief Starts the BLE HW, initialising any services that were + added before this function was called. + + @param[in] params + Basic advertising details, including the advertising + delay, timeout and how the device should be advertised + + @note All services must be added before calling this function! + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ + +ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) +{ + tBleStatus ret; + int err; + + /* Make sure we support the advertising type */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { + /* ToDo: This requires a proper security implementation, etc. */ + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /* Check interval range */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { + /* Min delay is slightly longer for unconnectable devices */ + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } else { + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } + + /* Check timeout is zero for Connectable Directed */ + if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { + /* Timeout must be 0 with this type, although we'll never get here */ + /* since this isn't implemented yet anyway */ + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* Check timeout for other advertising types */ + if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && + (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* + * Advertising filter policy setting + * FIXME: the Security Manager should be implemented + */ + AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode(); + if(mode != ADV_POLICY_IGNORE_WHITELIST) { + ret = aci_gap_configure_whitelist(); + if(ret != BLE_STATUS_SUCCESS) { + PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret); + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } + + uint8_t advFilterPolicy = NO_WHITE_LIST_USE; + switch(mode) { + case ADV_POLICY_FILTER_SCAN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN; + break; + case ADV_POLICY_FILTER_CONN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN; + break; + case ADV_POLICY_FILTER_ALL_REQS: + advFilterPolicy = WHITE_LIST_FOR_ALL; + break; + default: + advFilterPolicy = NO_WHITE_LIST_USE; + break; + } + + /* Check the ADV type before setting scan response data */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED || + params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) { + + /* set scan response data */ + PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen()); + ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS!=ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + } else { + hci_le_set_scan_resp_data(0, NULL); + } + + setAdvParameters(); + PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType()); + + err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload()); + + if (err) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + + tBDAddr dummy_addr = { 0 }; + uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval; + uint16_t advIntervalMax = advIntervalMin + 1; + + err = hci_le_set_advertising_parameters( + advIntervalMin, + advIntervalMax, + params.getAdvertisingType(), + addr_type, + 0x00, + dummy_addr, + /* all channels */ 7, + advFilterPolicy + ); + + if (err) { + PRINTF("impossible to set advertising parameters\n\r"); + PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1); + PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy); + return BLE_ERROR_INVALID_PARAM; + } + + err = hci_le_set_advertise_enable(0x01); + if (err) { + PRINTF("impossible to start advertising\n\r"); + return BLE_ERROR_UNSPECIFIED; + } + + if(params.getTimeout() != 0) { + PRINTF("!!! attaching adv to!!!\n"); +#ifdef AST_FOR_MBED_OS + minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000)); +#else + advTimeout.attach(advTimeoutCB, params.getTimeout()); +#endif + } + + return BLE_ERROR_NONE; + +} + + +/**************************************************************************/ +/*! + @brief Stops the BLE HW and disconnects from any devices + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::stopAdvertising(void) +{ + if(state.advertising == 1) { + + int err = hci_le_set_advertise_enable(0); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + PRINTF("Advertisement stopped!!\n\r") ; + //Set GapState_t::advertising state + state.advertising = 0; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason) +{ + tBleStatus ret; + + ret = aci_gap_terminate(connectionHandle, reason); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_COMMAND_DISALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason) +{ + return disconnect(m_connectionHandle, reason); +} + +/**************************************************************************/ +/*! + @brief Sets the 16-bit connection handle + + @param[in] conn_handle + Connection Handle which is set in the Gap Instance + + @returns void +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionHandle(uint16_t conn_handle) +{ + m_connectionHandle = conn_handle; +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit connection handle + + @param[in] void + + @returns uint16_t + Connection Handle of the Gap Instance +*/ +/**************************************************************************/ +uint16_t BlueNRGGap::getConnectionHandle(void) +{ + return m_connectionHandle; +} + +/**************************************************************************/ +/*! + @brief Sets the BLE device address. SetAddress will reset the BLE + device and re-initialize BTLE. Will not start advertising. + + @param[in] type + Type of Address + + @param[in] address[6] + Value of the Address to be set + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address) +{ + if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if(type == BLEProtocol::AddressType::PUBLIC){ + tBleStatus ret = aci_hal_write_config_data( + CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + address + ); + if(ret != BLE_STATUS_SUCCESS) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } else if (type == BLEProtocol::AddressType::RANDOM_STATIC) { + // ensure that the random static address is well formed + if ((address[5] & 0xC0) != 0xC0) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // thanks to const correctness of the API ... + tBDAddr random_address = { 0 }; + memcpy(random_address, address, sizeof(random_address)); + int err = hci_le_set_random_address(random_address); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // It is not possible to get the bluetooth address when it is set + // store it locally in class data member + memcpy(bdaddr, address, sizeof(bdaddr)); + } else { + // FIXME random addresses are not supported yet + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + // if we're here then the address was correctly set + // commit it inside the addr_type + addr_type = type; + isSetAddress = true; + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Returns boolean if the address of the device has been set + or not + + @returns bool + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +bool BlueNRGGap::getIsSetAddress() +{ + return isSetAddress; +} + +/**************************************************************************/ +/*! + @brief Returns the address of the device if set + + @returns Pointer to the address if Address is set else NULL + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) +{ + uint8_t bdaddr[BDADDR_SIZE]; + uint8_t data_len_out; + + // precondition, check that pointers in input are valid + if (typeP == NULL || address == NULL) { + return BLE_ERROR_INVALID_PARAM; + } + + if (addr_type == BLEProtocol::AddressType::PUBLIC) { + tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr); + if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) { + return BLE_ERROR_UNSPECIFIED; + } + } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) { + // FIXME hci_read_bd_addr and + // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1 + // does not work, use the address stored in class data member + memcpy(bdaddr, this->bdaddr, sizeof(bdaddr)); + } else { + // FIXME: should be implemented with privacy features + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + *typeP = addr_type; + memcpy(address, bdaddr, BDADDR_SIZE); + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief obtains preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + + if (!g_preferred_connection_parameters_char_handle) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // Peripheral preferred connection parameters are an array of 4 uint16_t + uint8_t parameters_packed[parameter_size * 4]; + uint16_t bytes_read = 0; + + tBleStatus err = aci_gatt_read_handle_value( + g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE, + sizeof(parameters_packed), + &bytes_read, + parameters_packed + ); + + PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read); + + // check that the read succeed and the result have the expected length + if (err || bytes_read != sizeof(parameters_packed)) { + return BLE_ERROR_UNSPECIFIED; + } + + // memcpy field by field + memcpy(¶ms->minConnectionInterval, parameters_packed, parameter_size); + memcpy(¶ms->maxConnectionInterval, ¶meters_packed[parameter_size], parameter_size); + memcpy(¶ms->slaveLatency, ¶meters_packed[2 * parameter_size], parameter_size); + memcpy(¶ms->connectionSupervisionTimeout, ¶meters_packed[3 * parameter_size], parameter_size); + + return BLE_ERROR_NONE; +} + + +/**************************************************************************/ +/*! + @brief sets preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + uint8_t parameters_packed[parameter_size * 4]; + + // ensure that parameters are correct + // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC + if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) && + params->minConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) && + params->maxConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (params->slaveLatency > 0x01F3) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) && + params->connectionSupervisionTimeout != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // copy the parameters inside the byte array + memcpy(parameters_packed, ¶ms->minConnectionInterval, parameter_size); + memcpy(¶meters_packed[parameter_size], ¶ms->maxConnectionInterval, parameter_size); + memcpy(¶meters_packed[2 * parameter_size], ¶ms->slaveLatency, parameter_size); + memcpy(¶meters_packed[3 * parameter_size], ¶ms->connectionSupervisionTimeout, parameter_size); + + tBleStatus err = aci_gatt_update_char_value( + g_gap_service_handle, + g_preferred_connection_parameters_char_handle, + /* offset */ 0, + sizeof(parameters_packed), + parameters_packed + ); + + if (err) { + PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ; + switch (err) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief updates preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) +{ + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(gapRole == Gap::CENTRAL) { + ret = aci_gap_start_connection_update(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout, + CONN_L1, CONN_L2); + } else { + ret = aci_l2cap_connection_parameter_update_request(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout); + } + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case ERR_COMMAND_DISALLOWED: + case BLE_STATUS_NOT_ALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sets the Device Name Characteristic + + @param[in] deviceName + pointer to device name to be set + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) +{ + tBleStatus ret; + uint8_t nameLen = 0; + + nameLen = strlen((const char*)deviceName); + PRINTF("DeviceName Size=%d\n\r", nameLen); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_device_name_char_handle, + 0, + nameLen, + deviceName); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Gets the Device Name Characteristic + + @param[in] deviceName + pointer to device name + + @param[in] lengthP + pointer to device name length + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) +{ + tBleStatus ret; + + ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + *lengthP, + (uint16_t *)lengthP, + deviceName); + PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } +} + +/**************************************************************************/ +/*! + @brief Sets the Device Appearance Characteristic + + @param[in] appearance + device appearance + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance) +{ + tBleStatus ret; + uint8_t deviceAppearance[2]; + + STORE_LE_16(deviceAppearance, appearance); + PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_appearance_char_handle, + 0, 2, (uint8_t *)deviceAppearance); + if (BLE_STATUS_SUCCESS == ret){ + return BLE_ERROR_NONE; + } + + PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Gets the Device Appearance Characteristic + + @param[in] appearance + pointer to device appearance value + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) +{ + tBleStatus ret; + uint16_t lengthP = 2; + + ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + lengthP, + &lengthP, + (uint8_t*)appearanceP); + PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + +} + +GapScanningParams* BlueNRGGap::getScanningParams(void) +{ + return &_scanningParams; +} + +static void makeConnection(void) +{ + BlueNRGGap::getInstance().createConnection(); +} + +void BlueNRGGap::Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI) +{ + switch (reason) { + case DEVICE_FOUND: + { + GapAdvertisingParams::AdvertisingType_t type; + bool isScanResponse = false; + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * Private Random Address + * => scan_results = FALSE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type); + if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV || + (addr_type == RESOLVABLE_PRIVATE_ADDR || + addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) { + return; + } + + switch(adv_type) { + case ADV_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + break; + case ADV_DIRECT_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED; + break; + case ADV_SCAN_IND: + case SCAN_RSP: + type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED; + isScanResponse = true; + break; + case ADV_NONCONN_IND: + type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED; + break; + default: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + } + + PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n", + *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + if(!_connecting) { + processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data); + } + PRINTF("!!!After processAdvertisementReport\n\r"); + } + break; + + case DISCOVERY_COMPLETE: + // The discovery is complete. If this is due to a stop scanning (i.e., the device + // we are interested in has been found) and a connection has been requested + // then we start the device connection. + PRINTF("DISCOVERY_COMPLETE\n\r"); + _scanning = false; + + // Since the DISCOVERY_COMPLETE event can be received during the scanning interval, + // we need to delay the starting of connection + uint16_t delay = (_scanningParams.getInterval()*0.625); + +#ifdef AST_FOR_MBED_OS + if(_connecting) { + minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay)); + } +#else + Clock_Wait(delay); + if(_connecting) { + makeConnection(); + } +#endif /* AST_FOR_MBED_OS */ + + break; + } +} + +ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) +{ + + tBleStatus ret = BLE_STATUS_SUCCESS; + + // Stop ADV before scanning + /* + if (state.advertising == 1) { + stopAdvertising(); + } + */ + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * White List is empty + * => scan operation = FAILURE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + uint8_t whiteListSize = whitelistAddresses.size; + if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + ret = btleStartRadioScan(scanningParams.getActiveScanning(), + scanningParams.getInterval(), + scanningParams.getWindow(), + addr_type); + + PRINTF("Scanning...\n\r"); + PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000); + PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000); + //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval()); + //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1); + //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2); + if (BLE_STATUS_SUCCESS == ret){ + PRINTF("Observation Procedure Started\n"); + _scanning = true; + + if(scanningParams.getTimeout() != 0) { + PRINTF("!!! attaching scan to!!!\n"); + scanTimeout.attach(scanTimeoutCB, scanningParams.getTimeout()); + } + + return BLE_ERROR_NONE; + } + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + switch (ret) { + case BLE_STATUS_INVALID_CID: + PRINTF("Observation Procedure not implemented!!!\n\r"); + return BLE_ERROR_NOT_IMPLEMENTED; + default: + PRINTF("Observation Procedure failed (0x%02X)\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } + +} + +ble_error_t BlueNRGGap::stopScan() { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(_scanning) { + ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC); + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Discovery Procedure Terminated\n"); + return BLE_ERROR_NONE; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief set Tx power level + @param[in] txPower Transmission Power level + @returns ble_error_t +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setTxPower(int8_t txPower) +{ + tBleStatus ret; + + int8_t enHighPower = 0; + int8_t paLevel = 0; + + ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + ret = aci_hal_set_tx_power_level(enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief get permitted Tx power values + @param[in] values pointer to pointer to permitted power values + @param[in] num number of values +*/ +/**************************************************************************/ +void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { + static const int8_t permittedTxValues[] = { + -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8 + }; + + *valueArrayPP = permittedTxValues; + *countP = sizeof(permittedTxValues) / sizeof(int8_t); +} + +/**************************************************************************/ +/*! + @brief Set advertising parameters according to the current state + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setAdvParameters(void) +{ + uint32_t advIntMS; + + if(state.connected == 1) { + advIntMS = (conn_min_interval*1.25)-GUARD_INT; + advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS); + + PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval); + } else { + advInterval = _advParams.getIntervalInADVUnits(); + } +} + +/**************************************************************************/ +/*! + @brief Set connection parameters according to the current state (ADV and/or SCAN) + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionParameters(void) +{ + if (state.connected == 1) { + + PRINTF("state.connected=1\r\n"); + scanInterval = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(conn_min_interval*1.25); + scanWindow = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(((conn_min_interval*1.25)/100)*60); // scanWin ~= 60%(scanInt) + + } else if (state.advertising == 1) { + + if (_scanningParams.getInterval() < advInterval) { + PRINTF("state.adv=1 scanInterval<advInterval\r\n"); + scanInterval = advInterval; + scanWindow = advInterval; + } else { + PRINTF("state.adv=1 scanInterval>=advInterval\r\n"); + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + } + + if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms + conn_min_interval = MAX_INT_CONN; + conn_max_interval = MAX_INT_CONN; + } else { + conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + } + + } else { + + PRINTF("state.adv = 0\r\n"); + + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) || + SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms + conn_min_interval = DEF_INT_CONN; + conn_max_interval = DEF_INT_CONN; + } else { + conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + } + } + PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval)); + PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow)); + PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25)); + PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25)); + +} + +ble_error_t BlueNRGGap::createConnection () +{ + tBleStatus ret; + + /* + Before creating connection, set parameters according + to previous or current procedure (ADV and/or SCAN) + */ + setConnectionParameters(); + + /* + Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, + Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max + */ + ret = aci_gap_create_connection(scanInterval, + scanWindow, + _peerAddrType, + (unsigned char*)_peerAddr, + addr_type, + conn_min_interval, conn_max_interval, 0, + SUPERV_TIMEOUT, CONN_L1, CONN_L1); + + //_connecting = false; + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Connection started.\n"); + _connecting = false; + return BLE_ERROR_NONE; + } +} + +ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) +{ + /* avoid compiler warnings about unused variables */ + (void)connectionParams; + + setScanParams(scanParams->getInterval(), + scanParams->getWindow(), + scanParams->getTimeout(), + scanParams->getActiveScanning() + ); + + // Save the peer address + for(int i=0; i<BDADDR_SIZE; i++) { + _peerAddr[i] = peerAddr[i]; + } + _peerAddrType = peerAddrType; + + _connecting = true; + + if(_scanning) { + stopScan(); + } else { + PRINTF("Calling createConnection from connect()\n\r"); + return createConnection(); + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the advertising policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode) +{ + advertisingPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the scanning policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode) +{ + scanningPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Get the current advertising policy filter mode. + + @returns The advertising policy filter mode. +*/ +/**************************************************************************/ +Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const +{ + return advertisingPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Get the current scanning policy filter mode. + + @returns The scanning policy filter mode. + +*/ +/**************************************************************************/ +Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const +{ + return scanningPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGap's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::reset(void) +{ + PRINTF("BlueNRGGap::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (Gap::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + AdvToFlag = false; + ScanToFlag = false; + + /* Clear derived class members */ + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + return BLE_ERROR_NONE; +} + +void BlueNRGGap::setConnectionInterval(uint16_t interval) { + conn_min_interval = interval; + conn_max_interval = interval; +} + +Gap::Role_t BlueNRGGap::getGapRole(void) +{ + return (gapRole); +} + +void BlueNRGGap::setGapRole(Gap::Role_t role) +{ + gapRole = role; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,403 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTClient + * @brief BlueNRG BLE_API GattClient Adaptation + * @{ + */ + +#include "BlueNRGGattClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +#include <new> +#include <assert.h> + +ble_error_t BlueNRGGattClient::createGattConnectionClient(Gap::Handle_t connectionHandle) +{ + if(MAX_ACTIVE_CONNECTIONS <= _numConnections) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + for(uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + + if(_connectionPool[i] == NULL) { + BlueNRGGattConnectionClient *gattConnectionClient = new(std::nothrow) BlueNRGGattConnectionClient(this, connectionHandle); + + if (gattConnectionClient == NULL) { + return BLE_ERROR_NO_MEM; + } + + _connectionPool[i] = gattConnectionClient; + _connectionPool[i]->onServiceDiscoveryTermination(terminationCallback); + _numConnections++; + + PRINTF("createGattConnectionClient: _connectionPool index=%d\r\n", i); + PRINTF("createGattConnectionClient: succesfully added new gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + break; + } + } + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattClient::removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason) +{ + + PRINTF("removeGattConnectionClient: connectionHandle=%d reason=0x%x\r\n", connectionHandle, reason); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("removeGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("removeGattConnectionClient: Found gattConnectionClient\r\n"); + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + PRINTF("removeGattConnectionClient: succesfully removed gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + + break; + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + + return BLE_ERROR_NONE; +} + +BlueNRGGattConnectionClient * BlueNRGGattClient::getGattConnectionClient(Gap::Handle_t connectionHandle) { + PRINTF("getGattConnectionClient\r\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("getGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("getGattConnectionClient: Found gattConnectionClient\r\n"); + return _connectionPool[i]; + } + } + + return NULL; +} + +void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code) { + + if(error_code != BLE_STATUS_SUCCESS) { + return; + } + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->gattProcedureCompleteCB(error_code); +} + +void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServicesCB(event_data_length, + attribute_data_length, + attribute_data_list); +} + +void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServiceCB(event_data_length, + handles_info_list); +} + +ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->findServiceChars(); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharsCB(event_data_length, + handle_value_pair_length, + handle_value_pair); +} + +void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharByUUIDCB(event_data_length, + attr_handle, + attr_value); +} + +void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->discAllCharacDescCB(event_data_length, + format, + handle_uuid_pair); +} + +void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charReadCB(event_data_length, + attribute_value); +} + +void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWritePrepareCB(event_data_length, + attribute_handle, + offset, + part_attr_value); +} + +void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWriteExecCB(event_data_length); +} + +ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattClient launchServiceDiscovery\n\r"); + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->launchServiceDiscovery(sc, cc, matchingServiceUUID, matchingCharacteristicUUIDIn); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, matchingServiceUUID); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, startHandle, endHandle); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +bool BlueNRGGattClient::isServiceDiscoveryActive(void) const +{ + bool isSDActive = false; + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + isSDActive |= _connectionPool[i]->isServiceDiscoveryActive(); + } + } + + return isSDActive; +} + +void BlueNRGGattClient::terminateServiceDiscovery(void) +{ + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + _connectionPool[i]->terminateServiceDiscovery(); + } + } +} + +void BlueNRGGattClient::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; ++i) { + if (_connectionPool[i]) { + _connectionPool[i]->onServiceDiscoveryTermination(callback); + } + } +} + +ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->read(attributeHandle, offset); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->write(cmd, attributeHandle, length, value); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(characteristic.getConnectionHandle()); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverCharacteristicDescriptors(characteristic, discoveryCallback, terminationCallback); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattClient's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattClient::reset(void) +{ + PRINTF("BlueNRGGattClient::reset\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if(_connectionPool[i] != NULL) { + _connectionPool[i]->reset(); + + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + } + } + + return BLE_ERROR_NONE; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,816 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGattConnectionClient + * @brief BlueNRG GattConnectionClient Adaptation + * @{ + */ + +#include "BlueNRGGattConnectionClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" +#include "ble_debug.h" + +// #define PRINTF printf + +static uint8_t props_mask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 + }; + +void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code) +{ + if(error_code != BLE_STATUS_SUCCESS) { + _currentState = GATT_IDLE; + return; + } + + // Service Discovery complete +/* + if(_currentState != GATT_IDLE && + _currentState != GATT_DISCOVERY_TERMINATED && + _currentState != GATT_WRITE_CHAR && + _currentState != GATT_READ_CHAR) { +*/ + if(_currentState == GATT_SERVICE_DISCOVERY) { + findServiceChars(); + return; + } + + if(_currentState == GATT_CHAR_DESC_DISCOVERY) { + _currentState = GATT_IDLE; + if(charDescTerminationCallback != NULL) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { + _characteristic, + BLE_ERROR_NONE + }; + charDescTerminationCallback(¶ms); + } + return; + } + + // Read complete + if(_currentState == GATT_READ_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processReadResponse(&readCBParams); + free((void*)(readCBParams.data)); + readCBParams.data = NULL; + return; + } + + // Write complete + if(_currentState == GATT_WRITE_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); + return; + } +} + +void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numAttr; + + numAttr = (event_data_length - 1) / attribute_data_length; + + offset = 0; + for (i=0; i<numAttr; i++) { + startHandle = attribute_data_list[offset]; + endHandle = attribute_data_list[offset+2]; + + // UUID Type + if (attribute_data_length == 6) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4]; + PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(attribute_data_list+offset+4, UUID::LSB); + +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + + } + + PRINTF("Setup serviceIndex = %d\n\r", _numServices); + discoveredService[_numServices].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += attribute_data_length; + } + + PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr); + +} + +void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numHandlePairs; + + numHandlePairs = (event_data_length - 1) / 2; + + offset = 0; + for (i=0; i<numHandlePairs; i++) { + startHandle = handles_info_list[offset]; + endHandle = handles_info_list[offset+2]; + + PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle); + + + if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle); + uuid = _matchingServiceUUID.getShortUUID(); + } else { +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02x", longUUIDBytes[i]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB); + } + + discoveredService[i].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += 4; + } +} + +void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) +{ + // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + uint8_t i, numChar, offset; + + numChar = (event_data_length - 1) / handle_value_pair_length; + + PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar); + + offset = 0; + for (i=0; i<numChar; i++) { + // UUID Type + if (handle_value_pair_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(handle_value_pair+offset+5, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & handle_value_pair[offset+2]); + p._read = (props_mask[1] & handle_value_pair[offset+2])>>1; + p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2; + p._write = (props_mask[3] & handle_value_pair[offset+2])>>3; + p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4; + p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5; + p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = handle_value_pair[offset+2]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = handle_value_pair[offset]; + valueHandle = handle_value_pair[offset+3]; + lastHandle = valueHandle+1; + PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle); + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; + + offset += handle_value_pair_length; + } +} + +void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) +{ + // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + + PRINTF("serviceCharByUUIDCB\n\r"); + + // UUID Type + if (event_data_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = attr_value[4]<<8|attr_value[3]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(attr_value+3, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & attr_value[0]); + p._read = (props_mask[1] & attr_value[0])>>1; + p._writeWoResp = (props_mask[2] & attr_value[0])>>2; + p._write = (props_mask[3] & attr_value[0])>>3; + p._notify = (props_mask[4] & attr_value[0])>>4; + p._indicate = (props_mask[5] & attr_value[0])>>5; + p._authSignedWrite = (props_mask[6] & attr_value[0])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = attr_value[0]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = attr_handle; + valueHandle = attr_value[1]; + lastHandle = valueHandle+1; + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + // update the last handle and call the characteristic discovery callback for previous char + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; +} + +ble_error_t BlueNRGGattConnectionClient::findServiceChars(void) +{ + PRINTF("findServiceChars\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + + DiscoveredService *service; + + // complete the discovery of the last characteristic of the previous service. + // Its last handle wasn't known before this point + // update the handle and call the characteristic discovery callback. + if (_servIndex != 0 && _numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle()); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars = 0; + + // We finished chars discovery for all services + if(_servIndex >= _numServices) { + PRINTF("!!!We finished chars discovery for all services!!!\n\r"); + //_currentState = GATT_CHARS_DISCOVERY_COMPLETE; + + terminateServiceDiscovery(); + + return BLE_ERROR_NONE; + } + + service = &discoveredService[_servIndex]; + /* + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID()); + } else { + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); + } + */ + + if(serviceDiscoveryCallback) { + serviceDiscoveryCallback(service); + } + + PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex); + //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle()); + + if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) { + PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r"); + ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle()); + } else { + + uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID()); + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; +#ifdef DEBUG + PRINTF("findServiceChars C UUID-"); + for(unsigned i = 0; i < 2; i++) { + PRINTF("%02X", short_uuid[i]); + } + PRINTF("\n\r"); +#endif + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID(); +#ifdef DEBUG + PRINTF("(findServiceChars) C UUID-"); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", uuid[i]); + } + PRINTF("\r\n"); +#endif + } + + ret = aci_gatt_disc_charac_by_uuid(_connectionHandle, + service->getStartHandle(), + service->getEndHandle(), + uuid_type, + uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _servIndex++; + } + + PRINTF("findServiceChars ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + unsigned j; + + if(isServiceDiscoveryActive()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if(!sc && !cc) { + // nothing to do + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r"); + return BLE_ERROR_NONE; + } + + serviceDiscoveryCallback = sc; + characteristicDiscoveryCallback = cc; + _matchingServiceUUID = matchingServiceUUID; + _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn; + + //reset services + _numServices = 0; + _numChars = 0; + _servIndex = 0; + for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) { + discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE); + } + + if(matchingServiceUUID == BLE_UUID_UNKNOWN) { + + // Wildcard: search for all services + PRINTF("Wildcard: search for all services\r\n"); + ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle); + + } else { + PRINTF("search for specific services\r\n"); + + uint8_t type = matchingServiceUUID.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID()); +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x"); + for(j = 0; j < 2; j++) { + PRINTF("%02X", short_uuid[j]); + } + PRINTF("\n\r"); +#endif + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; + + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)matchingServiceUUID.getBaseUUID(); + +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x"); + for(j = 0; j < 16; j++) { + PRINTF("%02X", uuid[j]); + } + PRINTF("\n\r"); +#endif + } + + // search for specific service by UUID + ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_SERVICE_DISCOVERY; + } + + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)matchingServiceUUID; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)startHandle; + (void)endHandle; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const +{ + if(_currentState == GATT_SERVICE_DISCOVERY) { + return true; + } + + return false; +} + +void BlueNRGGattConnectionClient::terminateServiceDiscovery(void) +{ + _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED; + + if (terminationCallback) { + terminationCallback(_connectionHandle); + } +} + +void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value) +{ + // copy the data read, they will be forwarded to the user once the procedure + // has completed + readCBParams.connHandle = _connectionHandle; + readCBParams.offset = 0; + readCBParams.len = event_data_length; + readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length)); + memcpy((void*)(readCBParams.data), attribute_value, event_data_length); +} + +ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + /* avoid compiler warnings about unused variables */ + (void)offset; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // Save the attribute_handle not provided by evt_att_read_resp + gattc->readCBParams.handle = attributeHandle; + + ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle); + + if(ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_READ_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } +} + +void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) +{ + // Update the write response params + writeCBParams.handle = attribute_handle; + writeCBParams.offset = offset; + writeCBParams.len = event_data_length-4; //(?) + writeCBParams.data = part_attr_value; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length) +{ + /* avoid compiler warnings about unused variables */ + (void)event_data_length; + + writeCBParams.connHandle = _connectionHandle; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + /* avoid compiler warnings about unused variables */ + (void)cmd; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // We save the write response params (used by the callback) because + // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE + gattc->writeCBParams.connHandle = _connectionHandle; + gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD; + gattc->writeCBParams.handle = attributeHandle; + gattc->writeCBParams.offset = 0; + gattc->writeCBParams.len = length; + gattc->writeCBParams.data = value; + + ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); + + if (ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_WRITE_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } + +} + +void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + GattAttribute::Handle_t attHandle; + UUID uuid; + uint8_t i, numCharacDesc, offset, handle_uuid_length; + + handle_uuid_length = 4; //Handle + UUID_16 + if (format == 2) + handle_uuid_length = 18; //Handle + UUID_128 + + numCharacDesc = (event_data_length - 1) / handle_uuid_length; + + offset = 0; + + PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n", + event_data_length, format); + + + for (i=0; i<numCharacDesc; i++) { + memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle)); + + // UUID Type + if (handle_uuid_length == 4) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2]; + PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB); +#ifdef DEBUG + PRINTF("D UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + } + + if(charDescDiscoveryCallback != NULL) { + CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { + _characteristic, + DiscoveredCharacteristicDescriptor( + _characteristic.getGattClient(), + _connectionHandle, + attHandle, + uuid + ) + }; + charDescDiscoveryCallback(¶ms); + } + + _numCharDesc++; + + offset += handle_uuid_length; + } +} + +ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { + + tBleStatus ret; + + if(_currentState != GATT_IDLE) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + charDescDiscoveryCallback = discoveryCallback; + charDescTerminationCallback = terminationCallback; + + GattAttribute::Handle_t valueHandle = characteristic.getValueHandle(); + GattAttribute::Handle_t lastHandle = characteristic.getLastHandle(); + + PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle); + ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle); + + if (ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_CHAR_DESC_DISCOVERY; + _characteristic = characteristic; + return BLE_ERROR_NONE; + } + switch (ret) { + case BLE_STATUS_INVALID_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattConnectionClient::reset(void) { + PRINTF("BlueNRGGattConnectionClient::reset\n"); + + /* Clear all state, including private members */ + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + _numServices = 0; + _servIndex = 0; + _numChars = 0; + _numCharDesc = 0; + + /* Clear class members */ + memset(discoveredService, 0, sizeof(discoveredService)); + memset(discoveredChar, 0, sizeof(discoveredChar)); + + // free response if allocated + if(readCBParams.data) { + free((void*)(readCBParams.data)); + } + + return BLE_ERROR_NONE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,755 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTSERVER + * @brief BlueNRG BLE_API GattServer Adaptation + * @{ + */ + +#include "BlueNRGGattServer.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/**************************************************************************/ +/*! + @brief Adds a new service to the GATT table on the peripheral + + @params[in] service + Pointer to instance of the Gatt Server to add + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::addService(GattService &service) +{ + /* ToDo: Make sure we don't overflow the array, etc. */ + /* ToDo: Make sure this service UUID doesn't already exist (?) */ + /* ToDo: Basic validation */ + + tBleStatus ret; + uint8_t type; + uint16_t short_uuid; + uint8_t primary_short_uuid[2]; + uint8_t primary_base_uuid[16]; + uint8_t char_base_uuid[16]; + const uint8_t *base_uuid; + const uint8_t *base_char_uuid; + + uint8_t charsCount = service.getCharacteristicCount(); + const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount; + + // check that there is enough characteristics left in the + // characteristic array. + if (charsCount > available_characteristics) { + PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics); + return BLE_ERROR_NO_MEM; + } + + const uint16_t maxAttrRecords = computeAttributesRecord(service); + + type = (service.getUUID()).shortOrLong(); + PRINTF("AddService(): Type:%d\n\r", type); + + /* Add the service to the BlueNRG */ + short_uuid = (service.getUUID()).getShortUUID(); + STORE_LE_16(primary_short_uuid, short_uuid); + + if(type==UUID::UUID_TYPE_LONG) { + base_uuid = (service.getUUID()).getBaseUUID(); + + COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]); + } + + ret = BLE_STATUS_SUCCESS; + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_serv(UUID_TYPE_16, + primary_short_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_serv(UUID_TYPE_128, + primary_base_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_OUT_OF_HANDLE: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case ERR_UNSPECIFIED_ERROR: + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_ERROR: + default: + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + + + service.setHandle(servHandle); + //serviceHandleVector.push_back(servHandle); + PRINTF("added servHandle handle =%u\n\r", servHandle); + uint16_t bleCharacteristic; + + //iterate to include all characteristics + for (uint8_t i = 0; i < charsCount; i++) { + GattCharacteristic *p_char = service.getCharacteristic(i); + uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); + + uint8_t int_8_uuid[2]; + STORE_LE_16(int_8_uuid, char_uuid); + + type = (p_char->getValueAttribute().getUUID()).shortOrLong(); + + if(type==UUID::UUID_TYPE_LONG) { + base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); +#ifdef DEBUG + for(uint8_t j=0; j<16; j++) { + PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]); + } + PRINTF("\n\r"); +#endif + COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]); + } + + PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); + /* + * Gatt_Evt_Mask -> HardCoded (0) + * Encryption_Key_Size -> Hardcoded (16) + * isVariable (variable length value field) -> Hardcoded (1) + */ + uint8_t Gatt_Evt_Mask = 0x0; + + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP; + } + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; + } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_16, + int_8_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_128, + char_base_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + case BLE_STATUS_CHARAC_ALREADY_EXISTS: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); + + p_characteristics[characteristicCount++] = p_char; + /* Set the characteristic value handle */ + p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE); + PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle()); + + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + ble_error_t err = write(p_char->getValueAttribute().getHandle(), + p_char->getValueAttribute().getValuePtr(), + p_char->getValueAttribute().getLength(), false /* localOnly */); + if (err) { + PRINTF("ERROR HERE !!!!\r\n"); + return err; + } + } + + // add descriptors now + uint16_t descHandle = 0; + PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); + + for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { + GattAttribute *descriptor = p_char->getDescriptor(descIndex); + uint8_t desc_uuid[16] = { 0 }; + + + uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT; + STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID()); + + if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) { + desc_uuid_type = CHAR_DESC_TYPE_128_BIT; + const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID(); + + COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]); + } + + ret = aci_gatt_add_char_desc(service.getHandle(), + bleCharacteristic, + desc_uuid_type, + desc_uuid, + descriptor->getMaxLength(), + descriptor->getLength(), + descriptor->getValuePtr(), + CHAR_DESC_SECURITY_PERMISSION, + CHAR_DESC_ACCESS_PERMISSION, + GATT_NOTIFY_ATTRIBUTE_WRITE, + MIN_ENCRY_KEY_SIZE, + CHAR_ATTRIBUTE_LEN_IS_FIXED, + &descHandle); + PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); + + switch (ret) { + case BLE_STATUS_SUCCESS: + PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); + descriptor->setHandle(descHandle); + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_INVALID_OPERATION: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + } + + serviceCount++; + + //FIXME: There is no GattService pointer array in GattServer. + // There should be one? (Only the user is aware of GattServices!) Report to forum. + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on char handle + + @param[in] attributeHandle + The handle of the GattCharacteristic to read from + @param[in] buffer + Buffer to hold the the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes read into the buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) +{ + tBleStatus ret; + uint16_t charHandle = attributeHandle; + + ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer); + + if(ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on the connection + and char handle + + @param[in] connectionHandle + The handle of the connection + @param[in] attributeHandle + The handle of the GattCharacteristic to write to + @param[in] buffer + Data to use when updating the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes in buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + uint8_t buffer[], + uint16_t *lengthP) { + + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)attributeHandle; + (void)buffer; + (void)lengthP; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t, + const uint8_t[], + uint16_t, bool localOnly) { + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)localOnly; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly) +{ + /* avoid compiler warnings about unused variables */ + (void)localOnly; + + // check that the len of the data to write are compatible with the characteristic + GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle); + if (!characteristic) { + PRINTF("characteristic not found\r\n"); + return BLE_ERROR_INVALID_PARAM; + } + + // if the attribute handle is the attribute handle of the characteristic value then + // write the value + if (attributeHandle == characteristic->getValueHandle()) { + // assert the len in input is correct for this characteristic + const GattAttribute& value_attribute = characteristic->getValueAttribute(); + + // reject write if the lenght exceed the maximum lenght of this attribute + if (value_attribute.getMaxLength() < len) { + PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + // reject write if the attribute size is fixed and the lenght in input is different than the + // length of the attribute. + if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) { + PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + tBleStatus ret; + + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + + PRINTF("updating bleCharacteristic valueHandle=%u,\ + corresponding serviceHandle=%u len=%d\n\r", + attributeHandle, bleCharHandleMap.find(charHandle)->second, len); + + /* + * If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. + */ + ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } else { + // write this handle has a descriptor handle + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + uint16_t service_handle = bleCharHandleMap.find(charHandle)->second; + + tBleStatus ret = aci_gatt_set_desc_value( + service_handle, + charHandle, + attributeHandle, + 0, + len, + buffer + ); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } +} + +/**************************************************************************/ +/*! + @brief Reads a value according to the handle provided + + @param[in] attributeHandle + The handle of the attribute to read from + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle) +{ + uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); + + GattReadCallbackParams readParams; + readParams.handle = attributeHandle; + + //PRINTF("readParams.handle = %d\n\r", readParams.handle); + HCIDataReadEvent(&readParams); + + //EXIT: + if(gapConnectionHandle != 0){ + //PRINTF("Calling aci_gatt_allow_read\n\r"); + aci_gatt_allow_read(gapConnectionHandle); + } + + return BLE_ERROR_NONE; +} + +// ask if the write request should be accepted of rejected +// return 0 in case of success or an ATT error response in +// case of faillure +uint8_t BlueNRGGattServer::Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length, + const uint8_t* data) { + + GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle); + if(!characteristic) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF; + } + + // check if the data length is in range + if (characteristic->getValueAttribute().getMaxLength() < data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + // if the length of the characteristic value is fixed + // then the data in input should be of that length + if (characteristic->getValueAttribute().hasVariableLength() == false && + characteristic->getValueAttribute().getMaxLength() != data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + GattWriteAuthCallbackParams params = { + connection_handle, + attr_handle, + /* offset */ 0, + data_length, + data, + /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED + }; + + return characteristic->authorizeWrite(¶ms) & 0xFF; +} + +/**************************************************************************/ +/*! + @brief Returns the GattCharacteristic according to the handle provided + + @param[in] attrHandle + The handle of the attribute + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) +{ + GattCharacteristic *p_char = NULL; + int i; + uint16_t handle, handle_1; + + PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle); + for(i=0; i<characteristicCount; i++) + { + handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + PRINTF("handle(%d)=%d\n\r", i, handle); + if(i==characteristicCount-1)//Last Characteristic check + { + if(attrHandle>=handle) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); + break; + } + } + else { + handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + //Testing if attribute handle is between two Characteristic Handles + if(attrHandle>=handle && attrHandle<handle_1) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); + break; + } else continue; + } + } + + return p_char; +} + +void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { + this->handleDataWrittenEvent(params); +} + +void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { + PRINTF("Called HCIDataReadEvent\n\r"); + this->handleDataReadEvent(params); +} + +void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { + this->handleEvent(type, charHandle); +} + +void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { + this->handleDataSentEvent(count); +} + + +ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { + // <TODO> + return (ble_error_t)0; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::reset(void) +{ + PRINTF("BlueNRGGattServer::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (GattServer::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + /* Clear class members */ + memset(p_characteristics, 0, sizeof(p_characteristics)); + memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles)); + serviceCount = 0; + characteristicCount = 0; + + return BLE_ERROR_NONE; +} + + +/// compute the number of attributes needed by this service. +uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) { + uint16_t attribute_records = 1; + + for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) { + // add two attributes, one for the characteristic declaration + // and the other for the characteristic value. + attribute_records += 2; + + const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index); + const uint8_t properties = characteristic->getProperties(); + // if notify or indicate are present, two attributes are + // needed + if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) || + (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { + attribute_records += 2; + } + + // if broadcast is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) { + attribute_records += 2; + } + + // if extended properties flag is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) { + attribute_records += 2; + } + + attribute_records += characteristic->getDescriptorCount(); + } + + // for some reason, if there is just a service, this value should + // be equal to 5 + if (attribute_records == 1) { + attribute_records = 5; + } + + return attribute_records; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,421 @@ +/** + ****************************************************************************** + * @file ble_hci.c + * @author AMS/HESA Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "ble_gp_timer.h" +#include "ble_debug.h" + +#include "stm32_bluenrg_ble.h" + +#if BLE_CONFIG_DBG_ENABLE +#undef PRINTF +#endif + +#define HCI_LOG_ON 0 + +#define HCI_READ_PACKET_NUM_MAX (0x40) + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tListNode hciReadPktPool; +tListNode hciReadPktRxQueue; + +// betzw - DEBUG: +//#define POOL_CNT +#ifdef POOL_CNT +#include <stdio.h> +static unsigned int nr_hciReadPktPool; +static unsigned int lowest_nr_hciReadPktPool; +#endif // POOL_CNT + +/* pool of hci read packets */ +static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; + +static volatile uint8_t hci_timer_id; +static volatile uint8_t hci_timeout; + +void hci_timeout_callback(void) +{ + hci_timeout = 1; + return; +} + +void HCI_Init(void) +{ + uint8_t index; + +#ifdef POOL_CNT + nr_hciReadPktPool = 0; +#endif // POOL_CNT + + /* Initialize list heads of ready and free hci data packet queues */ + list_init_head (&hciReadPktPool); + list_init_head (&hciReadPktRxQueue); + + /* Initialize the queue of free hci data packets */ + for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) + { + list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif // POOL_CNT + } + +#ifdef POOL_CNT + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif // POOL_CNT +} + +#define HCI_PCK_TYPE_OFFSET 0 +#define EVENT_PARAMETER_TOT_LEN_OFFSET 2 + +/** + * Verify if HCI packet is correctly formatted. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * @return 0 if HCI packet is as expected + */ +int HCI_verify(const tHciDataPacket * hciReadPacket) +{ + const uint8_t *hci_pckt = hciReadPacket->dataBuff; + + if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) + return 1; /* Incorrect type. */ + + if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) + return 2; /* Wrong length (packet truncated or too long). */ + + return 0; +} + +void HCI_Process(void) +{ + tHciDataPacket * hciReadPacket = NULL; + +#ifdef POOL_CNT + printf("betzw(%s, %d): nr_hciReadPktPool = %u (lowest = %u)\r\n", __func__, __LINE__, + nr_hciReadPktPool, lowest_nr_hciReadPktPool); +#endif // POOL_CNT + + Disable_SPI_IRQ(); + uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); + /* process any pending events read */ + while(list_empty == FALSE) + { + list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + Enable_SPI_IRQ(); + HCI_Event_CB(hciReadPacket->dataBuff); + Disable_SPI_IRQ(); + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + list_empty = list_is_empty(&hciReadPktRxQueue); + } + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG. */ + HCI_HandleSPI(); + Enable_SPI_IRQ(); +} + +BOOL HCI_Queue_Empty(void) +{ + return list_is_empty(&hciReadPktRxQueue); +} + +/** + * When an interrupt is raised by BlueNRG, + * just signal that a new event (availability of SPI data to be read) + * needs to be processed. + */ +void HCI_Isr(void) +{ + signalEventsToProcess(); +} + +/** + * Now, SPI Data are handled in user space. + * In case it has to be called in ISR, take care to + * call Disable_SPI_IRQ/Enable_SPI_IRQ in a proper way. + * The calls Disable_SPI_IRQ/Enable_SPI_IRQ have not been removed + * from this code for backward compatibility. + */ +void HCI_HandleSPI(void) +{ + tHciDataPacket * hciReadPacket = NULL; + uint8_t data_len; + + Clear_SPI_EXTI_Flag(); + while(BlueNRG_DataPresent()){ + if (list_is_empty (&hciReadPktPool) == FALSE){ + + /* enqueueing a packet for read */ + list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool--; + if(nr_hciReadPktPool < lowest_nr_hciReadPktPool) + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif + + data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); + if(data_len > 0){ + hciReadPacket->data_len = data_len; + if(HCI_verify(hciReadPacket) == 0) { + list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); + } else { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else { + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else{ + // HCI Read Packet Pool is empty, wait for a free packet. + Clear_SPI_EXTI_Flag(); + return; + } + + Clear_SPI_EXTI_Flag(); + } +} + +void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){ +#if HCI_LOG_ON + PRINTF("HCI <- "); + for(int i=0; i < n_bytes1; i++) + PRINTF("%02X ", *((uint8_t*)data1 + i)); + for(int i=0; i < n_bytes2; i++) + PRINTF("%02X ", *((uint8_t*)data2 + i)); + PRINTF("\n"); +#endif + + Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); +} + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) +{ + hci_command_hdr hc; + + hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); + hc.plen= plen; + + uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; + header[0] = HCI_COMMAND_PKT; + Osal_MemCpy(header+1, &hc, sizeof(hc)); + + hci_write(header, param, sizeof(header), plen); +} + +static void move_list(tListNode * dest_list, tListNode * src_list) +{ + pListNode tmp_node; + + while(!list_is_empty(src_list)){ + list_remove_tail(src_list, &tmp_node); + list_insert_head(dest_list, tmp_node); + } +} + + /* It ensures that we have at least half of the free buffers in the pool. */ +static void free_event_list(void) +{ + tHciDataPacket * pckt; + + Disable_SPI_IRQ(); + + while(list_get_size(&hciReadPktPool) < HCI_READ_PACKET_NUM_MAX/2){ + list_remove_head(&hciReadPktRxQueue, (tListNode **)&pckt); + list_insert_tail(&hciReadPktPool, (tListNode *)pckt); + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG */ + HCI_HandleSPI(); + } + + Enable_SPI_IRQ(); +} + +int hci_send_req(struct hci_request *r, BOOL async) +{ + uint8_t *ptr; + uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + hci_event_pckt *event_pckt; + hci_uart_pckt *hci_hdr; + int to = DEFAULT_TIMEOUT; + struct timer t; + tHciDataPacket * hciReadPacket = NULL; + tListNode hciTempQueue; + + list_init_head(&hciTempQueue); + + free_event_list(); + + hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); + + if(async){ + return 0; + } + + /* Minimum timeout is 1. */ + if(to == 0) + to = 1; + + Timer_Set(&t, to); + + while(1) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + evt_le_meta_event *me; + int len; + + while(1){ + + Disable_SPI_IRQ(); + HCI_HandleSPI(); + Enable_SPI_IRQ(); + + if(Timer_Expired(&t)){ + goto failed; + } + if(!HCI_Queue_Empty()){ + break; + } + } + + /* Extract packet from HCI event queue. */ + Disable_SPI_IRQ(); + list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + + hci_hdr = (void *)hciReadPacket->dataBuff; + + if(hci_hdr->type == HCI_EVENT_PKT){ + + event_pckt = (void *) (hci_hdr->data); + + ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); + len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); + + switch (event_pckt->evt) { + + case EVT_CMD_STATUS: + cs = (void *) ptr; + + if (cs->opcode != opcode) + goto failed; + + if (r->event != EVT_CMD_STATUS) { + if (cs->status) { + goto failed; + } + break; + } + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_CMD_COMPLETE: + cc = (void *) ptr; + + if (cc->opcode != opcode) + goto failed; + + ptr += EVT_CMD_COMPLETE_SIZE; + len -= EVT_CMD_COMPLETE_SIZE; + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_LE_META_EVENT: + me = (void *) ptr; + + if (me->subevent != r->event) + break; + + len -= 1; + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, me->data, r->rlen); + goto done; + + case EVT_HARDWARE_ERROR: + goto failed; + + default: + break; + } + } + + /* If there are no more packets to be processed, be sure there is at list one + packet in the pool to process the expected event. + If no free packets are available, discard the processed event and insert it + into the pool. */ + if(list_is_empty(&hciReadPktPool) && list_is_empty(&hciReadPktRxQueue)){ + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); + hciReadPacket=NULL; + } + else { + /* Insert the packet in a different queue. These packets will be + inserted back in the main queue just before exiting from send_req(), so that + these events can be processed by the application. + */ + list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); + hciReadPacket = NULL; + } + + HCI_HandleSPI(); + + Enable_SPI_IRQ(); + + } + +failed: + if(hciReadPacket != NULL) { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + move_list(&hciReadPktRxQueue, &hciTempQueue); + Enable_SPI_IRQ(); + return -1; + +done: + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + move_list(&hciReadPktRxQueue, &hciTempQueue); + + Enable_SPI_IRQ(); + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,837 @@ +/** + ****************************************************************************** + * @file ble_hci_le.c + * @author AMG RF Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +int hci_reset(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_RESET; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_disconnect(uint16_t handle, uint8_t reason) +{ + struct hci_request rq; + disconnect_cp cp; + uint8_t status; + + cp.handle = handle; + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) +{ + struct hci_request rq; + read_local_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + + *hci_version = resp.hci_version; + *hci_revision = btohs(resp.hci_revision); + *lmp_pal_version = resp.lmp_pal_version; + *manufacturer_name = btohs(resp.manufacturer_name); + *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); + + return 0; +} + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) +{ + struct hci_request rq; + le_read_buffer_size_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_BUFFER_SIZE; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *pkt_len = resp.pkt_len; + *max_pkt = resp.max_pkt; + + return 0; +} + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter) +{ + struct hci_request rq; + le_set_adv_parameters_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.min_interval = min_interval; + adv_cp.max_interval = max_interval; + adv_cp.advtype = advtype; + adv_cp.own_bdaddr_type = own_bdaddr_type; + adv_cp.direct_bdaddr_type = direct_bdaddr_type; + if(direct_bdaddr != NULL) + Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); + adv_cp.chan_map = chan_map; + adv_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_PARAMETERS; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_adv_data_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.length = length; + Osal_MemCpy(adv_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_DATA; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertise_enable(uint8_t enable) +{ + struct hci_request rq; + le_set_advertise_enable_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.enable = enable?1:0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter) +{ + struct hci_request rq; + le_set_scan_parameters_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.type = type; + scan_cp.interval = interval; + scan_cp.window = window; + scan_cp.own_bdaddr_type = own_bdaddr_type; + scan_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) +{ + struct hci_request rq; + le_set_scan_enable_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.enable = enable?1:0; + scan_cp.filter_dup = filter_dup; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_ENABLE; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_rand(uint8_t random_number[8]) +{ + struct hci_request rq; + le_rand_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_RAND; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + Osal_MemCpy(random_number, resp.random, 8); + + return 0; +} + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_scan_response_data_cp scan_resp_cp; + uint8_t status; + + Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); + scan_resp_cp.length = length; + Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; + rq.cparam = &scan_resp_cp; + rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) +{ + struct hci_request rq; + le_read_adv_channel_tx_power_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *tx_power_level = resp.level; + + return 0; +} + +int hci_le_set_random_address(tBDAddr bdaddr) +{ + struct hci_request rq; + le_set_random_address_cp set_rand_addr_cp; + uint8_t status; + + Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); + Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; + rq.cparam = &set_rand_addr_cp; + rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_read_bd_addr(tBDAddr bdaddr) +{ + struct hci_request rq; + read_bd_addr_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_BD_ADDR; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_BD_ADDR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); + + return 0; +} + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) +{ + struct hci_request rq; + le_create_connection_cp create_cp; + uint8_t status; + + Osal_MemSet(&create_cp, 0, sizeof(create_cp)); + create_cp.interval = interval; + create_cp.window = window; + create_cp.initiator_filter = initiator_filter; + create_cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); + create_cp.own_bdaddr_type = own_bdaddr_type; + create_cp.min_interval=min_interval; + create_cp.max_interval=max_interval; + create_cp.latency = latency; + create_cp.supervision_timeout=supervision_timeout; + create_cp.min_ce_length=min_ce_length; + create_cp.max_ce_length=max_ce_length; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN; + rq.cparam = &create_cp; + rq.clen = LE_CREATE_CONN_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_create_connection_cancel(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN_CANCEL; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) +{ + struct hci_request rq; + le_encrypt_cp params; + le_encrypt_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemCpy(params.key, key, 16); + Osal_MemCpy(params.plaintext, plaintextData, 16); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ENCRYPT; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + le_ltk_neg_reply_cp params; + le_ltk_neg_reply_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + params.handle = 1; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_LTK_NEG_REPLY; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CLEAR_WHITE_LIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0){ + return BLE_STATUS_TIMEOUT; + } + + return status; +} + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) +{ + struct hci_request rq; + le_add_device_to_white_list_cp params; + uint8_t status; + + params.bdaddr_type = bdaddr_type; + Osal_MemCpy(params.bdaddr, bdaddr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; + rq.cparam = ¶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/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1309 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB05A1 cp; + gap_init_rp resp; + + cp.role = role; + cp.privacy_enabled = privacy_enabled; + cp.device_name_char_len = device_name_char_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} +tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB04A1 cp; + gap_init_rp resp; + + cp.role = role; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + SlaveConnIntervMin = htobs(SlaveConnIntervMin); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + SlaveConnIntervMax = htobs(SlaveConnIntervMax); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB05A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.directed_adv_type = directed_adv_type; + cp.adv_interv_min = adv_interv_min; + cp.adv_interv_max = adv_interv_max; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB04A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_io_capability(uint8_t io_capability) +{ + struct hci_request rq; + uint8_t status; + gap_set_io_capability_cp cp; + + cp.io_capability = io_capability; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_IO_CAPABILITY; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode) +{ + struct hci_request rq; + gap_set_auth_requirement_cp cp; + uint8_t status; + + cp.mitm_mode = mitm_mode; + cp.oob_enable = oob_enable; + Osal_MemCpy(cp.oob_data, oob_data, 16); + cp.min_encryption_key_size = min_encryption_key_size; + cp.max_encryption_key_size = max_encryption_key_size; + cp.use_fixed_pin = use_fixed_pin; + cp.fixed_pin = htobl(fixed_pin); + cp.bonding_mode = bonding_mode; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) +{ + struct hci_request rq; + gap_set_author_requirement_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorization_enable = authorization_enable; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) +{ + struct hci_request rq; + gap_passkey_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.passkey = htobl(passkey); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_PASSKEY_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) +{ + struct hci_request rq; + gap_authorization_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorize = authorize; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB05A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + cp.own_address_type = own_address_type; + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB04A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) +{ + struct hci_request rq; + gap_set_undirected_connectable_cp cp; + uint8_t status; + + cp.own_addr_type = own_addr_type; + cp.adv_filter_policy = adv_filter_policy; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) +{ + struct hci_request rq; + gap_slave_security_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.bonding = bonding; + cp.mitm_protection = mitm_protection; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[32]; + uint8_t indx = 0; + + if (AdvLen > (sizeof(buffer)-1)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvLen; + indx++; + + Osal_MemCpy(buffer + indx, AdvData, AdvLen); + indx += AdvLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_UPDATE_ADV_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) +{ + struct hci_request rq; + gap_delete_ad_type_cp cp; + uint8_t status; + + cp.ad_type = ad_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_DELETE_AD_TYPE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required) +{ + struct hci_request rq; + gap_get_security_level_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; + rq.rparam = &resp; + rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *mitm_protection = resp.mitm_protection; + *bonding = resp.bonding; + *oob_data = resp.oob_data; + *passkey_required = resp.passkey_required; + + return resp.status; +} + +tBleStatus aci_gap_configure_whitelist(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) +{ + struct hci_request rq; + gap_terminate_cp cp; + uint8_t status; + + cp.handle = htobs(conn_handle); + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_clear_security_database(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) +{ + struct hci_request rq; + gap_allow_rebond_cp_IDB05A1 cp; + uint8_t status; + + cp.conn_handle = conn_handle; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_allow_rebond_IDB04A1(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_limited_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_general_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_name_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = use_reconn_addr; + indx++; + + Osal_MemCpy(buffer + indx, reconn_addr, 6); + indx += 6; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB05A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB04A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.use_reconn_addr = use_reconn_addr; + Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_start_selective_conn_establish_proc_cp cp; + uint8_t status; + + if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.num_whitelist_entries = num_whitelist_entries; + + Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_create_connection_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CREATE_CONNECTION; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; + rq.cparam = &procedure_code; + rq.clen = 1; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_connection_update_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) +{ + struct hci_request rq; + gap_send_pairing_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.force_rebond = force_rebond; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + gap_resolve_private_address_rp rp; + + Osal_MemCpy(cp.address, private_address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); + + return 0; +} +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + uint8_t status; + + Osal_MemCpy(cp.address, address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_set_broadcast_mode_cp cp; + uint8_t status; + uint8_t indx = 0; + uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; + + if (variable_size > sizeof(cp.var_len_data) ) + return BLE_STATUS_INVALID_PARAMS; + + cp.adv_interv_min = htobs(adv_interv_min); + cp.adv_interv_max = htobs(adv_interv_max); + cp.adv_type = adv_type; + cp.own_addr_type = own_addr_type; + + cp.var_len_data[indx] = adv_data_length; + indx++; + Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); + indx += adv_data_length; + cp.var_len_data[indx] = num_whitelist_entries; + indx ++; + Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_BROADCAST_MODE; + rq.cparam = &cp; + rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_observation_proc_cp cp; + uint8_t status; + + cp.scan_interval = scan_interval; + cp.scan_window = scan_window; + cp.scan_type = scan_type; + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_OBSERVATION_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) +{ + struct hci_request rq; + gap_is_device_bonded_cp cp; + uint8_t status; + + cp.peer_address_type = peer_address_type; + Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_IS_DEVICE_BONDED; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) +{ + struct hci_request rq; + gap_get_bonded_devices_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_BONDED_DEVICES; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (rp.status) { + return rp.status; + } + + *num_devices = rp.num_addr; + if(device_list != NULL) + Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1505 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.c +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : File with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_gatt_init(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INIT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[19]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, service_uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = service_type; + indx++; + + buffer[indx] = max_attr_records; + indx++; + + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle) +{ + struct hci_request rq; + gatt_include_serv_rp resp; + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + service_handle = htobs(service_handle); + Osal_MemCpy(buffer, &service_handle, 2); + indx += 2; + + included_start_handle = htobs(included_start_handle); + Osal_MemCpy(buffer+indx, &included_start_handle, 2); + indx += 2; + + included_end_handle = htobs(included_end_handle); + Osal_MemCpy(buffer+indx, &included_end_handle, 2); + indx += 2; + + if(included_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } else { + uuid_len = 16; + } + + buffer[indx] = included_uuid_type; + indx++; + + Osal_MemCpy(buffer + indx, included_uuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INCLUDE_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *included_handle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[25]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + buffer[indx] = charValueLen; + indx++; + + buffer[indx] = charProperties; + indx++; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *charHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle) +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = descValueMaxLen; + indx++; + + buffer[indx] = descValueLen; + indx++; + + if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + Osal_MemCpy(buffer + indx, descValue, descValueLen); + indx += descValueLen; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = accPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR_DESC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *descHandle = btohs(resp.handle); + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = charValOffset; + indx++; + + buffer[indx] = charValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charValue, charValueLen); + indx += charValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_char_cp cp; + + cp.service_handle = htobs(servHandle); + cp.char_handle = htobs(charHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_CHAR; + rq.cparam = &cp; + rq.clen = GATT_DEL_CHAR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_service(uint16_t servHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_serv_cp cp; + + cp.service_handle = htobs(servHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_inc_serv_cp cp; + + cp.service_handle = htobs(servHandle); + cp.inc_serv_handle = htobs(includeServHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_INC_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_INC_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) +{ + struct hci_request rq; + uint8_t status; + gatt_set_evt_mask_cp cp; + + cp.evt_mask = htobs(event_mask); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_EVT_MASK; + rq.cparam = &cp; + rq.clen = GATT_SET_EVT_MASK_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_exchange_config_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_EXCHANGE_CONFIG; + rq.cparam = &cp; + rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) +{ + struct hci_request rq; + uint8_t status; + att_find_info_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_INFO_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_find_by_type_value_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + Osal_MemCpy(cp.uuid, uuid, 2); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_group_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_prepare_write_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.value_offset = htobs(value_offset); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) +{ + struct hci_request rq; + uint8_t status; + att_execute_write_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.execute = execute; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_prim_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_prim_service_by_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; + rq.cparam = &cp; + rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, + uint16_t end_service_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_find_included_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_service_handle); + cp.end_handle = htobs(end_service_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_of_serv_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_attr_handle = htobs(start_attr_handle); + cp.end_attr_handle = htobs(end_attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t charUuidType, + const uint8_t* charUuid) +{ + struct hci_request rq; + uint8_t status; + + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + start_handle = htobs(start_handle); + Osal_MemCpy(buffer + indx, &start_handle, 2); + indx += 2; + + end_handle = htobs(end_handle); + Osal_MemCpy(buffer + indx, &end_handle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == 0x01){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_descriptors_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.char_val_handle = htobs(char_val_handle); + cp.char_end_handle = htobs(char_end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_read_using_charac_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; + rq.cparam = &cp; + rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles) +{ + struct hci_request rq; + uint8_t status; + gatt_read_multiple_charac_val_cp cp; + + if(num_handles*2 > sizeof(cp.set_of_handles)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.num_handles = htobs(num_handles); + Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_long_charac_val_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; + rq.cparam = &cp; + rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_signed_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_confirm_indication_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_CONFIRM_INDICATION; + rq.cparam = &cp; + rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = write_status; + indx += 1; + + buffer[indx] = err_code; + indx += 1; + + buffer[indx] = att_val_len; + indx += 1; + + Osal_MemCpy(buffer + indx, att_val, att_val_len); + indx += att_val_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(uint16_t conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ALLOW_READ; + rq.cparam = &cp; + rq.clen = GATT_ALLOW_READ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission) +{ + struct hci_request rq; + gatt_set_security_permission_cp cp; + uint8_t status; + + cp.service_handle = htobs(service_handle); + cp.attr_handle = htobs(attr_handle); + cp.security_permission = security_permission; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; + rq.cparam = &cp; + rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + charDescHandle = htobs(charDescHandle); + Osal_MemCpy(buffer + indx, &charDescHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charDescValOffset, 2); + indx += 2; + + buffer[indx] = charDescValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); + indx += charDescValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_DESC_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_cp cp; + gatt_read_handle_val_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = btohs(rp.value_len); + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_offset_cp cp; + gatt_read_handle_val_offset_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rp.value_len; + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value) +{ + struct hci_request rq; + uint8_t status; + gatt_upd_char_val_ext_cp cp; + + if(value_length > sizeof(cp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.service_handle = htobs(service_handle); + cp.char_handle = htobs(char_handle); + cp.update_type = update_type; + cp.char_length = htobs(char_length); + cp.value_offset = htobs(value_offset); + cp.value_length = value_length; + Osal_MemCpy(cp.value, value, value_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL_EXT; + rq.cparam = &cp; + rq.clen = GATT_UPD_CHAR_VAL_EXT_CP_SIZE + value_length; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,266 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number) +{ + struct hci_request rq; + hal_get_fw_build_number_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_FW_BUILD_NUMBER; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *build_number = rp.build_number; + + return 0; +} + +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((len+2) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = offset; + indx++; + + buffer[indx] = len; + indx++; + + Osal_MemCpy(buffer + indx, val, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + hal_read_config_data_cp cp; + hal_read_config_data_rp rp; + + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_READ_CONFIG_DATA; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rq.rlen-1; + + Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) +{ + struct hci_request rq; + hal_set_tx_power_level_cp cp; + uint8_t status; + + cp.en_high_power = en_high_power; + cp.pa_level = pa_level; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets) +{ + struct hci_request rq; + hal_le_tx_test_packet_number_rp resp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_LE_TX_TEST_PACKET_NUMBER; + rq.rparam = &resp; + rq.rlen = sizeof(resp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *number_of_packets = btohl(resp.number_of_packets); + + return 0; +} + +tBleStatus aci_hal_device_standby(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_DEVICE_STANDBY; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_start(uint8_t rf_channel) +{ + struct hci_request rq; + hal_tone_start_cp cp; + uint8_t status; + + cp.rf_channel = rf_channel; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_START; + rq.cparam = &cp; + rq.clen = HAL_TONE_START_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_stop(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_STOP; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]) +{ + struct hci_request rq; + hal_get_link_status_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_LINK_STATUS; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(link_status,rp.link_status,sizeof(link_status)); + for(int i = 0; i < 8; i++) + conn_handle[i] = btohs(rp.conn_handle[i]); + + return 0; +} + +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot) +{ + struct hci_request rq; + hal_get_anchor_period_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_ANCHOR_PERIOD; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *anchor_period = btohl(rp.anchor_period); + *max_free_slot = btohl(rp.max_free_slot); + + return 0; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,117 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB05A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.min_ce_length = htobs(min_ce_length); + cp.max_ce_length = htobs(max_ce_length); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB04A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,269 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_updater_aci.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_updater_reboot(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_get_updater_version(uint8_t *version) +{ + struct hci_request rq; + get_updater_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_VERSION; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) +{ + struct hci_request rq; + get_updater_bufsize_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_BUFSIZE; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_reset_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = htobl(address); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_SECTOR; + rq.cparam = &cp; + rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_program_data_block(uint32_t address, + uint16_t len, + const uint8_t *data) +{ + struct hci_request rq; + uint8_t status; + updater_prog_data_block_cp cp; + + if( len > sizeof(cp.data)) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(len); + Osal_MemCpy(cp.data, data, len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_read_data_block(uint32_t address, + uint16_t data_len, + uint8_t *data) +{ + struct hci_request rq; + updater_read_data_block_cp cp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + + if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(data_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; + rq.rparam = buffer; + rq.rlen = data_len + 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + // First byte is status + Osal_MemCpy(data, buffer+1, data_len); + + return buffer[0]; +} + +tBleStatus aci_updater_calc_crc(uint32_t address, + uint8_t num_sectors, + uint32_t *crc) +{ + struct hci_request rq; + updater_calc_crc_cp cp; + updater_calc_crc_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + cp.address = htobl(address); + cp.num_sectors = num_sectors; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_CALC_CRC; + rq.cparam = &cp; + rq.clen = UPDATER_CALC_CRC_CP_SIZE; + rq.rparam = &resp; + rq.rlen = UPDATER_CALC_CRC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *crc = btohl(resp.crc); + + return resp.status; +} + +tBleStatus aci_updater_hw_version(uint8_t *version) +{ + struct hci_request rq; + updater_hw_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_HW_VERSION; + rq.rparam = &resp; + rq.rlen = UPDATER_HW_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,423 @@ + +#include "ble_hal.h" +#include "ble_hal_types.h" +#include "ble_status.h" +#include "bluenrg_aci.h" +#include "bluenrg_utils.h" +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "ble_osal.h" +#include "string.h" +#include "stm32_bluenrg_ble.h" + +#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 +#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 + +#define BASE_ADDRESS 0x10010000 + +#define FW_OFFSET (2*1024) // 2 KB +#define FW_OFFSET_MS 0 +#define FULL_STACK_SIZE (66*1024) // 66 KB +#define BOOTLOADER_SIZE (2*1024) // 2 kB +#define SECTOR_SIZE (2*1024) // 2 KB + +// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + +// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 +#define CRC_POLY 0x04C11DB7 // the poly without the x**32 + +#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC + +#define IFR_SIZE 192 +#define IFR_BASE_ADDRESS 0x10020000 +#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data + +#if BLUENRG_MS +#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET +#else +#define IFR_WRITE_OFFSET_BEGIN 0 +#endif + + +#define BLUE_FLAG_OFFSET 0x8C0 +#define MAX_ERASE_RETRIES 2 +#define MAX_WRITE_RETRIES 2 +#define MIN_WRITE_BLOCK_SIZE 4 +#define MAX_WRITE_BLOCK_SIZE 64 // 64 bytes +#define READ_BLOCK_SIZE 64 // 64 bytes + +#define RETRY_COMMAND(func, num_ret, error) \ +{ \ + uint8_t num_retries; \ + num_retries = 0; \ + error = 0; \ + while (num_retries++ < num_ret) { \ + if (func == BLE_STATUS_SUCCESS) \ + break; \ + if (num_retries == num_ret) \ + error = BLE_UTIL_ACI_ERROR; \ + } \ +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, + they are extended with 0xFF until sector size is reached +*/ +static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) +{ + uint32_t i, j, a1; + uint32_t crc, value; + + crc = 0; + for (i = 0; i < SECTOR_SIZE; i += 4) { + uint8_t *dataw = (uint8_t *) &value; + + dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; + dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; + dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; + dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; + + crc = crc ^ value; + for (j = 0; j < 32; j ++) { + a1 = (crc >> 31) & 0x1; + crc = (crc << 1) ^ (a1 * CRC_POLY); + } + } + + return crc; +} + +int program_device(const uint8_t *fw_image, uint32_t fw_size) +{ + uint8_t version, num_erase_retries, status, write_block_size; + uint32_t address; + uint32_t crc, crc2, crc_size; + uint32_t fw_offset = FW_OFFSET; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + if(aci_updater_hw_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version==0x31){ + // It does not contain bootloader inside first sector. It may contain code. + fw_offset = FW_OFFSET_MS; + } + + if (fw_size != FULL_STACK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + if (fw_size % MIN_WRITE_BLOCK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + + /*********************************************************************** + * Erase BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + /*********************************************************************** + * Erase and Program sectors + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE) { + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(BASE_ADDRESS + i); + for (int j=i; ((j<i+SECTOR_SIZE)&&(j<fw_size)); j += write_block_size) { + + write_block_size = MIN(fw_size-j, MAX_WRITE_BLOCK_SIZE); + + RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, write_block_size, fw_image+j), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + break; + } + if (status == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + } + + /*********************************************************************** + * Verify firmware + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE){ + address = BASE_ADDRESS + i; + if(aci_updater_calc_crc(address, 1, &crc)) + return BLE_UTIL_ACI_ERROR; + + crc_size = MIN(fw_size-i,SECTOR_SIZE); + + crc2 = updater_calc_crc(fw_image+i,crc_size); + if(crc!=crc2) + return BLE_UTIL_CRC_ERROR; + } + + /*********************************************************************** + * Write BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +int read_IFR(uint8_t *data) +{ + uint8_t version, offset; + tBleStatus ret; + + offset = 0; + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + /*********************************************************************** + * Reading last 3 IFR 64-byte blocks + ************************************************************************/ + for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(BASE_ADDRESS+i, READ_BLOCK_SIZE, (data+offset)); + offset += READ_BLOCK_SIZE; + if(ret) return BLE_UTIL_ACI_ERROR; + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; + +} + +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) +{ + IFR_config->stack_mode = data[0]; + IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); + IFR_config->master_sca = data[30]; + IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); + IFR_config->year = BCD_TO_INT(data[41]); + IFR_config->month = BCD_TO_INT(data[42]); + IFR_config->day = BCD_TO_INT(data[43]); +} + +int IFR_validate(IFR_config2_TypeDef *IFR_config) +{ +#if BLUENRG_MS + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) +#else + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) +#endif + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode + if(IFR_config->master_sca > 7) + return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->day > 31 || IFR_config->day < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + + return BLE_STATUS_SUCCESS; +} + +/* TODO: Function to generate data from given options. */ + +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) +{ + data[0] = IFR_config->stack_mode; + HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); + data[30] = IFR_config->master_sca; + HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); + data[41] = INT_TO_BCD(IFR_config->year); + data[42] = INT_TO_BCD(IFR_config->month); + data[43] = INT_TO_BCD(IFR_config->day); +} + + +int program_IFR(const IFR_config_TypeDef *ifr_image) +{ + uint8_t version, num_erase_retries; + tBleStatus ret; +#if BLUENRG_MS + const uint8_t *ifr_data = (uint8_t *)ifr_image; +#else + uint8_t ifr_data[SECTOR_SIZE]; +#endif + uint8_t hwVersion; + uint16_t fwVersion; + + if(getBlueNRGVersion(&hwVersion, &fwVersion)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + +#ifndef BLUENRG_MS + /*********************************************************************** + * READ IFR data + ************************************************************************/ + for(int i = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_data+i); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + } +#endif + + /*********************************************************************** + * Erase & Flashing IFR sectors + ************************************************************************/ +#ifndef BLUENRG_MS + Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); +#endif + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(IFR_BASE_ADDRESS); + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += MAX_WRITE_BLOCK_SIZE, j += MAX_WRITE_BLOCK_SIZE) { + RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, MAX_WRITE_BLOCK_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); + if (ret != BLE_STATUS_SUCCESS) + break; + } + if (ret == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + + /*********************************************************************** + * Verify IFR + ************************************************************************/ + { + uint8_t ifr_updated[READ_BLOCK_SIZE]; + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE, j += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ifr_data+j, READ_BLOCK_SIZE) != 0) + return BLE_UTIL_WRONG_VERIFY; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) +{ + uint8_t ifr_updated[READ_BLOCK_SIZE]; + uint8_t version, ret = BLE_STATUS_SUCCESS; + + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + for(int i = 0; i < IFR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, READ_BLOCK_SIZE) != 0) + { + ret = BLE_UTIL_WRONG_VERIFY; + break; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return ret; +} + +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) +{ + uint8_t status; + uint8_t hci_version, lmp_pal_version; + uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; + + status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, + &manufacturer_name, &lmp_pal_subversion); + + if (status == BLE_STATUS_SUCCESS) { + *hwVersion = hci_revision >> 8; + *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number + *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number + *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number + } + + return status; +} + +uint8_t getBlueNRGUpdaterVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(version)) + return BLE_UTIL_ACI_ERROR; + + if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_updater_hw_version(version)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t isHWBootloader_Patched(void) +{ + uint8_t status, version; + uint32_t crc, address = 0x10010000; + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); + if (status != BLE_STATUS_SUCCESS) + return 0; + + if (crc == BOOTLOADER_CRC_NOT_PATCHED) + return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +#include "ble_gp_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function sets a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * @param[in] t A pointer to the timer + * @param[in] interval The interval before the timer expires. + * + */ +void +Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +Timer_Expired(struct timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + tClockTime diff = (Clock_Time() - t->start) + 1; + return t->interval < diff; + +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +tClockTime +Timer_Remaining(struct timer *t) +{ + return t->start + t->interval - Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +#ifdef __DMA_LP__ + +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID) +{ + TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, + (pf_TIMER_TimerCallBack_t) timercb); + TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); + + return (BLE_STATUS_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) +{ + TIMER_Delete(timerID); + + return (BLE_STATUS_SUCCESS); +} + +#endif /* __DMA_LP__ */ +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,119 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Circular Linked List Implementation. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/****************************************************************************** + * Include Files +******************************************************************************/ +#include <ble_hal_types.h> +#include "ble_list.h" + +/****************************************************************************** + * Function Definitions +******************************************************************************/ +void list_init_head (tListNode * listHead) +{ + listHead->next = listHead; + listHead->prev = listHead; +} + +uint8_t list_is_empty (tListNode * listHead) +{ + return ((listHead->next == listHead)? TRUE:FALSE); +} + +void list_insert_head (tListNode * listHead, tListNode * node) +{ + node->next = listHead->next; + node->prev = listHead; + listHead->next = node; + (node->next)->prev = node; +} + + +void list_insert_tail (tListNode * listHead, tListNode * node) +{ + node->next = listHead; + node->prev = listHead->prev; + listHead->prev = node; + (node->prev)->next = node; +} + + +void list_remove_node (tListNode * node) +{ + (node->prev)->next = node->next; + (node->next)->prev = node->prev; +} + + +void list_remove_head (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->next; + list_remove_node (listHead->next); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_remove_tail (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->prev; + list_remove_node (listHead->prev); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_insert_node_after (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node->next; + node->prev = ref_node; + ref_node->next = node; + (node->next)->prev = node; +} + + +void list_insert_node_before (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node; + node->prev = ref_node->prev; + ref_node->prev = node; + (node->prev)->next = node; +} + + +int list_get_size (tListNode * listHead) +{ + int size = 0; + tListNode * temp = listHead->next; + while (temp != listHead) + { + size++; + temp = temp->next; + } + return (size); +} + +void list_get_next_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->next; +} + + +void list_get_prev_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->prev; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,72 @@ +/** +****************************************************************************** +* @file ble_osal.c +* @author AMS - HEA&RF BU / CL +* @version V1.0.0 +* @date 04-July-2014 +* @brief Implementation of OS abstraction layer functions used by the +* library. +****************************************************************************** +* @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> +#include <ble_osal.h> + + /** + * @brief Osal_MemCpy + * @param dest: Pointer to the destination buffer + * @param src : Pointer to the source buffer + * @param size: Number of bytes to copy from the source to the destination + * buffer + * @retval Pointer to the destination buffer + */ +void* Osal_MemCpy(void *dest, const void *src, unsigned int size) +{ + return(memcpy(dest,src,size)); +} + +/** + * @brief Osal_MemSet + * @param ptr : Pointer to block of memory to fill + * @param value: Value to assign to each byte of the memory block + * @param size : Number of bytes to be set to "value" + * @retval Pointer to the filled block of memory + */ +void* Osal_MemSet(void *ptr, int value, unsigned int size) +{ + return(memset(ptr,value,size)); +} + +/****************************************************************************** + * local Functions + *****************************************************************************/ + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ + +#include "ble_clock.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/wait_api.h" + #include "mbed-drivers/rtc_time.h" +#else + #include "wait_api.h" + #include "rtc_time.h" +#endif + +const uint32_t CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + //Not Used +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return clock(); +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,715 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file btle.cpp + * @author STMicroelectronics + * @brief Implementation BlueNRG Init and helper functions. + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + + +#include "btle.h" +#include "ble/Gap.h" +#include "ble/GapEvents.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" + +#include "bluenrg_targets.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* C File Includes ------------------------------------------------------------------*/ +#include <stdio.h> +#include <string.h> +#include "ble_hci.h" +#include "ble_hci_const.h" +#include "bluenrg_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" +#include "bluenrg_utils.h" + +#include "ble_hal_types.h" +#include "ble_hal.h" +#include "ble_gp_timer.h" +#include "ble_osal.h" +#include "ble_sm.h" +#include "ble_debug.h" + +#ifdef __cplusplus +} +#endif + +#define IDB04A1 0 +#define IDB05A1 1 + +/* See file 'bluenrg_targets.h' for details regarding the BLUENRG_STACK_MODE */ +#define STACK_MODE BLUENRG_STACK_MODE + +void HCI_Input(tHciDataPacket * hciReadPacket); + +uint16_t g_gap_service_handle = 0; +uint16_t g_appearance_char_handle = 0; +uint16_t g_device_name_char_handle = 0; +uint16_t g_preferred_connection_parameters_char_handle = 0; + +/* Private variables ---------------------------------------------------------*/ +volatile uint8_t set_connectable = 1; + +static char versionString[32]; +uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ + +/**************************************************************************/ +/*! + @brief Init the BTLE stack with the specified role + @returns void +*/ +/**************************************************************************/ +void btleInit(void) +{ + PRINTF("btleInit>>\n\r"); + + int ret; + uint8_t hwVersion; + uint16_t fwVersion; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* get the BlueNRG HW and FW versions */ + getBlueNRGVersion(&hwVersion, &fwVersion); + + /* + * Reset BlueNRG again otherwise we won't + * be able to change its MAC address. + * aci_hal_write_config_data() must be the first + * command after reset otherwise it will fail. + */ + BlueNRG_RST(); + + if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ + bnrg_expansion_board = IDB05A1; + } + + /* set BLE version string */ + setVersionString(hwVersion, fwVersion); + + if (bnrg_expansion_board == IDB05A1) { + uint8_t stackMode = STACK_MODE; + ret = aci_hal_write_config_data(CONFIG_DATA_MODE_OFFSET, + CONFIG_DATA_MODE_LEN, + &stackMode); + } + + ret = aci_gatt_init(); + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GATT_Init failed.\n"); + } + if (bnrg_expansion_board == IDB05A1) { + ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1, + 0, + 0x18, + &service_handle, + &dev_name_char_handle, + &appearance_char_handle); + } else { + // IDB04A1 is configured as peripheral by default + ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + } + + // read the default static address and inject it into the GAP object + { + Gap::Address_t BLE_address_BE = { 0 }; + uint8_t data_len_out; + aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS, BDADDR_SIZE, &data_len_out, BLE_address_BE); + // FIXME error handling of this function + BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE); + } + + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GAP_Init failed.\n"); + } + + //FIXME: Security and passkey set by default + ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, + OOB_AUTH_DATA_ABSENT, + NULL, + 7, + 16, + USE_FIXED_PIN_FOR_PAIRING, + 123456, + BONDING); + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Auth Req set failed.\n"); + } + + aci_hal_set_tx_power_level(1,4); + + g_gap_service_handle = service_handle; + g_appearance_char_handle = appearance_char_handle; + g_device_name_char_handle = dev_name_char_handle; + //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API + /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, + strlen(name), (tHalUint8 *)name);*/ + + signalEventsToProcess(); + // update the peripheral preferred conenction parameters handle + // This value is hardcoded at the moment. + g_preferred_connection_parameters_char_handle = 10; + + return; +} + +/**************************************************************************/ +/*! + @brief mbedOS + + @param[in] void + + @returns +*/ +/**************************************************************************/ +int btle_handler_pending = 0; + +void btle_handler(void) +{ + btle_handler_pending = 0; + BlueNRGGap::getInstance().Process(); + HCI_HandleSPI(); + HCI_Process(); +} + +/* set BLE Version string */ +void setVersionString(uint8_t hwVersion, uint16_t fwVersion) +{ + if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) { + snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u", + hwVersion>>4, (hwVersion&0x0F), + fwVersion>>8, (fwVersion&0x00F0)>>4); + } else { + snprintf(versionString, sizeof(versionString), "ST (unknown spec)"); + } +} + +/* get BLE Version string */ +const char* getVersionString(void) +{ + return versionString; +} + +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type) +{ + tBleStatus ret; + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + if(bnrg_expansion_board == IDB05A1) { + PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window); + PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type); + ret = aci_gap_start_observation_procedure(scan_interval, + scan_window, + scan_type, + own_address_type, + 0); // 1 to filter duplicates + } else { + ret = BLE_STATUS_INVALID_CID; + } + + return ret; + +} + +/*! + @brief Not Used + + @param[in] void + + @returns +*/ +void SPI_Poll(void) +{ + //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); + return; +} + +void Attribute_Modified_CB(evt_blue_aci *blue_evt) +{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t *att_data; + uint8_t offset; + + if (bnrg_expansion_board == IDB05A1) { + evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = evt->offset; + } else { + evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = 0; + } + + //Extract the GattCharacteristic from p_characteristics[] and find the properties mask + GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle); + if(p_char!=NULL) { + GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE; + PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]); + PRINTF("getProperties 0x%x\n\r",p_char->getProperties()); + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; + } + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; + } + PRINTF("currentHandle %d\n\r", currentHandle); + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && + currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { + + GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1; + + PRINTF("*****NOTIFICATION CASE\n\r"); + //Now Check if data written in Enable or Disable + if((uint16_t)att_data[0]==1) { + //PRINTF("Notify ENABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle); + } else { + //PRINTF("Notify DISABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle); + } + return; + } + + //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) && + currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) { + + PRINTF("*****WRITE CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = p_char->getValueAttribute().getHandle(); + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle); + //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + BlueNRGGattServer::getInstance().write( + p_char->getValueAttribute().getHandle(), + (uint8_t*)att_data, + data_length, + false + ); + } + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } else { + PRINTF("*****WRITE DESCRIPTOR CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = attr_handle; + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } + } + +} + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************************/ + /*! + @brief Handle HCI Stack Event + + @param[in] pckt + Event Packet sent by the stack to be decoded + + @returns + */ + /**************************************************************************/ + extern void HCI_Event_CB(void *pckt) { + hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; + hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; + + if(hci_pckt->type != HCI_EVENT_PKT) + return; + + switch(event_pckt->evt){ + + case EVT_DISCONN_COMPLETE: + { + PRINTF("EVT_DISCONN_COMPLETE\n"); + + evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data; + + if(BlueNRGGap::getInstance().getGapRole() == Gap::CENTRAL) { + BlueNRGGattClient::getInstance().removeGattConnectionClient(evt->handle, evt->reason); + } + + BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason); + } + break; + + case EVT_LE_META_EVENT: + { + PRINTF("EVT_LE_META_EVENT\n"); + + evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; + + switch(evt->subevent){ + + case EVT_LE_CONN_COMPLETE: + { + PRINTF("EVT_LE_CONN_COMPLETE\n"); + Gap::Address_t ownAddr; + Gap::AddressType_t ownAddrType; + BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr); + + Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + Gap::Role_t role; + + evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; + + BlueNRGGap::getInstance().setConnectionHandle(cc->handle); + BlueNRGGap::ConnectionParams_t connectionParams = { + /* minConnectionInterval = */ cc->interval, + /* maxConnectionInterval = */ cc->interval, + /* slaveLatency = */ cc->latency, + /* connectionSupervisionTimeout = */ cc->supervision_timeout + }; + + BlueNRGGap::getInstance().setConnectionInterval(cc->interval); + + switch (cc->peer_bdaddr_type) { + case PUBLIC_ADDR: + peerAddrType = BLEProtocol::AddressType::PUBLIC; + break; + case STATIC_RANDOM_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + break; + case RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE; + break; + case NON_RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE; + break; + } + //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role); + switch (cc->role) { + case 0: //master + role = Gap::CENTRAL; + BlueNRGGattClient::getInstance().createGattConnectionClient(cc->handle); + break; + case 1: + role = Gap::PERIPHERAL; + break; + default: + role = Gap::PERIPHERAL; + break; + } + + BlueNRGGap::getInstance().setGapRole(role); + + BlueNRGGap::getInstance().processConnectionEvent(cc->handle, + role, + peerAddrType, + cc->peer_bdaddr, + ownAddrType, + ownAddr, + &connectionParams); + } + break; + + case EVT_LE_ADVERTISING_REPORT: + PRINTF("EVT_LE_ADVERTISING_REPORT\n\r"); + /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */ + // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT) + // Formally the structure related to both events are identical except that for the ADV REPORT + // there is one more field (number of reports) which is not forwarded to upper layer. + // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT. + le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1); + PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + break; + } + } + break; + + case EVT_VENDOR: + { + evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; + //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode); + + switch(blue_evt->ecode){ + + case EVT_BLUE_GATT_WRITE_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_WRITE_PERMIT_REQ\r\n"); + evt_gatt_write_permit_req* write_req = (evt_gatt_write_permit_req*)blue_evt->data; + + // ask the local server if the write operation is authorized + uint8_t err_code = BlueNRGGattServer::getInstance().Write_Request_CB( + write_req->conn_handle, + write_req->attr_handle, + write_req->data_length, + write_req->data + ); + uint8_t write_status = err_code == 0 ? 0 : 1; + + // reply to the shield + aci_gatt_write_response( + write_req->conn_handle, + write_req->attr_handle, + write_status, + err_code, + write_req->data_length, + write_req->data + ); + } + break; + + case EVT_BLUE_GATT_READ_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r"); + evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle); + BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle); + } + break; + + case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: + { + PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r"); + /* this callback is invoked when a GATT attribute is modified + extract callback data and pass to suitable handler function */ + Attribute_Modified_CB(blue_evt); + } + break; + + //Any cases for Data Sent Notifications? + case EVT_BLUE_GATT_NOTIFICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_NOTIFICATION"); + break; + case EVT_BLUE_GATT_INDICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_INDICATION"); + break; + + case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r"); + evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_data_length, + pr->attribute_data_list); + } + break; + case EVT_BLUE_ATT_READ_BY_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r"); + evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle, + pr->event_data_length, + pr->handle_value_pair_length, + pr->handle_value_pair); + } + break; + case EVT_BLUE_ATT_READ_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_RESP\n\r"); + evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_value); + } + break; + case EVT_BLUE_ATT_EXEC_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle, + pr->event_data_length); + } + break; + case EVT_BLUE_ATT_PREPARE_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_handle, + pr->offset, + pr->part_attr_value); + } + break; + case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP: + { + PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r"); + evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle, + pr->event_data_length, + pr->attr_handle, + pr->attr_value); + } + break; + case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r"); + evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle, + pr->event_data_length, + pr->handles_info_list); + } + break; + case EVT_BLUE_ATT_FIND_INFORMATION_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r"); + evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle, + pr->event_data_length, + pr->format, + pr->handle_uuid_pair); + } + break; + case EVT_BLUE_GATT_PROCEDURE_COMPLETE: + { + evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code); + BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code); + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_REQ: + { + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_REQ\r\n"); + evt_l2cap_conn_upd_req *evt = (evt_l2cap_conn_upd_req*)blue_evt->data; + if(bnrg_expansion_board == IDB05A1) { + // we assume the application accepts the request from the slave + aci_l2cap_connection_parameter_update_response_IDB05A1(evt->conn_handle, + evt->interval_min, + evt->interval_max, + evt->slave_latency, + evt->timeout_mult, + CONN_L1, CONN_L2, + evt->identifier, + 0x0000); + } + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_RESP: + { + evt_l2cap_conn_upd_resp *evt = (evt_l2cap_conn_upd_resp*)blue_evt->data; + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_RESP code=0x%x, result=0x%x\r\n", evt->code, evt->result); + } + break; + + case EVT_LE_CONN_UPDATE_COMPLETE: + { + evt_le_connection_update_complete *evt = (evt_le_connection_update_complete*)blue_evt->data; + PRINTF("EVT_LE_CONN_UPDATE_COMPLETE status=0x%x\r\n", evt->status); + } + break; + + case EVT_BLUE_GAP_DEVICE_FOUND: + { + evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data; + PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + } + break; + + case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + { + evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data; + //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code); + + switch(pr->procedure_code) { + case GAP_OBSERVATION_PROC_IDB05A1: + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL); + break; + } + } + break; + } + } + break; + } + return ; + } + + +#ifdef __cplusplus +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,217 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.cpp + * @author CL + * @version V1.0.0 + * @date 15-June-2015 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRGGap.h" +#include "BlueNRGDevice.h" +#include "btle.h" + +// FIXME: find a better way to get the instance of the BlueNRG device +extern BlueNRGDevice bluenrgDeviceInstance; + + +//////////////////////////////////////// +// Start of C function wrappers +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32_bluenrg_ble.h" +#include "ble_debug.h" + + +void BlueNRG_RST(void) +{ + bluenrgDeviceInstance.reset(); +} + +uint8_t BlueNRG_DataPresent(void) +{ + return (bluenrgDeviceInstance.dataPresent()); +} + + +/** + * @brief This function is a utility to print the log time +* in the format HH:MM:SS:MSS (DK GUI time format) + * @param None + * @retval None + */ +void print_csv_time(void){ +#ifdef PRINT_CSV_FORMAT + uint32_t ms = 0;//ms_counter; + PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000); +#endif +} + +/** + * @brief Writes data to a serial interface. + * @param data1 : 1st buffer + * @param data2 : 2nd buffer + * @param n_bytes1: number of bytes in 1st buffer + * @param n_bytes2: number of bytes in 2nd buffer + * @retval None + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, + int32_t n_bytes2) +{ + struct timer t; + + Timer_Set(&t, CLOCK_SECOND/10); + +#ifdef PRINT_CSV_FORMAT + print_csv_time(); + for (int i=0; i<n_bytes1; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data1)[i]); + } + for (int i=0; i<n_bytes2; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data2)[i]); + } + PRINT_CSV("\n"); +#endif + + while(1){ + if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; + if(Timer_Expired(&t)){ + break; + } + } +} + + +/** + * @brief Activate internal bootloader using pin. + * @param None + * @retval None + */ +void BlueNRG_HW_Bootloader(void) +{ + // Reset BlueNRG SPI interface + BlueNRG_RST(); + + // Send an ACI command to reboot BlueNRG in bootloader mode + // The safest way to get in bootloader mode is keeping high + // the interrupt pin during reset, but this would require many + // changes to the current mbed driver + aci_updater_start(); +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size) +{ + int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size); + + return ret; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2); + + return ret; +} + +/** + * @brief Enable SPI IRQ. + * @param None + * @retval None + */ +void Enable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.enable_irq(); +} + +void signalEventsToProcess(void) { + if(btle_handler_pending == 0) { + btle_handler_pending = 1; + bluenrgDeviceInstance.signalEventsToProcess(BLE::DEFAULT_INSTANCE); + } +} + +/** + * @brief Disable SPI IRQ. + * @param None + * @retval None + */ +void Disable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.disable_irq(); +} + +/** + * @brief Clear Pending SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_IRQ(void) +{ +} + +/** + * @brief Clear EXTI (External Interrupt) line for SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_EXTI_Flag(void) +{ +} + + + + +#ifdef __cplusplus +} +#endif +// End of C function wrappers +//////////////////////////////////////// + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <ble_payload.h> + +Payload::Payload() { + stringLength = 0; + payloadUnitCount = 0; + payload = NULL; +} + +Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + stringLength = string_ength; + payloadUnitCount = 0; + payload = NULL; + + int index = 0; + while( index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + UnitPayload *obj = new UnitPayload[payloadUnitCount]; + int i=0; + int c=0; + int j,k; + + while(i<payloadUnitCount) + { + obj[i].length=tokenString[c]; + obj[i].id=tokenString[c+1]; + + obj[i].data = new uint8_t[obj[i].length]; + for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) + { + obj[i].data[k]=tokenString[j]; + + } + + c=c+obj[i].length+1; + i++; + + } + payload = obj; +} + +uint8_t Payload::getPayloadUnitCount() { + return payloadUnitCount; +} + +uint8_t Payload::getIDAtIndex(int index) { + return payload[index].get_id(); +} + +uint8_t Payload::getLengthAtIndex(int index) { + return payload[index].get_length(); +} + +uint8_t* Payload::getDataAtIndex(int index) { + return payload[index].get_data(); +} + +int8_t Payload::getInt8AtIndex(int index) { + uint8_t* str = payload[index].get_data(); + int8_t value = (int8_t)str[0]; + return value; +} + +uint16_t Payload::getUint16AtIndex(int index) { + uint16_t* str = (uint16_t*)payload[index].get_data(); + uint16_t value = str[0]; + return value; +} + +uint8_t* Payload::getSerializedAdDataAtIndex(int index) { + uint8_t length = payload[index].get_length(); + uint8_t* data = payload[index].get_data(); + uint8_t id = payload[index].get_id(); + uint8_t *serializedAdData = new uint8_t[length]; + + serializedAdData[0] = id; + for(int i=0; i<length-1; i++) { + serializedAdData[i+1] = data[i]; + } + return serializedAdData; +} + +Payload::~Payload() { + int i = 0; + + if(payload) { + while(i<payloadUnitCount) { + if(payload->data) { + delete[] payload->data; + payload->data = NULL; + } + } + delete[] payload; + payload = NULL; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,93 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ble_utils.h" + +/**************************************************************************/ +/*! + @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power + +*/ +/**************************************************************************/ +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(dBMLevel==-18) { + EN_HIGH_POWER = 0; + PA_LEVEL = 0; + } + else if(dBMLevel==-15) { + EN_HIGH_POWER = 0; + PA_LEVEL = 1; + } + else if(dBMLevel==-14) { + EN_HIGH_POWER = 1; + PA_LEVEL = 0; + } + else if(dBMLevel==-12) { + EN_HIGH_POWER = 0; + PA_LEVEL = 2; + } + else if(dBMLevel==-11) { + EN_HIGH_POWER = 1; + PA_LEVEL = 1; + } + else if(dBMLevel==-9) { + EN_HIGH_POWER = 0; + PA_LEVEL = 3; + } + else if(dBMLevel==-8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 2; + } + else if(dBMLevel==-6) { + EN_HIGH_POWER = 0; + PA_LEVEL = 4; + } + else if(dBMLevel==-5) { + EN_HIGH_POWER = 1; + PA_LEVEL = 3; + } + else if(dBMLevel==-2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 4; + } + else if(dBMLevel==0) { + EN_HIGH_POWER = 0; + PA_LEVEL = 6; + } + else if(dBMLevel==2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 5; + } + else if(dBMLevel==4) { + EN_HIGH_POWER = 1; + PA_LEVEL = 6; + } + else if(dBMLevel==5) { + EN_HIGH_POWER = 0; + PA_LEVEL = 7; + } + else if(dBMLevel==8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + else { + ret = ERR_INVALID_HCI_CMD_PARAMS; + } + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GAPButton/source/main.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,209 @@ +/* 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 <events/mbed_events.h> +#include <mbed.h> +#include "ble/BLE.h" + +DigitalOut led1(LED1, 1); +InterruptIn button(BLE_BUTTON_PIN_NAME); +uint8_t cnt; + +// Change your device name below +const char DEVICE_NAME[] = "GAPButton"; + +/* We can arbiturarily choose the GAPButton service UUID to be 0xAA00 + * as long as it does not overlap with the UUIDs defined here: + * https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx */ +#define GAPButtonUUID 0xAA00 +const uint16_t uuid16_list[] = {GAPButtonUUID}; + +static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); + +void print_error(ble_error_t error, const char* msg) +{ + printf("%s: ", msg); + switch(error) { + case BLE_ERROR_NONE: + printf("BLE_ERROR_NONE: No error"); + break; + case BLE_ERROR_BUFFER_OVERFLOW: + printf("BLE_ERROR_BUFFER_OVERFLOW: The requested action would cause a buffer overflow and has been aborted"); + break; + case BLE_ERROR_NOT_IMPLEMENTED: + printf("BLE_ERROR_NOT_IMPLEMENTED: Requested a feature that isn't yet implement or isn't supported by the target HW"); + break; + case BLE_ERROR_PARAM_OUT_OF_RANGE: + printf("BLE_ERROR_PARAM_OUT_OF_RANGE: One of the supplied parameters is outside the valid range"); + break; + case BLE_ERROR_INVALID_PARAM: + printf("BLE_ERROR_INVALID_PARAM: One of the supplied parameters is invalid"); + break; + case BLE_STACK_BUSY: + printf("BLE_STACK_BUSY: The stack is busy"); + break; + case BLE_ERROR_INVALID_STATE: + printf("BLE_ERROR_INVALID_STATE: Invalid state"); + break; + case BLE_ERROR_NO_MEM: + printf("BLE_ERROR_NO_MEM: Out of Memory"); + break; + case BLE_ERROR_OPERATION_NOT_PERMITTED: + printf("BLE_ERROR_OPERATION_NOT_PERMITTED"); + break; + case BLE_ERROR_INITIALIZATION_INCOMPLETE: + printf("BLE_ERROR_INITIALIZATION_INCOMPLETE"); + break; + case BLE_ERROR_ALREADY_INITIALIZED: + printf("BLE_ERROR_ALREADY_INITIALIZED"); + break; + case BLE_ERROR_UNSPECIFIED: + printf("BLE_ERROR_UNSPECIFIED: Unknown error"); + break; + case BLE_ERROR_INTERNAL_STACK_FAILURE: + printf("BLE_ERROR_INTERNAL_STACK_FAILURE: internal stack faillure"); + break; + } + printf("\r\n"); +} + +void updatePayload(void) +{ + // Update the count in the SERVICE_DATA field of the advertising payload + uint8_t service_data[3]; + service_data[0] = GAPButtonUUID & 0xff; + service_data[1] = GAPButtonUUID >> 8; + service_data[2] = cnt; // Put the button click count in the third byte + ble_error_t err = BLE::Instance().gap().updateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)service_data, sizeof(service_data)); + if (err != BLE_ERROR_NONE) { + print_error(err, "Updating payload failed"); + } +} + +void buttonPressedCallback(void) +{ + ++cnt; + + // Calling BLE api in interrupt context may cause race conditions + // Using mbed-events to schedule calls to BLE api for safety + eventQueue.call(updatePayload); +} + +void blinkCallback(void) +{ + led1 = !led1; +} + +void printMacAddress() +{ + /* Print out device MAC address to the console*/ + Gap::AddressType_t addr_type; + Gap::Address_t address; + BLE::Instance().gap().getAddress(&addr_type, address); + printf("DEVICE MAC ADDRESS: "); + for (int i = 5; i >= 1; i--){ + printf("%02x:", address[i]); + } + printf("%02x\r\n", address[0]); +} + +void bleInitComplete(BLE::InitializationCompleteCallbackContext *context) +{ + BLE& ble = context->ble; + ble_error_t err = context->error; + + if (err != BLE_ERROR_NONE) { + print_error(err, "BLE initialisation failed"); + return; + } + + // Set up the advertising flags. Note: not all combination of flags are valid + // BREDR_NOT_SUPPORTED: Device does not support Basic Rate or Enchanced Data Rate, It is Low Energy only. + // LE_GENERAL_DISCOVERABLE: Peripheral device is discoverable at any moment + err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + if (err != BLE_ERROR_NONE) { + print_error(err, "Setting GAP flags failed"); + return; + } + + // Put the device name in the advertising payload + err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + if (err != BLE_ERROR_NONE) { + print_error(err, "Setting device name failed"); + return; + } + + err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + if (err != BLE_ERROR_NONE) { + print_error(err, "Setting service UUID failed"); + return; + } + + // The Service Data data type consists of a service UUID with the data associated with that service. + // We will encode the number of button clicks in the Service Data field + // First two bytes of SERVICE_DATA field should contain the UUID of the service + uint8_t service_data[3]; + service_data[0] = GAPButtonUUID & 0xff; + service_data[1] = GAPButtonUUID >> 8; + service_data[2] = cnt; // Put the button click count in the third byte + err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)service_data, sizeof(service_data)); + if (err != BLE_ERROR_NONE) { + print_error(err, "Setting service data failed"); + return; + } + + // It is not connectable as we are just boardcasting + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); + + // Send out the advertising payload every 1000ms + ble.gap().setAdvertisingInterval(1000); + + err = ble.gap().startAdvertising(); + if (err != BLE_ERROR_NONE) { + print_error(err, "Start advertising failed"); + return; + } + + printMacAddress(); +} + +void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { + BLE &ble = BLE::Instance(); + eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); +} + +int main() +{ + cnt = 0; + + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(scheduleBleEventsProcessing); + ble_error_t err = ble.init(bleInitComplete); + if (err != BLE_ERROR_NONE) { + print_error(err, "BLE initialisation failed"); + return 0; + } + + // Blink LED every 500 ms to indicate system aliveness + eventQueue.call_every(500, blinkCallback); + + // Register function to be called when button is released + button.rise(buttonPressedCallback); + + eventQueue.dispatch_forever(); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/.mbed Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,3 @@ +ROOT=. +TARGET=NRF52_DK +TOOLCHAIN=GCC_ARM
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/BLEProcess.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,206 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 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 GATT_SERVER_EXAMPLE_BLE_PROCESS_H_ +#define GATT_SERVER_EXAMPLE_BLE_PROCESS_H_ + +#include <stdint.h> +#include <stdio.h> + +#include "events/EventQueue.h" +#include "platform/Callback.h" +#include "platform/NonCopyable.h" + +#include "ble/BLE.h" +#include "ble/Gap.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/FunctionPointerWithContext.h" + +/** + * Handle initialization adn shutdown of the BLE Instance. + * + * Setup advertising payload and manage advertising state. + * Delegate to GattClientProcess once the connection is established. + */ +class BLEProcess : private mbed::NonCopyable<BLEProcess> { +public: + /** + * Construct a BLEProcess from an event queue and a ble interface. + * + * Call start() to initiate ble processing. + */ + BLEProcess(events::EventQueue &event_queue, BLE &ble_interface) : + _event_queue(event_queue), + _ble_interface(ble_interface), + _post_init_cb() { + } + + ~BLEProcess() + { + stop(); + } + + /** + * Subscription to the ble interface initialization event. + * + * @param[in] cb The callback object that will be called when the ble + * interface is initialized. + */ + void on_init(mbed::Callback<void(BLE&, events::EventQueue&)> cb) + { + _post_init_cb = cb; + } + + /** + * Initialize the ble interface, configure it and start advertising. + */ + bool start() + { + printf("Ble process started.\r\n"); + + if (_ble_interface.hasInitialized()) { + printf("Error: the ble instance has already been initialized.\r\n"); + return false; + } + + _ble_interface.onEventsToProcess( + makeFunctionPointer(this, &BLEProcess::schedule_ble_events) + ); + + ble_error_t error = _ble_interface.init( + this, &BLEProcess::when_init_complete + ); + + if (error) { + printf("Error: %u returned by BLE::init.\r\n", error); + return false; + } + + return true; + } + + /** + * Close existing connections and stop the process. + */ + void stop() + { + if (_ble_interface.hasInitialized()) { + _ble_interface.shutdown(); + printf("Ble process stopped."); + } + } + +private: + + /** + * Schedule processing of events from the BLE middleware in the event queue. + */ + void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *event) + { + _event_queue.call(mbed::callback(&event->ble, &BLE::processEvents)); + } + + /** + * Sets up adverting payload and start advertising. + * + * This function is invoked when the ble interface is initialized. + */ + void when_init_complete(BLE::InitializationCompleteCallbackContext *event) + { + if (event->error) { + printf("Error %u during the initialization\r\n", event->error); + return; + } + printf("Ble instance initialized\r\n"); + + Gap &gap = _ble_interface.gap(); + ble_error_t error = gap.setAdvertisingPayload(make_advertising_data()); + if (error) { + printf("Error %u during gap.setAdvertisingPayload\r\n", error); + return; + } + + gap.setAdvertisingParams(make_advertising_params()); + + gap.onConnection(this, &BLEProcess::when_connection); + gap.onDisconnection(this, &BLEProcess::when_disconnection); + + start_advertising(); + + if (_post_init_cb) { + _post_init_cb(_ble_interface, _event_queue); + } + } + + void when_connection(const Gap::ConnectionCallbackParams_t *connection_event) + { + printf("Connected.\r\n"); + } + + void when_disconnection(const Gap::DisconnectionCallbackParams_t *event) + { + printf("Disconnected.\r\n"); + start_advertising(); + } + + void start_advertising(void) + { + ble_error_t error = _ble_interface.gap().startAdvertising(); + if (error) { + printf("Error %u during gap.startAdvertising.\r\n", error); + return; + } else { + printf("Advertising started.\r\n"); + } + } + + static GapAdvertisingData make_advertising_data(void) + { + static const uint8_t device_name[] = "GattServer"; + GapAdvertisingData advertising_data; + + // add advertising flags + advertising_data.addFlags( + GapAdvertisingData::LE_GENERAL_DISCOVERABLE | + GapAdvertisingData::BREDR_NOT_SUPPORTED + ); + + // add device name + advertising_data.addData( + GapAdvertisingData::COMPLETE_LOCAL_NAME, + device_name, + sizeof(device_name) + ); + + return advertising_data; + } + + static GapAdvertisingParams make_advertising_params(void) + { + return GapAdvertisingParams( + /* type */ GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, + /* interval */ GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(500), + /* timeout */ 0 + ); + } + + events::EventQueue &_event_queue; + BLE &_ble_interface; + mbed::Callback<void(BLE&, events::EventQueue&)> _post_init_cb; +}; + +#endif /* GATT_SERVER_EXAMPLE_BLE_PROCESS_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/main.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,411 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 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 <stdio.h> + +#include "platform/Callback.h" +#include "events/EventQueue.h" +#include "platform/NonCopyable.h" + +#include "ble/BLE.h" +#include "ble/Gap.h" +#include "ble/GattClient.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/GattServer.h" +#include "BLEProcess.h" + +using mbed::callback; + +/** + * A Clock service that demonstrate the GattServer features. + * + * The clock service host three characteristics that model the current hour, + * minute and second of the clock. The value of the second characteristic is + * incremented automatically by the system. + * + * A client can subscribe to updates of the clock characteristics and get + * notified when one of the value is changed. Clients can also change value of + * the second, minute and hour characteristric. + */ +class ClockService { + typedef ClockService Self; + +public: + ClockService() : + _hour_char("485f4145-52b9-4644-af1f-7a6b9322490f", 0), + _minute_char("0a924ca7-87cd-4699-a3bd-abdcd9cf126a", 0), + _second_char("8dd6a1b7-bc75-4741-8a26-264af75807de", 0), + _clock_service( + /* uuid */ "51311102-030e-485f-b122-f8f381aa84ed", + /* characteristics */ _clock_characteristics, + /* numCharacteristics */ sizeof(_clock_characteristics) / + sizeof(_clock_characteristics[0]) + ), + _server(NULL), + _event_queue(NULL) + { + // update internal pointers (value, descriptors and characteristics array) + _clock_characteristics[0] = &_hour_char; + _clock_characteristics[1] = &_minute_char; + _clock_characteristics[2] = &_second_char; + + // setup authorization handlers + _hour_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); + _minute_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); + _second_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); + } + + + + void start(BLE &ble_interface, events::EventQueue &event_queue) + { + if (_event_queue) { + return; + } + + _server = &ble_interface.gattServer(); + _event_queue = &event_queue; + + // register the service + printf("Adding demo service\r\n"); + ble_error_t err = _server->addService(_clock_service); + + if (err) { + printf("Error %u during demo service registration.\r\n", err); + return; + } + + // read write handler + _server->onDataSent(as_cb(&Self::when_data_sent)); + _server->onDataWritten(as_cb(&Self::when_data_written)); + _server->onDataRead(as_cb(&Self::when_data_read)); + + // updates subscribtion handlers + _server->onUpdatesEnabled(as_cb(&Self::when_update_enabled)); + _server->onUpdatesDisabled(as_cb(&Self::when_update_disabled)); + _server->onConfirmationReceived(as_cb(&Self::when_confirmation_received)); + + // print the handles + printf("clock service registered\r\n"); + printf("service handle: %u\r\n", _clock_service.getHandle()); + printf("\thour characteristic value handle %u\r\n", _hour_char.getValueHandle()); + printf("\tminute characteristic value handle %u\r\n", _minute_char.getValueHandle()); + printf("\tsecond characteristic value handle %u\r\n", _second_char.getValueHandle()); + + _event_queue->call_every(1000 /* ms */, callback(this, &Self::increment_second)); + } + +private: + + /** + * Handler called when a notification or an indication has been sent. + */ + void when_data_sent(unsigned count) + { + printf("sent %u updates\r\n", count); + } + + /** + * Handler called after an attribute has been written. + */ + void when_data_written(const GattWriteCallbackParams *e) + { + printf("data written:\r\n"); + printf("\tconnection handle: %u\r\n", e->connHandle); + printf("\tattribute handle: %u", e->handle); + if (e->handle == _hour_char.getValueHandle()) { + printf(" (hour characteristic)\r\n"); + } else if (e->handle == _minute_char.getValueHandle()) { + printf(" (minute characteristic)\r\n"); + } else if (e->handle == _second_char.getValueHandle()) { + printf(" (second characteristic)\r\n"); + } else { + printf("\r\n"); + } + printf("\twrite operation: %u\r\n", e->writeOp); + printf("\toffset: %u\r\n", e->offset); + printf("\tlength: %u\r\n", e->len); + printf("\t data: "); + + for (size_t i = 0; i < e->len; ++i) { + printf("%02X", e->data[i]); + } + + printf("\r\n"); + } + + /** + * Handler called after an attribute has been read. + */ + void when_data_read(const GattReadCallbackParams *e) + { + printf("data read:\r\n"); + printf("\tconnection handle: %u\r\n", e->connHandle); + printf("\tattribute handle: %u", e->handle); + if (e->handle == _hour_char.getValueHandle()) { + printf(" (hour characteristic)\r\n"); + } else if (e->handle == _minute_char.getValueHandle()) { + printf(" (minute characteristic)\r\n"); + } else if (e->handle == _second_char.getValueHandle()) { + printf(" (second characteristic)\r\n"); + } else { + printf("\r\n"); + } + } + + /** + * Handler called after a client has subscribed to notification or indication. + * + * @param handle Handle of the characteristic value affected by the change. + */ + void when_update_enabled(GattAttribute::Handle_t handle) + { + printf("update enabled on handle %d\r\n", handle); + } + + /** + * Handler called after a client has cancelled his subscription from + * notification or indication. + * + * @param handle Handle of the characteristic value affected by the change. + */ + void when_update_disabled(GattAttribute::Handle_t handle) + { + printf("update disabled on handle %d\r\n", handle); + } + + /** + * Handler called when an indication confirmation has been received. + * + * @param handle Handle of the characteristic value that has emitted the + * indication. + */ + void when_confirmation_received(GattAttribute::Handle_t handle) + { + printf("confirmation received on handle %d\r\n", handle); + } + + /** + * Handler called when a write request is received. + * + * This handler verify that the value submitted by the client is valid before + * authorizing the operation. + */ + void authorize_client_write(GattWriteAuthCallbackParams *e) + { + printf("characteristic %u write authorization\r\n", e->handle); + + if (e->offset != 0) { + printf("Error invalid offset\r\n"); + e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; + return; + } + + if (e->len != 1) { + printf("Error invalid len\r\n"); + e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; + return; + } + + if ((e->data[0] >= 60) || + ((e->data[0] >= 24) && (e->handle == _hour_char.getValueHandle()))) { + printf("Error invalid data\r\n"); + e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED; + return; + } + + e->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; + } + + /** + * Increment the second counter. + */ + void increment_second(void) + { + uint8_t second = 0; + ble_error_t err = _second_char.get(*_server, second); + if (err) { + printf("read of the second value returned error %u\r\n", err); + return; + } + + second = (second + 1) % 60; + + err = _second_char.set(*_server, second); + if (err) { + printf("write of the second value returned error %u\r\n", err); + return; + } + + if (second == 0) { + increment_minute(); + } + } + + /** + * Increment the minute counter. + */ + void increment_minute(void) + { + uint8_t minute = 0; + ble_error_t err = _minute_char.get(*_server, minute); + if (err) { + printf("read of the minute value returned error %u\r\n", err); + return; + } + + minute = (minute + 1) % 60; + + err = _minute_char.set(*_server, minute); + if (err) { + printf("write of the minute value returned error %u\r\n", err); + return; + } + + if (minute == 0) { + increment_hour(); + } + } + + /** + * Increment the hour counter. + */ + void increment_hour(void) + { + uint8_t hour = 0; + ble_error_t err = _hour_char.get(*_server, hour); + if (err) { + printf("read of the hour value returned error %u\r\n", err); + return; + } + + hour = (hour + 1) % 24; + + err = _hour_char.set(*_server, hour); + if (err) { + printf("write of the hour value returned error %u\r\n", err); + return; + } + } + +private: + /** + * Helper that construct an event handler from a member function of this + * instance. + */ + template<typename Arg> + FunctionPointerWithContext<Arg> as_cb(void (Self::*member)(Arg)) + { + return makeFunctionPointer(this, member); + } + + /** + * Read, Write, Notify, Indicate Characteristic declaration helper. + * + * @tparam T type of data held by the characteristic. + */ + template<typename T> + class ReadWriteNotifyIndicateCharacteristic : public GattCharacteristic { + public: + /** + * Construct a characteristic that can be read or written and emit + * notification or indication. + * + * @param[in] uuid The UUID of the characteristic. + * @param[in] initial_value Initial value contained by the characteristic. + */ + ReadWriteNotifyIndicateCharacteristic(const UUID & uuid, const T& initial_value) : + GattCharacteristic( + /* UUID */ uuid, + /* Initial value */ &_value, + /* Value size */ sizeof(_value), + /* Value capacity */ sizeof(_value), + /* Properties */ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE, + /* Descriptors */ NULL, + /* Num descriptors */ 0, + /* variable len */ false + ), + _value(initial_value) { + } + + /** + * Get the value of this characteristic. + * + * @param[in] server GattServer instance that contain the characteristic + * value. + * @param[in] dst Variable that will receive the characteristic value. + * + * @return BLE_ERROR_NONE in case of success or an appropriate error code. + */ + ble_error_t get(GattServer &server, T& dst) const + { + uint16_t value_length = sizeof(dst); + return server.read(getValueHandle(), &dst, &value_length); + } + + /** + * Assign a new value to this characteristic. + * + * @param[in] server GattServer instance that will receive the new value. + * @param[in] value The new value to set. + * @param[in] local_only Flag that determine if the change should be kept + * locally or forwarded to subscribed clients. + */ + ble_error_t set( + GattServer &server, const uint8_t &value, bool local_only = false + ) const { + return server.write(getValueHandle(), &value, sizeof(value), local_only); + } + + private: + uint8_t _value; + }; + + ReadWriteNotifyIndicateCharacteristic<uint8_t> _hour_char; + ReadWriteNotifyIndicateCharacteristic<uint8_t> _minute_char; + ReadWriteNotifyIndicateCharacteristic<uint8_t> _second_char; + + // list of the characteristics of the clock service + GattCharacteristic* _clock_characteristics[3]; + + // demo service + GattService _clock_service; + + GattServer* _server; + events::EventQueue *_event_queue; +}; + +int main() { + BLE &ble_interface = BLE::Instance(); + events::EventQueue event_queue; + ClockService demo_service; + BLEProcess ble_process(event_queue, ble_interface); + + ble_process.on_init(callback(&demo_service, &ClockService::start)); + + // bind the event queue to the ble interface, initialize the interface + // and start advertising + ble_process.start(); + + // Process the event queue. + event_queue.dispatch_forever(); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/mbed-os.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/mbed_app.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "target_overrides": { + "K64F": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "NUCLEO_F401RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "DISCO_L475VG_IOT01A": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + } + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/#b630517008bbe47592927cc8e5dfcd2e5b9de968
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/.gitignore Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,9 @@ +# vim temporary files +*.sw* + +# yotta files +build +yotta_modules +yotta_targets +.yotta.json +upload.tar.gz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,34 @@ +# BLE-X-NUCLEO-IDB0XA1 + +BLE_API wrapper Library for X-NUCLEO-IDB05A1 BlueNRG (Bluetooth Low Energy) Expansion Board + +## Introduction + +This firmware package implements the port of BLE_API to STMicroelectronics' [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) Bluetooth Low Energy Nucleo Expansion Board. + +### Arduino Connector Compatibility Warning + +X-NUCLEO-IDB05A1 is Arduino compatible with an exception: instead of using pin **D13** for the SPI clock, pin **D3** is used. +The default configuration for this library is having the SPI clock on pin **D3**. + +To be fully Arduino compatible, X-NUCLEO-IDB05A1 needs a small HW patch. + +For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor **R4** and instead soldering zero resistor **R6**. + +In case you patch your board, then you also have to configure this library to use pin **D13** to drive the SPI clock. To this aim you need to compile this driver with macro `BLUENRG_PIN_SPI_SCK=D13` defined. + +If you use pin **D13** for the SPI clock, please be aware that on STM32 Nucleo boards you may **not** drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin **D13**. + +Referring to the current list of tested platforms (see [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) page), the patch is required by [ST-Nucleo-F103RB](https://developer.mbed.org/platforms/ST-Nucleo-F103RB/); [ST-Nucleo-F302R8](https://developer.mbed.org/platforms/ST-Nucleo-F302R8/); [ST-Nucleo-F411RE](https://developer.mbed.org/platforms/ST-Nucleo-F411RE/); [ST-Nucleo-F446RE](https://developer.mbed.org/platforms/ST-Nucleo-F446RE/); and [FRDM-K64F](https://developer.mbed.org/platforms/FRDM-K64F/). + +### Firmware update + +For better performance and compatibility with latest mbed API, you should update firmware of X-NUCLEO-IDB05A1 component by using this simple [application](https://developer.mbed.org/teams/ST/code/BlueNRG-MS-Stack-Updater). + +### Driver configuration + +In order to use the BlueNRG-MS module together with other targets, you need to set the macros defined in file [bluenrg_targets.h](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/bluenrg/bluenrg_targets.h). Please, update the [mbed_lib.json](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/mbed_lib.json) to include the list of extra macros that configure the driver for your target. + +## Example Applications + +To run BLE example applications using X-NUCLEO-IDB05A1 Expansion Board based on mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli), please refer to section [Using ST shield on other targets](https://github.com/ARMmbed/mbed-os-example-ble#using-st-nucleo-shield-on-other-targets) in the official [mbed-os-example-ble](https://github.com/ARMmbed/mbed-os-example-ble) page.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.h + * @author STMicroelectronics + * @brief Header file for BLEDeviceInstanceBase based BlueNRGDevice + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_DEVICE_H__ +#define __BLUENRG_DEVICE_H__ + +#define BLUENRG +#define DEBUG_BLUENRG_USER + +#include "btle.h" + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "ble/BLEInstanceBase.h" +#include "ble/BLE.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" + + +class BlueNRGDevice : public BLEInstanceBase +{ + +public: + BlueNRGDevice(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, PinName irq); + virtual ~BlueNRGDevice(void); + + virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback); + virtual ble_error_t shutdown(void); + virtual const char *getVersion(void); + virtual Gap& getGap(); + virtual const Gap& getGap() const; + virtual GattServer& getGattServer(); + virtual const GattServer& getGattServer() const; + virtual void waitForEvent(void); + + virtual GattClient& getGattClient() { + return BlueNRGGattClient::getInstance(); + } + + virtual SecurityManager& getSecurityManager() { + return *sm; + } + + virtual const SecurityManager& getSecurityManager() const { + return *sm; + } + void reset(void); + virtual bool hasInitialized(void) const { + return isInitialized; + } + + uint8_t getUpdaterHardwareVersion(uint8_t *hw_version); + int updateFirmware(const uint8_t *fw_image, uint32_t fw_size); + bool dataPresent(); + int32_t spiRead(uint8_t *buffer, uint8_t buff_size); + int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2); + void disable_irq(); + void enable_irq(); + + virtual void processEvents(); + +private: + bool isInitialized; + + SPI spi_; + DigitalOut nCS_; + DigitalOut rst_; + InterruptIn irq_; + + //FIXME: TBI (by now just placeholders to let build + /*** betzw: placeholders ***/ + SecurityManager *sm; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ +#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ + +#include "ble/DiscoveredCharacteristic.h" + +class BlueNRGGattClient; /* forward declaration */ + +class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic { +public: + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + + void setLastHandle(GattAttribute::Handle_t lastHandleIn); +}; + +#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGGap.h + * @author STMicroelectronics + * @brief Header file for BlueNRG BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GAP_H__ +#define __BLUENRG_GAP_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/Gap.h" + +#define BLE_CONN_HANDLE_INVALID 0x0 +#define BDADDR_SIZE 6 + +#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020) +#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000) +#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0) + +// Scanning and Connection Params used by Central for creating connection +#define GAP_OBSERVATION_PROC (0x80) + +#define SCAN_P (0x0010) +#define SCAN_L (0x0010) +#define SUPERV_TIMEOUT (0xC80) +#define CONN_P(x) ((int)((x)/1.25f)) +#define CONN_L(x) ((int)((x)/0.625f)) +#define CONN_P1 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_P2 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_L1 (0x0008) +#define CONN_L2 (0x0008) +#define GUARD_INT 5 //msec +#define MIN_INT_CONN 0x0006 //=>7.5msec +#define MAX_INT_CONN 0x0C80 //=>4000msec +#define DEF_INT_CONN 0x0140 //=>400msec (default value for connection interval) + +/**************************************************************************/ +/*! + \brief + +*/ +/**************************************************************************/ +class BlueNRGGap : public Gap +{ +public: + static BlueNRGGap &getInstance() { + static BlueNRGGap m_instance; + return m_instance; + } + + enum Reason_t { + DEVICE_FOUND, + DISCOVERY_COMPLETE + }; + + /* Functions that must be implemented from Gap */ + virtual ble_error_t setAddress(addr_type_t type, const BLEProtocol::AddressBytes_t address); + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address); + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &); + virtual ble_error_t startAdvertising(const GapAdvertisingParams &); + virtual ble_error_t stopAdvertising(void); + virtual ble_error_t stopScan(); + virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);} + virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);} + virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);} + virtual ble_error_t disconnect(DisconnectionReason_t reason); + virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason); + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params); + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); + + virtual ble_error_t setDeviceName(const uint8_t *deviceName); + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); + virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance); + virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP); + + virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode); + virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode); + virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const; + virtual ScanningPolicyMode_t getScanningPolicyMode(void) const; + + virtual ble_error_t setTxPower(int8_t txPower); + virtual void getPermittedTxPowerValues(const int8_t **, size_t *); + + virtual ble_error_t connect(const Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams); + + virtual ble_error_t reset(void); + + void Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI); + ble_error_t createConnection(void); + + void setConnectionHandle(uint16_t con_handle); + uint16_t getConnectionHandle(void); + + bool getIsSetAddress(); + + // ADV timeout handling + Timeout& getAdvTimeout(void) { + return advTimeout; + } + uint8_t getAdvToFlag(void) { + return AdvToFlag; + } + void setAdvToFlag(void); + + // SCAN timeout handling + Timeout& getScanTimeout(void) { + return scanTimeout; + } + uint8_t getScanToFlag(void) { + return ScanToFlag; + } + void setScanToFlag(void); + + void Process(void); + + GapScanningParams* getScanningParams(void); + + virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams); + + void setConnectionInterval(uint16_t interval); + Gap::Role_t getGapRole(void); + void setGapRole(Gap::Role_t role); + +private: + uint16_t m_connectionHandle; + Role_t gapRole; + AddressType_t addr_type; + Address_t _peerAddr; + AddressType_t _peerAddrType; + uint8_t bdaddr[BDADDR_SIZE]; + bool _scanning; + bool _connecting; + bool isSetAddress; + uint8_t deviceAppearance[2]; + + // ADV timeout handling + Timeout advTimeout; + bool AdvToFlag; + + // SCAN timeout handling + Timeout scanTimeout; + bool ScanToFlag; + + static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) { + return (duration * 625) / 1000; + } + + uint16_t scanInterval; + uint16_t scanWindow; + uint16_t advInterval; + uint16_t slaveConnIntervMin; + uint16_t slaveConnIntervMax; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + void setAdvParameters(void); + void setConnectionParameters(void); + + Gap::AdvertisingPolicyMode_t advertisingPolicyMode; + Gap::ScanningPolicyMode_t scanningPolicyMode; + + Whitelist_t whitelistAddresses; + + ble_error_t updateAdvertisingData(void); + + BlueNRGGap() : AdvToFlag(false), ScanToFlag(false) { + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + addr_type = BLEProtocol::AddressType::RANDOM_STATIC; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + isSetAddress = false; + memset(deviceAppearance, 0, sizeof(deviceAppearance)); + } + + BlueNRGGap(BlueNRGGap const &); + void operator=(BlueNRGGap const &); + + GapAdvertisingData _advData; + GapAdvertisingData _scanResponse; +}; + +#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,157 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattClient.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CLIENT_H__ +#define __BLUENRG_GATT_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattConnectionClient.h" + +using namespace std; + +#define MAX_ACTIVE_CONNECTIONS 7 + +class BlueNRGGattClient : public GattClient +{ +public: + static BlueNRGGattClient &getInstance() { + static BlueNRGGattClient m_instance; + return m_instance; + } + + ble_error_t createGattConnectionClient(Gap::Handle_t connectionHandle); + ble_error_t removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason); + + /* Functions that must be implemented from GattClient */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + virtual bool isServiceDiscoveryActive(void) const; + virtual void terminateServiceDiscovery(void); + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback); + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + virtual ble_error_t write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + virtual ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + virtual ble_error_t reset(void); + + void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code); + + void primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(Gap::Handle_t connectionHandle); + + void serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length); + + +protected: + + BlueNRGGattClient(): _connectionPool() {}; + + ServiceDiscovery::TerminationCallback_t terminationCallback; + +private: + + BlueNRGGattClient(BlueNRGGattClient const &); + void operator=(BlueNRGGattClient const &); + + BlueNRGGattConnectionClient *_connectionPool[MAX_ACTIVE_CONNECTIONS]; + uint8_t _numConnections; + + BlueNRGGattConnectionClient * getGattConnectionClient(Gap::Handle_t connectionHandle); + +}; + +#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,185 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattConnectionClient.cpp + * @author STMicroelectronics + * @brief Header file for BlueNRGGattConnectionClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CONNECTION_CLIENT_H__ +#define __BLUENRG_GATT_CONNECTION_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" + +using namespace std; + +#define BLE_TOTAL_DISCOVERED_SERVICES 10 +#define BLE_TOTAL_DISCOVERED_CHARS 10 + +class BlueNRGGattConnectionClient +{ +public: + + enum { + GATT_IDLE, + GATT_SERVICE_DISCOVERY, + GATT_CHAR_DESC_DISCOVERY, + //GATT_CHARS_DISCOVERY_COMPLETE, + //GATT_DISCOVERY_TERMINATED, + GATT_READ_CHAR, + GATT_WRITE_CHAR + }; + + /* Functions that must be implemented from GattClient */ + ble_error_t launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + bool isServiceDiscoveryActive(void) const; + void terminateServiceDiscovery(void); + void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + } + ble_error_t read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + ble_error_t write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + ble_error_t reset(void); + + void gattProcedureCompleteCB(uint8_t error_code); + + void primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(void); + + void serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(uint8_t event_data_length); + +protected: + + BlueNRGGattConnectionClient(BlueNRGGattClient *gattClient, Gap::Handle_t connectionHandle): + discoveredService(), + discoveredChar(), + readCBParams(), + writeCBParams(), + _characteristic() { + + //PRINTF("BlueNRGGattConnectionClient construtor: connHandle=%d\n\r", connectionHandle); + + _gattClient = gattClient; + _connectionHandle = connectionHandle; + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + } + + ServiceDiscovery::ServiceCallback_t serviceDiscoveryCallback; + ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback; + ServiceDiscovery::TerminationCallback_t terminationCallback; + CharacteristicDescriptorDiscovery::DiscoveryCallback_t charDescDiscoveryCallback; + CharacteristicDescriptorDiscovery::TerminationCallback_t charDescTerminationCallback; + +private: + + BlueNRGGattConnectionClient(BlueNRGGattConnectionClient const &); + void operator=(BlueNRGGattConnectionClient const &); + ~BlueNRGGattConnectionClient() {}; + + BlueNRGGattClient *_gattClient; + + Gap::Handle_t _connectionHandle; + DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES]; + BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS]; + + GattReadCallbackParams readCBParams; + GattWriteCallbackParams writeCBParams; + + // The char for which the descriptor discovery has been launched + DiscoveredCharacteristic _characteristic; + + UUID _matchingServiceUUID; + UUID _matchingCharacteristicUUIDIn; + uint8_t _currentState; + uint8_t _numServices, _servIndex; + uint8_t _numChars; + uint8_t _numCharDesc; + + friend class BlueNRGGattClient; +}; + +#endif /* __BLUENRG_GATT_CONNECTION_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_SERVER_H__ +#define __BLUENRG_GATT_SERVER_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattService.h" +#include "ble/GattServer.h" +#include <vector> +#include <map> + +#define BLE_TOTAL_CHARACTERISTICS 10 + +using namespace std; + +class BlueNRGGattServer : public GattServer +{ +public: + static BlueNRGGattServer &getInstance() { + static BlueNRGGattServer m_instance; + return m_instance; + } + + enum HandleEnum_t { + CHAR_HANDLE = 0, + CHAR_VALUE_HANDLE, + CHAR_DESC_HANDLE + }; + + /* Functions that must be implemented from GattServer */ + virtual ble_error_t addService(GattService &); + virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t initializeGATTDatabase(void); + + virtual bool isOnDataReadAvailable() const { + return true; + } + + virtual ble_error_t reset(void); + + /* BlueNRG Functions */ + void eventCallback(void); + //void hwCallback(void *pckt); + ble_error_t Read_Request_CB(uint16_t attributeHandle); + uint8_t Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, + uint8_t data_length, const uint8_t* data + ); + GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle); + void HCIDataWrittenEvent(const GattWriteCallbackParams *params); + void HCIDataReadEvent(const GattReadCallbackParams *params); + void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle); + void HCIDataSentEvent(unsigned count); + +private: + + // compute the number of attribute record needed by a service + static uint16_t computeAttributesRecord(GattService& service); + + + static const int MAX_SERVICE_COUNT = 10; + uint8_t serviceCount; + uint8_t characteristicCount; + uint16_t servHandle, charHandle; + + std::map<uint16_t, uint16_t> bleCharHandleMap; // 1st argument is characteristic, 2nd argument is service + GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS]; + uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS]; + + BlueNRGGattServer() { + serviceCount = 0; + characteristicCount = 0; + }; + + BlueNRGGattServer(BlueNRGGattServer const &); + void operator=(BlueNRGGattServer const &); + + static const int CHAR_DESC_TYPE_16_BIT=0x01; + static const int CHAR_DESC_TYPE_128_BIT=0x02; + static const int CHAR_DESC_SECURITY_PERMISSION=0x00; + static const int CHAR_DESC_ACCESS_PERMISSION=0x03; + static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_CLOCK_H__ +#define __BLE_CLOCK_H__ + +#include <ble_hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __BLE_CLOCK_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file ble_debug.h + * @author CL + * @version V1.0.0 + * @date 04-July-2014 + * @brief This file defines print functions for debug purposes. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLE_DEBUG_H +#define __BLE_DEBUG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> + +/* Exported macro ------------------------------------------------------------*/ +//#define DEBUG +#ifdef DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Print the data travelling over the SPI in the .csv format for the GUI*/ +//#define PRINT_CSV_FORMAT +#ifdef PRINT_CSV_FORMAT +#include <stdio.h> +#define PRINT_CSV(...) printf(__VA_ARGS__) +#else +#define PRINT_CSV(...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __BLE_DEBUG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_gp_timer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : General purpose timer library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_GP_TIMER_H__ +#define __BLE_GP_TIMER_H__ + +#include "ble_clock.h" +#include "ble_status.h" +#ifdef __DMA_LP__ +#include "stm32xx_timerserver.h" +#endif /* __DMA_LP__ */ + +/** + * timer + * + * A structure that represents a timer. Use Timer_Set() to set the timer. + * + */ +struct timer { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + tClockTime start; + tClockTime interval; + +#endif +}; + +typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); + +/** + * Timer_Set + * + * @param[in] t Pointer to a timer structure + * @param[in] interval timeout value + * + * This function sets the timeout value of a timer. + * + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * Timer_Reset + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the time it previously expired. + * + */ +void Timer_Reset(struct timer *t); + +/** + * Timer_Restart + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the current time. + * + */ +void Timer_Restart(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns TRUE if timer is expired, FALSE otherwise. + * + */ +int Timer_Expired(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns the time needed for expiration. + * + * @return Time before timer's expiration. + */ +tClockTime Timer_Remaining(struct timer *t); + +#ifdef __DMA_LP__ +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID); + +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); +#endif /* __DMA_LP__ */ + +#endif /* __BLE_GP_TIMER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,108 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_H__ +#define __BLE_HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void signalEventsToProcess(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __BLE_HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_TYPES_H__ +#define __BLE_HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __BLE_HAL_TYPES_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,126 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.0, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_H_ +#define __BLE_HCI_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ble_hal_types.h" +#include "ble_link_layer.h" +#include <ble_list.h> + +#define HCI_READ_PACKET_SIZE 128 //71 + +/** + * Maximum payload of HCI commands that can be sent. Change this value if needed. + * This value can be up to 255. + */ +#define HCI_MAX_PAYLOAD_SIZE 128 + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_READ_PACKET_SIZE]; + uint8_t data_len; +} tHciDataPacket; + +struct hci_request { + uint16_t ogf; + uint16_t ocf; + int event; + void *cparam; + int clen; + void *rparam; + int rlen; +}; + +typedef enum +{ + BUSY, + AVAILABLE +} HCI_CMD_STATUS_t; + + +/** + * This function must be used to pass the packet received from the HCI + * interface to the BLE Stack HCI state machine. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * + */ +void HCI_Input(tHciDataPacket *hciReadPacket); + +/** + * Initialization function. Must be done before any data can be received from + * BLE controller. + */ +void HCI_Init(void); + +/** + * Callback used to pass events to application. + * + * @param[in] pckt The event. + * + */ +extern void HCI_Event_CB(void *pckt); + +/** + * Processing function that must be called after an event is received from + * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if + * necessary. +*/ +void HCI_Process(void); + +/** + * @brief Check if queue of HCI event is empty or not. + * @note This funtion can be used to check if the event queue from BlueNRG is empty. This + * is useful when checking if it is safe to go to sleep. + * @return TRUE if event queue is empty. FALSE otherwhise. + */ +BOOL HCI_Queue_Empty(void); +/** + * Iterrupt service routine that must be called when the BlueNRG + * reports a packet received or an event to the host through the + * BlueNRG interrupt line. + */ +#ifdef __DMA_LP__ +void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); +void HCI_Process_Notification_Request(void); +void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); +void HCI_Wait_For_Response(void); +#else +void HCI_Isr(void); +void HCI_HandleSPI(void); + +int hci_send_req(struct hci_request *r, BOOL async); +#endif /* __DMA_LP__ */ + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#ifdef __cplusplus +} +#endif + + +#endif /* __BLE_HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,548 @@ +/****************************************************************************** +* +* File Description +* --------------------- +* This file defines constants and functions for HCI layer. +* See Bluetooth Core v 4.0, Vol. 2, Part E. +* +*******************************************************************************/ + +#ifndef __HCI_INTERNAL_H_ +#define __HCI_INTERNAL_H_ + +#include "ble_compiler.h" +#include "ble_hal_types.h" +#include "ble_clock.h" +#include "ble_link_layer.h" +#include "ble_hci.h" + +#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) + + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +typedef __packed struct _hci_uart_pckt{ + uint8_t type; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef __packed struct _hci_command_hdr{ + uint16_t opcode; /* OCF & OGF */ + uint8_t plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef __packed struct _hci_event_pckt{ + uint8_t evt; + uint8_t plen; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef __packed struct _hci_acl_hdr{ + uint16_t handle; /* Handle & Flags(PB, BC) */ + uint16_t dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef __packed struct _disconnect_cp{ + uint16_t handle; + uint8_t reason; +} PACKED disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 + +#define OCF_SET_EVENT_MASK 0x0001 +#define OCF_RESET 0x0003 + +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D +typedef __packed struct _read_transmit_power_level_cp{ + uint16_t handle; + uint8_t type; +} PACKED read_transmit_power_level_cp; +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 +typedef __packed struct _read_transmit_power_level_rp{ + uint8_t status; + uint16_t handle; + int8_t level; +} PACKED read_transmit_power_level_rp; +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 + +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 +#define OCF_HOST_BUFFER_SIZE 0x0033 +#define OCF_HOST_NUM_COMP_PKTS 0x0035 + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef __packed struct _read_local_version_rp{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t manufacturer_name; + uint16_t lmp_pal_subversion; +} PACKED read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_COMMANDS 0x0002 +#define OCF_READ_LOCAL_FEATURES 0x0003 + +#define OCF_READ_BD_ADDR 0x0009 +typedef __packed struct _read_bd_addr_rp{ + uint8_t status; + tBDAddr bdaddr; +} PACKED read_bd_addr_rp; +#define READ_BD_ADDR_RP_SIZE 7 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +#define OCF_READ_RSSI 0x0005 +typedef __packed struct _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef __packed struct _read_rssi_rp{ + uint8_t status; + uint16_t handle; + int8_t rssi; +} PACKED read_rssi_rp; +#define READ_RSSI_RP_SIZE 4 + + +/* LE commands */ +#define OGF_LE_CTL 0x08 + +#define OCF_LE_SET_EVENT_MASK 0x0001 +typedef __packed struct _le_set_event_mask_cp{ + uint8_t mask[8]; +} PACKED le_set_event_mask_cp; +#define LE_SET_EVENT_MASK_CP_SIZE 8 + +#define OCF_LE_READ_BUFFER_SIZE 0x0002 +typedef __packed struct _le_read_buffer_size_rp{ + uint8_t status; + uint16_t pkt_len; + uint8_t max_pkt; +} PACKED le_read_buffer_size_rp; +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 + +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 +typedef __packed struct _le_read_local_supported_features_rp{ + uint8_t status; + uint8_t features[8]; +} PACKED le_read_local_supported_features_rp; +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 + +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 +typedef __packed struct _le_set_random_address_cp{ + tBDAddr bdaddr; +} PACKED le_set_random_address_cp; +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 + +#define OCF_LE_SET_ADV_PARAMETERS 0x0006 +typedef __packed struct _le_set_adv_parameters_cp{ + uint16_t min_interval; + uint16_t max_interval; + uint8_t advtype; + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint8_t chan_map; + uint8_t filter; +} PACKED le_set_adv_parameters_cp; +#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 + +#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 +typedef __packed struct _le_read_adv_channel_tx_power_rp{ + uint8_t status; + int8_t level; +} PACKED le_read_adv_channel_tx_power_rp; +#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 + +#define OCF_LE_SET_ADV_DATA 0x0008 +typedef __packed struct _le_set_adv_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_adv_data_cp; +#define LE_SET_ADV_DATA_CP_SIZE 32 + +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 +typedef __packed struct _le_set_scan_response_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_scan_response_data_cp; +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 + +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A +typedef __packed struct _le_set_advertise_enable_cp{ + uint8_t enable; +} PACKED le_set_advertise_enable_cp; +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 + +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B +typedef __packed struct _le_set_scan_parameters_cp{ + uint8_t type; + uint16_t interval; + uint16_t window; + uint8_t own_bdaddr_type; + uint8_t filter; +} PACKED le_set_scan_parameters_cp; +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 + +#define OCF_LE_SET_SCAN_ENABLE 0x000C +typedef __packed struct _le_set_scan_enable_cp{ + uint8_t enable; + uint8_t filter_dup; +} PACKED le_set_scan_enable_cp; +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 + +#define OCF_LE_CREATE_CONN 0x000D +typedef __packed struct _le_create_connection_cp{ + uint16_t interval; + uint16_t window; + uint8_t initiator_filter; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_create_connection_cp; +#define LE_CREATE_CONN_CP_SIZE 25 + +#define OCF_LE_CREATE_CONN_CANCEL 0x000E + +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F +typedef __packed struct _le_read_white_list_size_rp{ + uint8_t status; + uint8_t size; +} PACKED le_read_white_list_size_rp; +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 + +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 +typedef __packed struct _le_add_device_to_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_add_device_to_white_list_cp; +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 +typedef __packed struct _le_remove_device_from_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_remove_device_from_white_list_cp; +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_CONN_UPDATE 0x0013 +typedef __packed struct _le_connection_update_cp{ + uint16_t handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_connection_update_cp; +#define LE_CONN_UPDATE_CP_SIZE 14 + +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 +typedef __packed struct _le_set_host_channel_classification_cp{ + uint8_t map[5]; +} PACKED le_set_host_channel_classification_cp; +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 + +#define OCF_LE_READ_CHANNEL_MAP 0x0015 +typedef __packed struct _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef __packed struct _le_read_channel_map_rp{ + uint8_t status; + uint16_t handle; + uint8_t map[5]; +} PACKED le_read_channel_map_rp; +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 + +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 +typedef __packed struct _le_read_remote_used_features_cp{ + uint16_t handle; +} PACKED le_read_remote_used_features_cp; +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 + +#define OCF_LE_ENCRYPT 0x0017 +typedef __packed struct _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef __packed struct _le_encrypt_rp{ + uint8_t status; + uint8_t encdata[16]; +} PACKED le_encrypt_rp; +#define LE_ENCRYPT_RP_SIZE 17 + +#define OCF_LE_RAND 0x0018 +typedef __packed struct _le_rand_rp{ + uint8_t status; + uint8_t random[8]; +} PACKED le_rand_rp; +#define LE_RAND_RP_SIZE 9 + +#define OCF_LE_START_ENCRYPTION 0x0019 +typedef __packed struct _le_start_encryption_cp{ + uint16_t handle; + uint8_t random[8]; + uint16_t diversifier; + uint8_t key[16]; +} PACKED le_start_encryption_cp; +#define LE_START_ENCRYPTION_CP_SIZE 28 + +#define OCF_LE_LTK_REPLY 0x001A +typedef __packed struct _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef __packed struct _le_ltk_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_reply_rp; +#define LE_LTK_REPLY_RP_SIZE 3 + +#define OCF_LE_LTK_NEG_REPLY 0x001B +typedef __packed struct _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef __packed struct _le_ltk_neg_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_neg_reply_rp; +#define LE_LTK_NEG_REPLY_RP_SIZE 3 + +#define OCF_LE_READ_SUPPORTED_STATES 0x001C +typedef __packed struct _le_read_supported_states_rp{ + uint8_t status; + uint8_t states[8]; +} PACKED le_read_supported_states_rp; +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 + +#define OCF_LE_RECEIVER_TEST 0x001D +typedef __packed struct _le_receiver_test_cp{ + uint8_t frequency; +} PACKED le_receiver_test_cp; +#define LE_RECEIVER_TEST_CP_SIZE 1 + +#define OCF_LE_TRANSMITTER_TEST 0x001E +typedef __packed struct _le_transmitter_test_cp{ + uint8_t frequency; + uint8_t length; + uint8_t payload; +} PACKED le_transmitter_test_cp; +#define LE_TRANSMITTER_TEST_CP_SIZE 3 + +#define OCF_LE_TEST_END 0x001F +typedef __packed struct _le_test_end_rp{ + uint8_t status; + uint16_t num_pkts; +} PACKED le_test_end_rp; +#define LE_TEST_END_RP_SIZE 3 + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3f + + +/*------------- Events -------------*/ +#define EVT_CONN_COMPLETE 0x03 +typedef __packed struct _evt_conn_complete{ + uint8_t status; + uint16_t handle; + tBDAddr bdaddr; + uint8_t link_type; + uint8_t encr_mode; +} PACKED evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef __packed struct _evt_disconn_complete{ + uint8_t status; + uint16_t handle; + uint8_t reason; +} PACKED evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef __packed struct _evt_encrypt_change{ + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} PACKED evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C + +#define EVT_CMD_COMPLETE 0x0E +typedef __packed struct _evt_cmd_complete{ + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef __packed struct _evt_cmd_status{ + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef __packed struct _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef __packed struct _evt_num_comp_pkts{ + uint8_t num_hndl; + /* variable length part */ +} PACKED evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +/* variable length part of evt_num_comp_pkts. */ +typedef __packed struct _evt_num_comp_pkts_param{ + uint16_t hndl; + uint16_t num_comp_pkts; +} PACKED evt_num_comp_pkts_param; +#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 + +#define EVT_DATA_BUFFER_OVERFLOW 0x1A +typedef __packed struct _evt_data_buffer_overflow{ + uint8_t link_type; +} PACKED evt_data_buffer_overflow; +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 + +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef __packed struct _evt_encryption_key_refresh_complete{ + uint8_t status; + uint16_t handle; +} PACKED evt_encryption_key_refresh_complete; +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 + +#define EVT_LE_META_EVENT 0x3E +typedef __packed struct _evt_le_meta_event{ + uint8_t subevent; + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef __packed struct _evt_le_connection_complete{ + uint8_t status; + uint16_t handle; + uint8_t role; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; +} PACKED evt_le_connection_complete; +#define EVT_LE_CONN_COMPLETE_SIZE 18 + +#define EVT_LE_ADVERTISING_REPORT 0x02 +typedef __packed struct _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t data_length; + uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef __packed struct _evt_le_connection_update_complete{ + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; +} PACKED evt_le_connection_update_complete; +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 + +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +typedef __packed struct _evt_le_read_remote_used_features_complete{ + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} PACKED evt_le_read_remote_used_features_complete; +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 + +#define EVT_LE_LTK_REQUEST 0x05 +typedef __packed struct _evt_le_long_term_key_request{ + uint16_t handle; + uint8_t random[8]; + uint16_t ediv; +} PACKED evt_le_long_term_key_request; +#define EVT_LE_LTK_REQUEST_SIZE 12 + +/** +* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, +* application can use @ref evt_blue_aci structure to parse the packet. +*/ +#define EVT_VENDOR 0xFF + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + + + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); + +typedef enum { + WAITING_TYPE, + WAITING_OPCODE1, + WAITING_OPCODE2, + WAITING_EVENT_CODE, + WAITING_HANDLE, + WAITING_HANDLE_FLAG, + WAITING_PARAM_LEN, + WAITING_DATA_LEN1, + WAITING_DATA_LEN2, + WAITING_PAYLOAD +}hci_state; + +typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); + +/* HCI library functions. */ + +int hci_send_req(struct hci_request *r, BOOL async); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,170 @@ +/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +* File Name : ble_hci_le.h +* Author : AMG RF FW team +* Version : V1.1.0 +* Date : 18-July-2016 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.1, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_LE_H_ +#define __BLE_HCI_LE_H_ + +#include "ble_hal_types.h" +#include "ble_link_layer.h" + +/** + * @defgroup HCI_Error_codes HCI Error codes + * @{ + */ +#define HCI_UNKNOWN_COMMAND 0x01 +#define HCI_NO_CONNECTION 0x02 +#define HCI_HARDWARE_FAILURE 0x03 +#define HCI_PAGE_TIMEOUT 0x04 +#define HCI_AUTHENTICATION_FAILURE 0x05 +#define HCI_PIN_OR_KEY_MISSING 0x06 +#define HCI_MEMORY_FULL 0x07 +#define HCI_CONNECTION_TIMEOUT 0x08 +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a +#define HCI_ACL_CONNECTION_EXISTS 0x0b +#define HCI_COMMAND_DISALLOWED 0x0c +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d +#define HCI_REJECTED_SECURITY 0x0e +#define HCI_REJECTED_PERSONAL 0x0f +#define HCI_HOST_TIMEOUT 0x10 +#define HCI_UNSUPPORTED_FEATURE 0x11 +#define HCI_INVALID_PARAMETERS 0x12 +#define HCI_OE_USER_ENDED_CONNECTION 0x13 +#define HCI_OE_LOW_RESOURCES 0x14 +#define HCI_OE_POWER_OFF 0x15 +#define HCI_CONNECTION_TERMINATED 0x16 +#define HCI_REPEATED_ATTEMPTS 0x17 +#define HCI_PAIRING_NOT_ALLOWED 0x18 +#define HCI_UNKNOWN_LMP_PDU 0x19 +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a +#define HCI_SCO_OFFSET_REJECTED 0x1b +#define HCI_SCO_INTERVAL_REJECTED 0x1c +#define HCI_AIR_MODE_REJECTED 0x1d +#define HCI_INVALID_LMP_PARAMETERS 0x1e +#define HCI_UNSPECIFIED_ERROR 0x1f +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 +#define HCI_UNIT_LINK_KEY_USED 0x26 +#define HCI_QOS_NOT_SUPPORTED 0x27 +#define HCI_INSTANT_PASSED 0x28 +#define HCI_PAIRING_NOT_SUPPORTED 0x29 +#define HCI_TRANSACTION_COLLISION 0x2a +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c +#define HCI_QOS_REJECTED 0x2d +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e +#define HCI_INSUFFICIENT_SECURITY 0x2f +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 +#define HCI_ROLE_SWITCH_PENDING 0x32 +#define HCI_SLOT_VIOLATION 0x34 +#define HCI_ROLE_SWITCH_FAILED 0x35 +#define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 +#define HCI_CONN_REJ_NO_CH_FOUND 0x39 +#define HCI_CONTROLLER_BUSY 0x3A +#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B +#define HCI_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_CONN_TERM_MIC_FAIL 0x3D +#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E +#define HCI_MAC_CONN_FAILED 0x3F +/** + * @} + */ + + +/* + * HCI library functions. + * Each function returns 0 in case of success, otherwise one of the error codes. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(uint8_t enable); + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter); + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter); + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); + +int hci_le_rand(uint8_t random_number[8]); + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); + +int hci_acl_data(const uint8_t * data, uint16_t len); + +int hci_le_set_random_address(tBDAddr bdaddr); + +int hci_read_bd_addr(tBDAddr bdaddr); + +int hci_le_read_white_list_size(uint8_t *size); + +int hci_le_clear_white_list(); + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); + +int hci_le_ltk_request_reply(uint8_t key[16]); + +int hci_le_ltk_request_neg_reply(); + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); + +int hci_le_create_connection_cancel(void); + +int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level); + +int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi); + +int hci_le_read_local_supported_features(uint8_t *features); + +int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); + +int hci_le_read_supported_states(uint8_t states[8]); + +int hci_le_receiver_test(uint8_t frequency); + +int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); + +int hci_le_test_end(uint16_t *num_pkts); + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion); + + + +#endif /* __BLE_HCI_LE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,161 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_link_layer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's link layer. It contains +* definition of functions for link layer, most of which are +* mapped to HCI commands. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef _BLE_LINK_LAYER_H +#define _BLE_LINK_LAYER_H + +#include <ble_status.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + *@name Advertising filter + *Advertising policy for filtering (white list related) + *@{ + */ +#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ +#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ +/** + * @} + */ + + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef uint8_t tBDAddr[6]; + + +/** + *@name Bluetooth address types + * Bluetooth address types + *@{ + */ +#define PUBLIC_ADDR (0) +#define RANDOM_ADDR (1) +#define STATIC_RANDOM_ADDR (1) +#define RESOLVABLE_PRIVATE_ADDR (2) +#define NON_RESOLVABLE_PRIVATE_ADDR (3) +/** + * @} + */ + +/** + *@name Directed advertising types + * Type of advertising during directed advertising + *@{ + */ +#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) +#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) +/** + * @} + */ + +/** + * @name Advertising type + * @{ + */ + +/** + * undirected scannable and connectable + */ +#define ADV_IND (0x00) + +/** + * directed non scannable + */ +#define ADV_DIRECT_IND (0x01) + +/** + * scannable non connectable + */ +#define ADV_SCAN_IND (0x02) + +/** + * non-connectable and no scan response + */ +#define ADV_NONCONN_IND (0x03) + +/** + * scan response + */ +#define SCAN_RSP (0x04) + +/** + * @} + */ + +/* 0X05-0XFF RESERVED */ + +/** + * @name Advertising ranges + * @{ + */ + +/** + * lowest allowed interval value for connectable types(20ms)..multiple of 625us + */ +#define ADV_INTERVAL_LOWEST_CONN (0X0020) + +/** + * highest allowed interval value (10.24s)..multiple of 625us. + */ +#define ADV_INTERVAL_HIGHEST (0X4000) + +/** + * lowest allowed interval value for non connectable types + * (100ms)..multiple of 625us. + */ +#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) + +/** + * @} + */ + +/** + * @name Advertising channels + * @{ + */ +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 +/** + * @} + */ + +/** + * @name Scan_types Scan types + * @{ + */ +#define PASSIVE_SCAN 0 +#define ACTIVE_SCAN 1 +/** + * @} + */ + +/** + * @} + */ + + +#endif /* _BLE_LINK_LAYER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,47 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for linked list library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef _BLE_LIST_H_ +#define _BLE_LIST_H_ + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +uint8_t list_is_empty (tListNode * listHead); + +void list_insert_head (tListNode * listHead, tListNode * node); + +void list_insert_tail (tListNode * listHead, tListNode * node); + +void list_remove_node (tListNode * node); + +void list_remove_head (tListNode * listHead, tListNode ** node ); + +void list_remove_tail (tListNode * listHead, tListNode ** node ); + +void list_insert_node_after (tListNode * node, tListNode * ref_node); + +void list_insert_node_before (tListNode * node, tListNode * ref_node); + +int list_get_size (tListNode * listHead); + +void list_get_next_node (tListNode * ref_node, tListNode ** node); + +void list_get_prev_node (tListNode * ref_node, tListNode ** node); + +#endif /* _BLE_LIST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_OSAL_H__ +#define __BLE_OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __BLE_OSAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,158 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_sm.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's security manager. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_SM_H__ +#define __BLE_SM_H__ + +/****************************************************************************** +* Macros +*****************************************************************************/ + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/* IO capabilities */ +/** + * @anchor IO_capabilities + * @name IO capabilities + * @{ + */ +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define IO_CAP_KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) +/** + * @} + */ + +/** + * @anchor Auth_req + * @name Authentication requirements + * @{ + */ +#define BONDING (0x01) +#define NO_BONDING (0x00) +/** + * @} + */ + +/** + * @anchor MITM_req + * @name MITM protection requirements + * @{ + */ +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor OOB_Data + * @name Out-Of-Band data + * @{ + */ +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) +/** + * @} + */ + +/** + * @anchor Author_req + * @name Authorization requirements + * @{ + */ +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor Conn_authorization + * @name Connection authorization + * @{ + */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) +/** + * @} + */ + +/** + * @anchor Use_fixed_pin + * @name Use fixed pin + * @{ + */ +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +/** + * @} + */ + +/** + * @anchor link_security_status + * @name Link security status + * @{ + */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) +/** + * @} + */ + +/** + * @anchor SMP_pairing_failed_codes + * @name SMP pairing failed reason codes + * @{ + */ +#define PASSKEY_ENTRY_FAILED (0x01) +#define OOB_NOT_AVAILABLE (0x02) +#define AUTH_REQ_CANNOT_BE_MET (0x03) +#define CONFIRM_VALUE_FAILED (0x04) +#define PAIRING_NOT_SUPPORTED (0x05) +#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) +#define CMD_NOT_SUPPORTED (0x07) +#define UNSPECIFIED_REASON (0x08) +#define VERY_EARLY_NEXT_ATTEMPT (0x09) +#define SM_INVALID_PARAMS (0x0A) +/** + * @} + */ + +/** + * @anchor pairing_failed_codes + * @name Pairing failed error codes + * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event + * @{ + */ +#define SM_PAIRING_SUCCESS (0x00) +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,188 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_status.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file with BLE Stack status codes. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_STATUS_H__ +#define __BLE_STATUS_H__ + +#include <ble_hal_types.h> + +/** @addtogroup Middlewares + * @{ + */ + +/** @defgroup ST + * @{ + */ + +/** @defgroup SimpleBlueNRG_HCI + * @{ + */ + +/** @defgroup ble_status Bluetooth Status/Error Codes + * @{ + */ + +typedef uint8_t tBleStatus; + +/* Error Codes as specified by the specification + * according to the spec the error codes range + * from 0x00 to 0x3F + */ +/** + * @name Standard error codes + * @brief Standard error codes. See Core v 4.1, Vol. 2, part D. + * @{ + */ +#define ERR_CMD_SUCCESS (0x00) +#define BLE_STATUS_SUCCESS (0x00) +#define ERR_UNKNOWN_HCI_COMMAND (0x01) +#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) + +#define ERR_AUTH_FAILURE (0x05) +#define ERR_PIN_OR_KEY_MISSING (0x06) +#define ERR_MEM_CAPACITY_EXCEEDED (0x07) +#define ERR_CONNECTION_TIMEOUT (0x08) + +#define ERR_COMMAND_DISALLOWED (0x0C) + +#define ERR_UNSUPPORTED_FEATURE (0x11) +#define ERR_INVALID_HCI_CMD_PARAMS (0x12) +#define ERR_RMT_USR_TERM_CONN (0x13) +#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) +#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) +#define ERR_LOCAL_HOST_TERM_CONN (0x16) + +#define ERR_UNSUPP_RMT_FEATURE (0x1A) + +#define ERR_INVALID_LMP_PARAM (0x1E) +#define ERR_UNSPECIFIED_ERROR (0x1F) + +#define ERR_LL_RESP_TIMEOUT (0x22) +#define ERR_LMP_PDU_NOT_ALLOWED (0x24) + +#define ERR_INSTANT_PASSED (0x28) + +#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) +#define ERR_CONTROLLER_BUSY (0x3A) + +#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) + +#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) + +#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) + + +/** + * @} + */ +/** + * @name Vendor-specific error codes + * @brief Error codes defined by ST related to BlueNRG stack + * @{ + */ +/** + * The command cannot be executed due to the current state of the device. + */ +#define BLE_STATUS_FAILED (0x41) +/** + * Some parameters are invalid. + */ +#define BLE_STATUS_INVALID_PARAMS (0x42) +/** + * It is not allowed to start the procedure (e.g. another the procedure is ongoing + * or cannot be started on the given handle). + */ +#define BLE_STATUS_NOT_ALLOWED (0x46) +/** + * Unexpected error. + */ +#define BLE_STATUS_ERROR (0x47) +#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) + +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +#define BLE_STATUS_INVALID_CID (0x50) + +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) +#define BLE_STATUS_IRK_NOT_FOUND (0x5B) +#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) +#define BLE_STATUS_SEC_DB_FULL (0x5D) +#define BLE_STATUS_DEV_NOT_BONDED (0x5E) +#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) + +#define BLE_STATUS_INVALID_HANDLE (0x60) +#define BLE_STATUS_INVALID_PARAMETER (0x61) +#define BLE_STATUS_OUT_OF_HANDLE (0x62) +#define BLE_STATUS_INVALID_OPERATION (0x63) +#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) +#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) +#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) + +/** + * Returned when no valid slots are available (e.g. when there are no available state machines). + */ +#define BLE_STATUS_NO_VALID_SLOT (0x82) + +/** + * Returned when a scan window shorter than minimum allowed value has been requested (i.e. 2ms) + */ + +#define BLE_STATUS_SCAN_WINDOW_SHORT (0x83) +/** + * Returned when the maximum requested interval to be allocated is shorter then the current + * anchor period and a there is no submultiple for the current anchor period that is between + * the minimum and the maximum requested intervals. + */ + +#define BLE_STATUS_NEW_INTERVAL_FAILED (0x84) +/** + * Returned when the maximum requested interval to be allocated is greater than the current anchor + * period and there is no multiple of the anchor period that is between the minimum and the maximum + * requested intervals. + */ + +#define BLE_STATUS_INTERVAL_TOO_LARGE (0x85) +/** + * Returned when the current anchor period or a new one can be found that is compatible to the + * interval range requested by the new slot but the maximum available length that can be allocated is + * less than the minimum requested slot length. + */ + +#define BLE_STATUS_LENGTH_FAILED (0x86) +/** + * @} + */ + +/** + * @name Library Error Codes + * @brief Error codes defined by ST related to MCU library. + * @{ + */ +#define BLE_STATUS_TIMEOUT (0xFF) +#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) +#define BLE_STATUS_NULL_PARAM (0xF1) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,813 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci_const.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with ACI definitions for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_CONST_H_ +#define __BLUENRG_ACI_CONST_H_ + +#include "ble_compiler.h" +#include "ble_link_layer.h" +#include "ble_hci_const.h" +#include "bluenrg_gatt_server.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define OCF_HAL_GET_FW_BUILD_NUMBER 0x0000 +typedef __packed struct _hal_get_fw_build_number_rp{ + uint8_t status; + uint16_t build_number; +} PACKED hal_get_fw_build_number_rp; +#define HAL_GET_FW_BUILD_NUMBER_RP_SIZE 3 +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +#define OCF_HAL_READ_CONFIG_DATA 0x000D +typedef __packed struct _hal_read_config_data_cp{ + uint8_t offset; +} PACKED hal_read_config_data_cp; +#define HAL_READ_CONFIG_DATA_RP_SIZE 1 +typedef __packed struct _hal_read_config_data_rp{ + uint8_t status; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE]; +} PACKED hal_read_config_data_rp; + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef __packed struct _hal_set_tx_power_level_cp{ + uint8_t en_high_power; + uint8_t pa_level; +} PACKED hal_set_tx_power_level_cp; +#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 + +#define OCF_HAL_DEVICE_STANDBY 0x0013 + +#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014 +typedef __packed struct _hal_le_tx_test_packet_number_rp{ + uint8_t status; + uint32_t number_of_packets; +} PACKED hal_le_tx_test_packet_number_rp; + +#define OCF_HAL_TONE_START 0x0015 +typedef __packed struct _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_HAL_TONE_STOP 0x0016 +#define OCF_HAL_GET_LINK_STATUS 0x0017 +typedef __packed struct _hal_get_link_status_rp{ + uint8_t status; + uint8_t link_status[8]; + uint16_t conn_handle[8]; +} PACKED hal_get_link_status_rp; + +#define OCF_HAL_GET_ANCHOR_PERIOD 0x0019 +typedef __packed struct _hal_get_anchor_period_rp{ + uint8_t status; + uint32_t anchor_period; + uint32_t max_free_slot; +} PACKED hal_get_anchor_period_rp; + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef __packed struct _get_updater_version_rp{ + uint8_t status; + uint8_t version; +} PACKED get_updater_version_rp; +#define GET_UPDATER_VERSION_RP_SIZE 2 + +#define OCF_GET_UPDATER_BUFSIZE 0x0023 +typedef __packed struct _get_updater_bufsize_rp{ + uint8_t status; + uint8_t buffer_size; +} PACKED get_updater_bufsize_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 + +#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 + +#define OCF_UPDATER_ERASE_SECTOR 0x0026 +typedef __packed struct _updater_erase_sector_cp{ + uint32_t address; +} PACKED updater_erase_sector_cp; +#define UPDATER_ERASE_SECTOR_CP_SIZE 4 + +#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 +#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_prog_data_block_cp{ + uint32_t address; + uint16_t data_len; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; +} PACKED updater_prog_data_block_cp; + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef __packed struct _updater_read_data_block_cp{ + uint32_t address; + uint16_t data_len; +} PACKED updater_read_data_block_cp; +#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[VARIABLE_SIZE]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef __packed struct _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef __packed struct _updater_calc_crc_rp{ + uint8_t status; + uint32_t crc; +} PACKED updater_calc_crc_rp; +#define UPDATER_CALC_CRC_RP_SIZE 5 + +#define OCF_UPDATER_HW_VERSION 0x002A +typedef __packed struct _updater_hw_version_rp{ + uint8_t status; + uint8_t version; +} PACKED updater_hw_version_rp; +#define UPDATER_HW_VERSION_RP_SIZE 2 + +#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 + +#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 + +#define OCF_GAP_SET_DISCOVERABLE 0x0083 + +#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 +typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ + uint8_t own_bdaddr_type; + uint8_t directed_adv_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint16_t adv_interv_min; + uint16_t adv_interv_max; +} PACKED gap_set_direct_conectable_cp_IDB05A1; + +typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB04A1; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef __packed struct _gap_set_io_capability_cp{ + uint8_t io_capability; +} PACKED gap_set_io_capability_cp; +#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 + +#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 +typedef __packed struct _gap_set_auth_requirement_cp{ + uint8_t mitm_mode; + uint8_t oob_enable; + uint8_t oob_data[16]; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t bonding_mode; +} PACKED gap_set_auth_requirement_cp; +#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 + +#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 +typedef __packed struct _gap_set_author_requirement_cp{ + uint16_t conn_handle; + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef __packed struct _gap_passkey_response_cp{ + uint16_t conn_handle; + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef __packed struct _gap_authorization_response_cp{ + uint16_t conn_handle; + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 + +#define OCF_GAP_INIT 0x008A +typedef __packed struct _gap_init_cp_IDB05A1{ + uint8_t role; + uint8_t privacy_enabled; + uint8_t device_name_char_len; +} PACKED gap_init_cp_IDB05A1; +#define GAP_INIT_CP_SIZE_IDB05A1 3 + +typedef __packed struct _gap_init_cp_IDB04A1{ + uint8_t role; +} PACKED gap_init_cp_IDB04A1; +#define GAP_INIT_CP_SIZE_IDB04A1 1 +typedef __packed struct _gap_init_rp{ + uint8_t status; + uint16_t service_handle; + uint16_t dev_name_char_handle; + uint16_t appearance_char_handle; +} PACKED gap_init_rp; +#define GAP_INIT_RP_SIZE 7 + +#define OCF_GAP_SET_NON_CONNECTABLE 0x008B +typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ + uint8_t advertising_event_type; + uint8_t own_address_type; +#endif +} PACKED gap_set_non_connectable_cp_IDB05A1; + +typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp_IDB04A1; + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef __packed struct _gap_set_undirected_connectable_cp{ + uint8_t adv_filter_policy; + uint8_t own_addr_type; +} PACKED gap_set_undirected_connectable_cp; +#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 + +#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D +typedef __packed struct _gap_slave_security_request_cp{ + uint16_t conn_handle; + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef __packed struct _gap_delete_ad_type_cp{ + uint8_t ad_type; +} PACKED gap_delete_ad_type_cp; +#define GAP_DELETE_AD_TYPE_CP_SIZE 1 + +#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 +typedef __packed struct _gap_get_security_level_rp{ + uint8_t status; + uint8_t mitm_protection; + uint8_t bonding; + uint8_t oob_data; + uint8_t passkey_required; +} PACKED gap_get_security_level_rp; +#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 + +#define OCF_GAP_SET_EVT_MASK 0x0091 +typedef __packed struct _gap_set_evt_mask_cp{ + uint16_t evt_mask; +} PACKED gap_set_evt_mask_cp; +#define GAP_SET_EVT_MASK_CP_SIZE 2 + +#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 + +#define OCF_GAP_TERMINATE 0x0093 +typedef __packed struct _gap_terminate_cp{ + uint16_t handle; + uint8_t reason; +} PACKED gap_terminate_cp; +#define GAP_TERMINATE_CP_SIZE 3 + +#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 + +#define OCF_GAP_ALLOW_REBOND_DB 0x0095 + +typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ + uint16_t conn_handle; +} PACKED gap_allow_rebond_cp_IDB05A1; + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef __packed struct _gap_start_limited_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_limited_discovery_proc_cp; +#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 +typedef __packed struct _gap_start_general_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_general_discovery_proc_cp; +#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 +typedef __packed struct _gap_start_name_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_name_discovery_proc_cp; +#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 + +#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 + +#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; + +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t use_reconn_addr; + tBDAddr reconn_addr; +} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; + +#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B +#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 +typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t num_whitelist_entries; + uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; +} PACKED gap_start_selective_conn_establish_proc_cp; + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef __packed struct _gap_create_connection_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_create_connection_cp; +#define GAP_CREATE_CONNECTION_CP_SIZE 24 + +#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D + +#define OCF_GAP_START_CONNECTION_UPDATE 0x009E +typedef __packed struct _gap_start_connection_update_cp{ + uint16_t conn_handle; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_connection_update_cp; +#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 + +#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F +typedef __packed struct _gap_send_pairing_request_cp{ + uint16_t conn_handle; + uint8_t force_rebond; +} PACKED gap_send_pairing_request_cp; +#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 + +#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 +typedef __packed struct _gap_resolve_private_address_cp{ + tBDAddr address; +} PACKED gap_resolve_private_address_cp; +#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 +typedef __packed struct _gap_resolve_private_address_rp{ + uint8_t status; + tBDAddr address; +} PACKED gap_resolve_private_address_rp; + +#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 +#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 +typedef __packed struct _gap_set_broadcast_mode_cp{ + uint16_t adv_interv_min; + uint16_t adv_interv_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; +} PACKED gap_set_broadcast_mode_cp; + +#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 +typedef __packed struct _gap_start_observation_proc_cp{ + uint16_t scan_interval; + uint16_t scan_window; + uint8_t scan_type; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_observation_proc_cp; + +#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 +typedef __packed struct _gap_get_bonded_devices_rp{ + uint8_t status; + uint8_t num_addr; + uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; +} PACKED gap_get_bonded_devices_rp; + +#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 +typedef __packed struct _gap_is_device_bonded_cp{ + uint8_t peer_address_type; + tBDAddr peer_address; +} PACKED gap_is_device_bonded_cp; + + +#define OCF_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef __packed struct _gatt_add_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_serv_rp; +#define GATT_ADD_SERV_RP_SIZE 3 + +#define OCF_GATT_INCLUDE_SERV 0x0103 +typedef __packed struct _gatt_include_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_include_serv_rp; +#define GATT_INCLUDE_SERV_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR 0x0104 +typedef __packed struct _gatt_add_char_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_rp; +#define GATT_ADD_CHAR_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR_DESC 0x0105 +typedef __packed struct _gatt_add_char_desc_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_desc_rp; +#define GATT_ADD_CHAR_DESC_RP_SIZE 3 + +#define OCF_GATT_UPD_CHAR_VAL 0x0106 + +#define OCF_GATT_DEL_CHAR 0x0107 +typedef __packed struct _gatt_del_char_cp{ + uint16_t service_handle; + uint16_t char_handle; +} PACKED gatt_del_char_cp; +#define GATT_DEL_CHAR_CP_SIZE 4 + +#define OCF_GATT_DEL_SERV 0x0108 +typedef __packed struct _gatt_del_serv_cp{ + uint16_t service_handle; +} PACKED gatt_del_serv_cp; +#define GATT_DEL_SERV_CP_SIZE 2 + +#define OCF_GATT_DEL_INC_SERV 0x0109 +typedef __packed struct _gatt_del_inc_serv_cp{ + uint16_t service_handle; + uint16_t inc_serv_handle; +} PACKED gatt_del_inc_serv_cp; +#define GATT_DEL_INC_SERV_CP_SIZE 4 + +#define OCF_GATT_SET_EVT_MASK 0x010A +typedef __packed struct _gatt_set_evt_mask_cp{ + uint32_t evt_mask; +} PACKED gatt_set_evt_mask_cp; +#define GATT_SET_EVT_MASK_CP_SIZE 4 + +#define OCF_GATT_EXCHANGE_CONFIG 0x010B +typedef __packed struct _gatt_exchange_config_cp{ + uint16_t conn_handle; +} PACKED gatt_exchange_config_cp; +#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 + +#define OCF_ATT_FIND_INFO_REQ 0x010C +typedef __packed struct _att_find_info_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED att_find_info_req_cp; +#define ATT_FIND_INFO_REQ_CP_SIZE 6 + +#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D +#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 +typedef __packed struct _att_find_by_type_value_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[2]; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU - 7]; +} PACKED att_find_by_type_value_req_cp; + +#define OCF_ATT_READ_BY_TYPE_REQ 0x010E +#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_type_req_cp; + +#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F +#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_group_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_group_type_req_cp; + +#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 +#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val +typedef __packed struct _att_prepare_write_req_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t value_offset; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU-5]; +} PACKED att_prepare_write_req_cp; + +#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 +typedef __packed struct _att_execute_write_req_cp{ + uint16_t conn_handle; + uint8_t execute; +} PACKED att_execute_write_req_cp; +#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 + +#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 +typedef __packed struct _gatt_disc_all_prim_serivces_cp{ + uint16_t conn_handle; +} PACKED gatt_disc_all_prim_services_cp; +#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 + +#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 +typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ + uint16_t conn_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_disc_prim_service_by_uuid_cp; +#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid + +#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 +typedef __packed struct _gatt_disc_find_included_services_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED gatt_find_included_services_cp; +#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 + +#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 +typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ + uint16_t conn_handle; + uint16_t start_attr_handle; + uint16_t end_attr_handle; +} PACKED gatt_disc_all_charac_of_serv_cp; +#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 + +#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 + +#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ + uint16_t conn_handle; + uint16_t char_val_handle; + uint16_t char_end_handle; +} PACKED gatt_disc_all_charac_descriptors_cp; +#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 + +#define OCF_GATT_READ_CHARAC_VAL 0x0118 +typedef __packed struct _gatt_read_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_val_cp; +#define GATT_READ_CHARAC_VAL_CP_SIZE 4 + +#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 +typedef __packed struct _gatt_read_using_charac_uuid_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_read_using_charac_uuid_cp; +#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID + +#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A +typedef __packed struct _gatt_read_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_val_cp; +#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 + +#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B +#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles +typedef __packed struct _gatt_read_multiple_charac_val_cp{ + uint16_t conn_handle; + uint8_t num_handles; + uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_read_multiple_charac_val_cp; + +#define OCF_GATT_WRITE_CHAR_VALUE 0x011C + +#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D +#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_write_long_charac_val_cp; + +#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E +#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_charac_reliable_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; +} PACKED gatt_write_charac_reliable_cp; + +#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F +#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; +} PACKED gatt_write_long_charac_desc_cp; + +#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 +typedef __packed struct _gatt_read_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_desc_cp; +#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 + +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 +typedef __packed struct _gatt_read_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_desc_cp; +#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 +#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 3]; +} PACKED gatt_write_without_resp_cp; + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 +#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_signed_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 13]; +} PACKED gatt_signed_write_without_resp_cp; + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 +typedef __packed struct _gatt_confirm_indication_cp{ + uint16_t conn_handle; +} PACKED gatt_confirm_indication_cp; +#define GATT_CONFIRM_INDICATION_CP_SIZE 2 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef __packed struct _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 +typedef __packed struct _gatt_set_security_permission_cp{ + uint16_t service_handle; + uint16_t attr_handle; + uint8_t security_permission; +} PACKED gatt_set_security_permission_cp; +#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_GATT_READ_HANDLE_VALUE 0x012A +typedef __packed struct _gatt_read_handle_val_cp{ + uint16_t attr_handle; +} PACKED gatt_read_handle_val_cp; +#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 +typedef __packed struct _gatt_read_handle_val_rp{ + uint8_t status; + uint16_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; +} PACKED gatt_read_handle_val_rp; + +#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B +typedef __packed struct _gatt_read_handle_val_offset_cp{ + uint16_t attr_handle; + uint8_t offset; +} PACKED gatt_read_handle_val_offset_cp; +#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 +typedef __packed struct _gatt_read_handle_val_offset_rp{ + uint8_t status; + uint8_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; +} PACKED gatt_read_handle_val_offset_rp; + +#define OCF_GATT_UPD_CHAR_VAL_EXT 0x012C +#define GATT_UPD_CHAR_VAL_EXT_CP_SIZE 10 // without value +typedef __packed struct _gatt_upd_char_val_ext_cp{ + uint16_t service_handle; + uint16_t char_handle; + uint8_t update_type; + uint16_t char_length; + uint16_t value_offset; + uint8_t value_length; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_UPD_CHAR_VAL_EXT_CP_SIZE]; +} PACKED gatt_upd_char_val_ext_cp; + +#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 +typedef __packed struct _l2cap_conn_param_update_req_cp{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_update_req_cp; +#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 + +#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint16_t min_ce_length; + uint16_t max_ce_length; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; + +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; + +/** + * @defgroup BlueNRG_Events BlueNRG events (vendor specific) + * @{ + */ + +/** + * Vendor specific event for BlueNRG. + */ +typedef __packed struct _evt_blue_aci{ + uint16_t ecode; /**< One of the BlueNRG event codes. */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_blue_aci; + + +/** + * @} + */ + +#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gap.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GAP layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BNRG_GAP_H__ +#define __BNRG_GAP_H__ + +#include <ble_link_layer.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + * @name GAP UUIDs + * @{ + */ +#define GAP_SERVICE_UUID (0x1800) +#define DEVICE_NAME_UUID (0x2A00) +#define APPEARANCE_UUID (0x2A01) +#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) +#define RECONNECTION_ADDR_UUID (0x2A03) +#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) +/** + * @} + */ + +/** + * @name Characteristic value lengths + * @{ + */ +#define DEVICE_NAME_CHARACTERISTIC_LEN (8) +#define APPEARANCE_CHARACTERISTIC_LEN (2) +#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) +#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) +#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) +/** + * @} + */ + +/*------------- AD types for adv data and scan response data ----------------*/ + +/** + * @defgroup AD_Types AD Types + * @brief AD Types + * @{ + */ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +/** + * @anchor Flags_AD_Type_bits + * @name Flags AD Type bits + * @brief Bits in Flags AD Type + * @{ + */ +#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) +#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) +#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) +#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) +#define FLAG_BIT_LE_BR_EDR_HOST (0x10) +/** + * @} + */ + +/** + * @name Service UUID AD types + * @{ + */ +#define AD_TYPE_16_BIT_SERV_UUID (0x02) +#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) +#define AD_TYPE_32_BIT_SERV_UUID (0x04) +#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) +#define AD_TYPE_128_BIT_SERV_UUID (0x06) +#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) +/** + * @} + */ + +/* LOCAL NAME AD types */ +/** + * @name Local name AD types + * @{ + */ +#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) +#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) +/** + * @} + */ + +/* TX power level AD type*/ +#define AD_TYPE_TX_POWER_LEVEL (0x0A) + +/* Class of device */ +#define AD_TYPE_CLASS_OF_DEVICE (0x0D) + +/* security manager TK value AD type */ +#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) + +/* security manager OOB flags */ +#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) + +/* slave connection interval AD type */ +#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) + +/* service solicitation UUID list Ad types*/ +/** + * @name Service solicitation UUID list AD types + * @{ + */ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) +#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) +/** + * @} + */ + +/* service data AD type */ +#define AD_TYPE_SERVICE_DATA (0x16) + +/* manufaturer specific data AD type */ +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/* appearance AD type */ +#define AD_TYPE_APPEARANCE (0x19) + +/* advertising interval AD type */ +#define AD_TYPE_ADVERTISING_INTERVAL (0x1A) + +/** + * @} + */ + +#define MAX_ADV_DATA_LEN (31) + +#define DEVICE_NAME_LEN (7) +#define BD_ADDR_SIZE (6) + +/** + * @name Privacy flag values + * @{ + */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) +/** + * @} + */ + +/** + * @name Intervals + * Intervals in terms of 625 micro sec + * @{ + */ +#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ +#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ +#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ +#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ +#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ +#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ +#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ +#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ +/** + * @} + */ + +/** + * @name Timeout values + * @{ + */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ +/** + * @} + */ + +/** + * @anchor gap_roles + * @name GAP Roles + * @{ +*/ +#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) +#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) + +#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) +#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) +/** + * @} + */ + +/** + * @anchor gap_procedure_codes + * @name GAP procedure codes + * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event + * and aci_gap_terminate_gap_procedure() command. + * @{ + */ +#define GAP_LIMITED_DISCOVERY_PROC (0x01) +#define GAP_GENERAL_DISCOVERY_PROC (0x02) +#define GAP_NAME_DISCOVERY_PROC (0x04) +#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) +#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) +#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) +#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) +#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1231 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gap_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GAP_ACI_H__ +#define __BLUENRG_GAP_ACI_H__ + +/** + *@addtogroup GAP GAP + *@brief GAP layer. + *@{ + */ + +/** + *@defgroup GAP_Functions GAP functions + *@brief API for GAP layer. + *@{ + */ + +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". + * @param privacy_enabled Enable (1) or disable (0) privacy. + * @param device_name_char_len Length of the device name characteristic + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, + uint8_t device_name_char_len, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Privacy Flag (peripheral role only) + * @li Reconnection Address (peripheral role only) + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB04A1(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); + +/** + * @brief Set the Device in non-discoverable mode. + * @note This command will disable the LL advertising. + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_discoverable(void); + +/** + * @brief Put the device in limited discoverable mode + * (as defined in GAP specification volume 3, section 9.2.3). + * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. + * The advertising can be disabled at any time by issuing + * aci_gap_set_non_discoverable() command. + * The AdvIntervMin and AdvIntervMax parameters are optional. If both + * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). + * Host can set the Local Name, a Service UUID list and the Slave Connection + * Minimum and Maximum. If provided, these data will be inserted into the + * advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() + * separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following + * standard AD types: + * @li AD Flags + * @li TX Power Level + * + * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates + * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. + * + * Example: + * @code + * + * #define ADV_INTERVAL_MIN_MS 100 + * #define ADV_INTERVAL_MAX_MS 200 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, + * (ADV_INTERVAL_MAX_MS*1000)/0.625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * sizeof(serviceUUIDList), serviceUUIDList, + * 0, 0); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 250 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 500 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg NO_WHITE_LIST_USE + * @arg WHITE_LIST_FOR_ONLY_SCAN + * @arg WHITE_LIST_FOR_ONLY_CONN + * @arg WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +/** + * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4). + * @note The device will be discoverable until the Host issue Aci_Gap_Set_Non_Discoverable command. + * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses + * the default values for advertising intervals (1.28 s and 2.56 s respectively for IDB04A1). + * When using connectable undirected advertising events:\n + * @li Adv_Interval_Min = 30 ms + * @li Adv_Interval_Max = 60 ms + * \nWhen using non-connectable advertising events or scannable undirected advertising events:\n + * @li Adv_Interval_Min = 100 ms + * @li Adv_Interval_Max = 150 ms + * Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided, + * these data will be inserted into the advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following standard AD types: + * @li AD Flags + * @li TX Power Level + * + * Usage example: + * + * @code + * + * #define ADV_INTERVAL_MIN_MS 800 + * #define ADV_INTERVAL_MAX_MS 900 + * #define CONN_INTERVAL_MIN_MS 100 + * #define CONN_INTERVAL_MAX_MS 300 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625, + * (ADV_INTERVAL_MAX_MS*1000)/625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * 0, NULL, + * (CONN_INTERVAL_MIN_MS*1000)/1250, + * (CONN_INTERVAL_MAX_MS*1000)/1250); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 1.28 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 2.56 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ONLY_SCAN + * @arg @ref WHITE_LIST_FOR_ONLY_CONN + * @arg @ref WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); + +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @param adv_interv_min Minimum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @param adv_interv_max Maximum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max); +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); + +/** + * @brief Set the IO capabilities of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param io_capability One of the allowed codes for IO Capability: + * @arg @ref IO_CAP_DISPLAY_ONLY + * @arg @ref IO_CAP_DISPLAY_YES_NO + * @arg @ref IO_CAP_KEYBOARD_ONLY + * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT + * @arg @ref IO_CAP_KEYBOARD_DISPLAY + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_io_capability(uint8_t io_capability); + +/** + * @brief Set the authentication requirements for the device. + * @note If the oob_enable is set to 0, oob_data will be ignored. + * This command has to be given only when the device is not in a connected state. + * @param mitm_mode MITM mode: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @param oob_enable If OOB data are present or not: + * @arg @ref OOB_AUTH_DATA_ABSENT + * @arg @ref OOB_AUTH_DATA_PRESENT + * @param oob_data Out-Of-Band data + * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process + * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process + * @param use_fixed_pin If application wants to use a fixed pin or not: + * @arg @ref USE_FIXED_PIN_FOR_PAIRING + * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING + * If a fixed pin is not used, it has to be provided by the application with + * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will + * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is + * accepted. + * @param bonding_mode One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode); + /** + * @brief Set the authorization requirements of the device. + * @note This command has to be given when connected to a device if authorization is required to access services + * which require authorization. + * @param conn_handle Handle of the connection. + * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required + * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables + * the authorization requirement in the device and when a remote device + * tries to read/write a characeristic with authorization requirements, the stack will + * send back an error response with "Insufficient authorization" error code. + * After pairing is complete a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event + * will be sent to the Host. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); + +/** + * @brief Provide the pass key that will be used during pairing. + * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param conn_handle Connection handle + * @param passkey Pass key that will be used during the pairing process. Must be a number between + * 0 and 999999. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); + +/** + * @brief Authorize a device to access attributes. + * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. + * + * @param conn_handle Connection handle + * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) + * @arg @ref CONNECTION_REJECTED : Reject (reject connection) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); + +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @param own_address_type If Privacy is disabled, then the peripheral address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the peripheral address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); + +/** + * @brief Put the device into undirected connectable mode. + * @note If privacy is enabled in the device, a resolvable private address is generated and used + * as the advertiser's address. If not, the address of the type specified in own_addr_type + * is used for advertising. + * @param own_addr_type Type of our address used during advertising: + * if BLUENRG (IDB04A1) + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * else if BLUENRG_MS (IDB05A1) + * If Privacy is disabled: + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled: + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_filter_policy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ALL + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); + +/** + * @brief Send a slave security request to the master. + * @note This command has to be issued to notify the master of the security requirements of the slave. + * The master may encrypt the link, initiate the pairing procedure, or reject the request. + * @param conn_handle Connection handle + * @param bonding One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @param mitm_protection If MITM protection is required or not: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); + +/** + * @brief Update advertising data. + * @note This command can be used to update the advertising data for a particular AD type. + * If the AD type specified does not exist, then it is added to the advertising data. + * If the overall advertising data length is more than 31 octets after the update, then + * the command is rejected and the old data is retained. + * @param AdvLen Length of AdvData array + * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification + * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. + * Example + * @code + * tBleStatus ret; + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; + * + * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * 8, local_name, 3, serviceUUIDList, 0, 0); + * ret = aci_gap_update_adv_data(5, manuf_data); + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); + +/** + * @brief Delete an AD Type + * @note This command can be used to delete the specified AD type from the advertisement data if + * present. + * @param ad_type One of the allowed AD types (see @ref AD_Types) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); + +/** + * @brief Get the current security settings + * @note This command can be used to get the current security settings of the device. + * @param mitm_protection @arg 0: Not required + * @arg 1: Required + * @param bonding @arg 0: No bonding mode + * @arg 1: Bonding mode + * @param oob_data @arg 0: Data absent + * @arg 1: Data present + * @param passkey_required @arg 0: Not required + * @arg 1: Fixed pin is present which is being used + * @arg 2: Passkey required for pairing. An event will be generated + * when required. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required); + +/** + * @brief Add addresses of bonded devices into the controller's whitelist. + * @note The command will return an error if there are no devices in the database or if it was unable + * to add the device into the whitelist. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_configure_whitelist(void); + +/** + * @brief Terminate a connection. + * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. + * @param conn_handle Connection handle + * @param reason Reason for requesting disconnection. The error code can be any of ones as specified + * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); + +/** + * @brief Clear the security database. + * @note All the devices in the security database will be removed. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_clear_security_database(void); + +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @param conn_handle + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB04A1(void); + +/** + * @brief Start the limited discovery procedure. + * @note The controller is commanded to start active scanning. When this procedure is started, + * only the devices in limited discoverable mode are returned to the upper layers. + * The procedure is terminated when either the upper layers issue a command to terminate the + * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code + * set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated + * due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC. + * The device found when the procedure is ongoing is returned to the upper layers through the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the general discovery procedure. + * @note The controller is commanded to start active scanning. The procedure is terminated when + * either the upper layers issue a command to terminate the procedure by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC + * or a timeout happens. When the procedure is terminated due to any of the above reasons, + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to + * @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to + * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the name discovery procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. Once a connection is established, GATT procedure is started to read the + * device name characteristic. When the read is completed (successfully or unsuccessfully), + * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also + * contains the name of the device if the device name was read successfully. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Start the auto connection establishment procedure. + * @note The devices specified are added to the white list of the controller and a LE_Create_Connection + * call will be made to the controller by GAP with the initiator filter policy set to + * use whitelist to determine which advertiser to connect to. When a command is issued to + * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the + * controller by GAP. + * The procedure is terminated when either a connection is successfully established with one of + * the specified devices in the white list or the procedure is explicitly terminated by issuing + * the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start a general connection establishment procedure. + * @note The host enables scanning in the controller with the scanner filter policy set + * to accept all advertising packets and from the scanning results all the devices + * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * The upper layer then has to select one of the devices to which it wants to connect + * by issuing the command aci_gap_create_connection(). The procedure is terminated + * when a connection is established or the upper layer terminates the procedure by + * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates); +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); + +/** + * @brief Start a selective connection establishment procedure. + * @note The GAP adds the specified device addresses into white list and enables scanning in + * the controller with the scanner filter policy set to accept packets only from + * devices in whitelist. All the devices found are sent to the upper layer by the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the + * devices to which it wants to connect by issuing the command aci_gap_create_connection(). + * On completion of the procedure a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated + * with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * The procedure is terminated when a connection is established or the upper layer terminates + * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure + * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start the direct connection establishment procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. The procedure can be terminated explicitly by the upper layer by issuing + * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the + * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller + * by GAP. + * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can + * be explicitly terminated by the upper layer by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is + * returned with the procedure code set to the corresponding procedure. + * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes"). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); + +/** + * @brief Start the connection parameter update procedure. + * @note Allowed by the Central to update the connection parameter of the specified connection. + * A Link Layer Connection Update procedure is started on the controller. + * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to + * the upper layer. + * @param conn_handle Handle of the connection for which the update procedure has to be started. + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Send a pairing request. + * @note Send the SM pairing request to start a pairing process from a Central. The authentication + * requirements and IO capabilities should be set before issuing this command using + * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). + * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. + * @param conn_handle Handle of the connection for which the pairing request has to be sent. + * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded + * @arg 0x01: Pairing request will be sent even if the device was previously bonded + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param[in] address Address to be resolved. + * @param[out] actual_address The public or static random address of the peer device, distributed during pairing phase. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); + +/** + * @brief This command gets the list of bonded devices. + * @note It returns the number of addresses and the corresponding address types and values. + * Example: + * @code + * tBleStatus ret; + * uint8_t num_devices = 0; + * uint8_t device_list[12*7]; + * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); + * for(int i = 0; i < num_devices; i+=7){ + * uint8_t addr_type = device_list[i]; + * uint8_t addr = device_list[i+1]; + * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); + * } + * @endcode + * + * @param[out] num_devices The number of bonded devices. + * @param[out] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address + * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. + * @param device_list_size Maximum size of the device_list buffer used to return the device list. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); + +/** + * @brief Puts the device into broadcast mode + * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address + * as specified in the own_addr_type parameter of the command. + * @param adv_interv_min Minimum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_interv_max Maximum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param own_addr_type If Privacy is disabled, the broadcaster address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the broadcaster address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_data_length Length of the advertising data in the advertising packet + * @param adv_data Advertising data used by the device while advertising + * @param num_whitelist_entries Number of devices to be added to whitelist + * @param addr_array It will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Starts an observation procedure, when the device is in Observer role. + * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer + * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth + * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. + * The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. + * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param own_address_type If Privacy is disabled, then the scanner address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the scanner address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates); + +/** + * @brief The command finds whether a device is bonded. + * @note If the device is using a resolvable private address and it has been bonded, then the command will return + * BLE_STATUS_SUCCESS. + * @param peer_address_type The address type of the peer device + * @arg @ref PUBLIC_ADDR. + * @arg @ref RANDOM_ADDR. + * @param peer_address Address used by the peer device while advertising. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address); + + +/** + * @} + */ + +/** + * @defgroup GAP_Events GAP events + * @{ + */ + +/** + * This event is generated by the controller when the limited discoverable + * mode ends due to timeout (180 seconds). No parameters in the event. + */ +#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) + + +/** + * This event is generated when the pairing process has completed successfully + * or a pairing procedure timeout has occurred or the pairing has failed. + * This is to notify the application that we have paired with a remote device + * so that it can take further actions or to notify that a timeout has occurred + * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. + */ +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +typedef __packed struct _evt_gap_pairing_cmplt{ + uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ + /** + * 0x00: Pairing Success. Pairing with a remote device was successful\n + * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n + * 0x02: Pairing Failed. The pairing failed with the remote device. + */ + uint8_t status; +} PACKED evt_gap_pairing_cmplt; + + +/** + * This event is generated by the Security manager to the application when a pass key is required for pairing. + * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. + * See @ref _evt_gap_pass_key_req. + */ +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +typedef __packed struct _evt_gap_pass_key_req{ + uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ +} PACKED evt_gap_pass_key_req; + + +/** + * This event is generated by the Security manager to the application when the application + * has set that authorization is required for reading/writing of attributes. This event will + * be generated as soon as the pairing is complete. When this event is received, + * aci_gap_authorization_response() command should be used by the application. + * See @ref _evt_gap_author_req. + */ +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +typedef __packed struct _evt_gap_author_req{ + uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ +} PACKED evt_gap_author_req; + +/** + * This event is generated when the slave security request is successfully sent to the master. + * No parameters for this event. + */ +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) + +/** + * This event is generated on the slave when a aci_gap_slave_security_request() is called to reestablish the bond + * with a master but the master has lost the bond. When this event is received, the upper layer has to issue the + * command aci_gap_allow_rebond() in order to allow the slave to continue the pairing process with the master. + * On the master this event is raised when aci_gap_send_pairing_request() is called to reestablish a bond with a slave + * but the slave has lost the bond. In order to create a new bond the master has to launch aci_gap_send_pairing_request() + * with force_rebond set to 1. + * No parameters for this event + */ +#define EVT_BLUE_GAP_BOND_LOST (0X0405) + +/** + * The event is given by the GAP layer to the upper layers when a device is discovered during scanning + * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. + */ +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef __packed struct _evt_gap_device_found{ + uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ + uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ + tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ + uint8_t data_length; /**< Length of advertising or scan response data. */ + uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ +} PACKED evt_gap_device_found; + +/** + * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated + * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. + */ +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef __packed struct _evt_gap_procedure_complete{ + uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ + /** + * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed + * due to authentication requirements). + */ + uint8_t status; + /** + * Procedure specific data.\n + * @li For Name Discovery Procedure:\n + * the name of the peer device if the procedure completed successfully. + * @li For General Connection Establishment Procedure:\n + * The reconnection address written to the peripheral device if the peripheral is privacy enabled + */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_gap_procedure_complete; + +/** + * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral + * is not able to resolve the private address of the peer device after connecting to it. + */ +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) +typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ + uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ +} PACKED evt_gap_addr_not_resolved_IDB05A1; +/** + * This event is raised when the reconnection address is generated during the general connection + * establishment procedure. The same address is set into the peer device also as a part of the general + * connection establishment procedure. In order to make use of the reconnection address the next time + * while connecting to the bonded peripheral, the application needs to use this reconnection address + * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() + * and aci_gap_start_auto_conn_establish_proc(). + */ +#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) +typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ + uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ +} PACKED evt_gap_reconnection_addr_IDB04A1; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1128 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GATT_ACI_H__ +#define __BLUENRG_GATT_ACI_H__ + +#include "bluenrg_gatt_server.h" + +/** + *@addtogroup GATT GATT + *@brief GATT layer. + *@{ + */ + +/** + *@defgroup GATT_Functions GATT functions + *@brief API for GATT layer. + *@{ + */ + +/** + * @brief Initialize the GATT layer for server and client roles. + * @note It adds also the GATT service with Service Changed Characteristic. + * Until this command is issued the GATT channel will not process any commands + * even if the connection is opened. This command has to be given + * before using any of the GAP features. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_init(void); + +/** + * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs + * to reserve the handle ranges for this service using max_attr_records parameter. This + * parameter specifies the maximum number of attribute records that can be added to this + * service (including the service attribute, include attribute, characteristic attribute, + * characteristic value attribute and characteristic descriptor attribute). Handle of the + * created service is returned. + * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors + * are allocated from the attribute pool. + * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field + * @param service_type Primary or secondary service. See @ref Service_type "Service Type". + * @param max_attr_records Maximum number of attribute records that can be added to this service + * (including the service declaration itself) + * @param[out] serviceHandle Handle of the Service. When this service is added to the service, + * a handle is allocated by the server to this service. Server also + * allocates a range of handles for this service from serviceHandle to + * <serviceHandle + max_attr_records>. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, + const uint8_t* service_uuid, + uint8_t service_type, + uint8_t max_attr_records, + uint16_t *serviceHandle); + +/** + * @brief Include a service given by included_start_handle and included_end_handle to another service + * given by service_handle. Attribute server creates an INCLUDE definition attribute and return + * the handle of this attribute in included_handle. + * @param service_handle Handle of the service to which another service has to be included + * @param included_start_handle Start Handle of the service which has to be included in service + * @param included_end_handle End Handle of the service which has to be included in service + * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". + * @param[in] included_uuid 16-bit or 128-bit UUID. + * @param[out] included_handle Handle of the include declaration. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle); + +/** + * @brief Add a characteristic to a service. + * @param serviceHandle Handle of the service to which the characteristic has to be added. + * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param charUuid 16-bit or 128-bit UUID. + * @param charValueLen Maximum length of the characteristic value. + * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, + * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". + * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @arg GATT_DONT_NOTIFY_EVENTS + * @arg GATT_NOTIFY_ATTRIBUTE_WRITE + * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP + * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. + * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client + * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE + * properties. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle); + +/** + * Add a characteristic descriptor to a service. + * @param serviceHandle Handle of the service to which the characteristic belongs + * @param charHandle Handle of the characteristic to which description has to be added. + * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG + * (Well_known_UUIDs) or a user-defined one. + * @param descValueMaxLen The maximum length of the descriptor value + * @param descValueLen Current Length of the characteristic descriptor value + * @param[in] descValue Value of the characteristic description + * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". + * @arg ATTR_NO_ACCESS + * @arg ATTR_ACCESS_READ_ONLY + * @arg ATTR_ACCESS_WRITE_REQ_ONLY + * @arg ATTR_ACCESS_READ_WRITE + * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE + * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param[out] descHandle Handle of the Characteristic Descriptor. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle); + +/** + * @brief Update a characteristic value in a service. + * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. The command is queued into the + * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, + * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or + * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate + * than what is allowed by the link. Throughput on BLE link depends on connection interval and + * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() + * for more info on how to suggest new connection parameters from a slave). If the application does not + * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function + * returns @ref BLE_STATUS_SUCCESS or any other error code.\n + * Example:\n + * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some + * notifications will be lost. + * @code + * tBleStatus Free_Fall_Notify(void) + * { + * uint8_t val; + * tBleStatus ret; + * + * val = 0x01; + * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); + * + * if (ret != BLE_STATUS_SUCCESS){ + * PRINTF("Error while updating FFall characteristic.\n") ; + * return BLE_STATUS_ERROR ; + * } + * return BLE_STATUS_SUCCESS; + * } + * @endcode + * Here if BlueNRG buffer become full, the application try again to send the notification. + * @code + * struct timer t; + * Timer_Set(&t, CLOCK_SECOND*10); + * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ + * // Radio is busy (buffer full). + * if(Timer_Expired(&t)) + * break; + * } + * @endcode + * + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic + * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, + * and the attribute value is of variable length, then the length of the attribute will + * be set to the charValueLen. If the charValOffset is set to a value greater than 0, + * then the length of the attribute will be set to the maximum length as specified for + * the attribute while adding the characteristic. + * @param charValueLen Length of the characteristic value in octets + * @param[in] charValue Characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue); +/** + * @brief Delete the specified characteristic from the service. + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); + +/** + * @brief Delete the specified service from the GATT server database. + * @param servHandle Handle of the service to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_service(uint16_t servHandle); + +/** + * @brief Delete the Include definition from the service. + * @param servHandle Handle of the service to which Include definition belongs + * @param includeServHandle Handle of the Included definition to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); + +/** + * @brief Perform an ATT MTU exchange procedure. + * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP + * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated + * to indicate the end of the procedure. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); + +/** + * @brief Send a @a Find @a Information @a Request. + * @note This command is used to obtain the mapping of attribute handles with their associated + * types. The responses of the procedure are given through the + * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by + * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range of attributes to be discovered on the server + * @param end_handle Ending handle of the range of attributes to be discovered on the server + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send a @a Find @a By @a Type @a Value @a Request + * @note The Find By Type Value Request is used to obtain the handles of attributes that + * have a given 16-bit UUID attribute type and a given attribute value. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid 2 octet UUID to find (little-endian) + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). + * @param attr_val Attribute value to find + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send a @a Read @a By @a Type @a Request + * @note The Read By Type Request is used to obtain the values of attributes where the attribute type + * is known but the handle is not known. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Read @a By @a Group @a Type @a Request + * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute + * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping + * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Prepare @a Write @a Request + * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param attr_handle The handle of the attribute to be written + * @param value_offset The offset of the first octet to be written + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). + * @param attr_val The value of the attribute to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send an @a Execute @a Write @a Request + * @note The Execute Write Request is used to request the server to write or cancel the write of all the + * prepared values currently held in the prepare queue from this client. + * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param execute @arg 0x00 Cancel all prepared writes + * @arg 0x01 Immediately write all pending prepared values. + * @return Value indicating success or error code. + */ +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); + +/** + * @brief This command will start the GATT client procedure to discover all primary services on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +/** + * @brief Start the procedure to discover the primary services of the specified UUID on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to find all included services. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle Start handle of the service + * @param end_handle End handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Start the procedure to discover all the characteristics of a given service. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_attr_handle Start attribute handle of the service + * @param end_attr_handle End attribute handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +/** + * @brief Start the procedure to discover all the characteristics specified by a UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Start attribute handle of the service + * @param end_handle End attribute handle of the service + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); + +/** + * @brief Start the procedure to discover all characteristic descriptors on the server. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. + * @param conn_handle Connection handle for which the command is given. + * @param char_val_handle Starting handle of the characteristic + * @param char_end_handle End handle of the characteristic + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +/** + * @brief Start the procedure to read the attribute value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to read all the characteristics specified by the UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range to be searched + * @param end_handle End handle of the range to be searched + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start a procedure to read multiple characteristic values from a server. + * @note This sub-procedure is used to read multiple Characteristic Values from a server when the + * client knows the Characteristic Value Handles. + * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param num_handles The number of handles for which the value has to be read + * @param set_of_handles The handles for which the attribute value has to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles); + +/** + * @brief Start the procedure to write a characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to write a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start the procedure to write a characteristic reliably. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to write a long characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP + * event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic descriptor + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start the procedure to write a characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to read the descriptor specified. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the descriptor to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to write a characteristic value without waiting for any response from the server. + * @note No events are generated after this command is executed. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 3) + * @param[in] attr_val Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start a signed write without response from the server. + * @note The procedure i used to write a characteristic value with an authentication signature without waiting + * for any response from the server. It cannot be used when the link is encrypted. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 13). + * @param attr_val Value to be written + * @return Value indicating success or error code + */ +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Confirm an indication + * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); + +/** + * @brief Allow or reject a write request from a client. + * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, + * then the status has to be set to 1 and the error code has to be set to the error code that has to be + * passed to the client. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n + * 0x01: The value cannot be written to the attribute specified by the attr_handle. + * @param err_code The error code that has to be passed to the client in case the write has to be rejected. + * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val); + +/** + * @brief Allow the GATT server to send a response to a read request from a client. + * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ + * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response + * can be sent to the client. So if the application wishes to update any of the attributes before + * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value + * and then give this command. The application should perform the required operations within 30 seconds, + * otherwise the GATT procedure will go to timeout. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_allow_read(uint16_t conn_handle); + +/** + * @brief Set the security permission for the attribute handle specified. + * @note Currently the setting of security permission is allowed only for client configuration descriptor. + * @param service_handle Handle of the service which contains the attribute whose security + * permission has to be modified. + * @param attr_handle Handle of the attribute whose security permission has to be modified. + * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission); + +/** + * @brief This command sets the value of the descriptor specified by charDescHandle. + * @param servHandle Handle of the service which contains the descriptor. + * @param charHandle Handle of the characteristic which contains the descriptor. + * @param charDescHandle Handle of the descriptor whose value has to be set. + * @param charDescValOffset Offset from which the descriptor value has to be updated. + * @param charDescValueLen Length of the descriptor value + * @param[in] charDescValue descriptor value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue); + +/** + * @brief Reads the value of the attribute handle specified from the local GATT database. + * @param attr_handle Handle of the attribute to read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + + /** + * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. + * @param attr_handle Handle of the attribute to read + * @param offset Offset from which the value needs to be read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); +/** + * @brief Update the value of a characteristic and sends notifications or indications. + * @note This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute + * up to 512 bytes and indicate selectively the generation of indications and notifications. + * @param service_handle Handle of the service to which the characteristic belongs. + * @param char_handle Handle of the characteristic + * @param update_type Bitmask that controls generation of notifications and indications. It can be a combination + * @arg @ref NOTIFICATION (0x01): send notification, if enabled. + * @arg @ref INDICATION (0x02): send indication, if enabled. + * If set to 0 no notifications or indications are sent. + * @param char_length Total length of the characteristic value. In case of a variable size characteristic, + * this field specifies the new length of the characteristic value after the update; + * in case of fixed length characteristic this field is ignored. + * @param value_offset The offset from which the attribute value has to be updated + * @param value_length Length of the value to be updated + * @param[out] value Updated characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value); + +/** + * @} + */ + + +/** + * @defgroup GATT_Events GATT events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** + * This event (if enabled, see @ref Gatt_Event_Mask "Gatt Event Mask") is raised to the application + * by the GATT server when a client modifies any attribute on the server, as consequence of one of + * the following GATT procedures: + * @li write without response + * @li signed write without response + * @li write characteristic value + * @li write long characteristic value + * @li reliable write. + * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. + */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint16_t offset; /**< Offset from which the write has been performed by the peer device */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB05A1; + +typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB04A1; + +/** + * This event is generated by the client/server to the application on a GATT timeout (30 seconds). + * See @ref _evt_gatt_procedure_timeout. + */ +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +typedef __packed struct _evt_gatt_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ +} PACKED evt_gatt_procedure_timeout; + +/** + * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). + * See @ref _evt_att_exchange_mtu_resp. + */ +#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) +typedef __packed struct _evt_att_exchange_mtu_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data (always 1). */ + uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ +} PACKED evt_att_exchange_mtu_resp; + +/** + * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and + * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. + */ +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef __packed struct _evt_att_find_information_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ + /** + * A sequence of handle-uuid pairs.\n + * @li if format=1, each pair is:\n + * [2 octets for handle, 2 octets for UUIDs] \n + * @li if format=2, each pair is:\n + * [2 octets for handle, 16 octets for UUIDs] + */ + uint8_t handle_uuid_pair[VARIABLE_SIZE]; +} PACKED evt_att_find_information_resp; + +/** + * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See + * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. + */ +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +typedef __packed struct _evt_att_find_by_type_val_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + /** + * Handles Information List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] + */ + uint8_t handles_info_list[VARIABLE_SIZE]; +} PACKED evt_att_find_by_type_val_resp; + +/** + * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and + * aci_gatt_disc_all_charac_of_serv(). + * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. + */ +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef __packed struct _evt_att_read_by_type_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ + /** + * Attribute Data List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] + */ + uint8_t handle_value_pair[VARIABLE_SIZE]; +} PACKED evt_att_read_by_type_resp; + +/** + * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). + * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. + */ +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +typedef __packed struct _evt_att_read_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ +} PACKED evt_att_read_resp; + +/** + * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). + * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. + */ +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +typedef __packed struct _evt_att_read_blob_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ +} PACKED evt_att_read_blob_resp; + +/** + * This event is generated in response to a @a Read @a Multiple @a Request. + * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. + */ +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +typedef __packed struct _evt_att_read_mult_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ +} PACKED evt_att_read_mult_resp; + +/** + * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). + * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. + */ +#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) +typedef __packed struct _evt_att_read_by_group_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_data_length; /**< The size of each Attribute Data. */ + /** + * A list of Attribute Data where the attribute data is composed by: + * @li 2 octets for Attribute Handle + * @li 2 octets for End Group Handle + * @li (attribute_data_length - 4) octets for Attribute Value + */ + uint8_t attribute_data_list[VARIABLE_SIZE]; +} PACKED evt_att_read_by_group_resp; + +/** + * This event is generated in response to a @a Prepare @a Write @a Request. + * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. + */ +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +typedef __packed struct _evt_att_prepare_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attribute_handle; /**< The handle of the attribute to be written. */ + uint16_t offset; /**< The offset of the first octet to be written. */ + uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ +} PACKED evt_att_prepare_write_resp; + +/** + * This event is generated in response to an @a Execute @a Write @a Request. + * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. + */ +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +typedef __packed struct _evt_att_exec_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Always 0. */ +} PACKED evt_att_exec_write_resp; + +/** + * This event is generated when an indication is received from the server. + * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. + */ +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +typedef __packed struct _evt_gatt_indication{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_indication; + +/** + * This event is generated when a notification is received from the server. + * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. + */ +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef __packed struct _evt_gatt_notification{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_attr_notification; + +/** + * This event is generated when a GATT client procedure completes either with error or successfully. + * See @ref _evt_gatt_procedure_complete. + */ +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef __packed struct _evt_gatt_procedure_complete{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ + uint8_t data_length; /**< Length of error_code field (always 1). */ + /** + * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). + */ + uint8_t error_code; +} PACKED evt_gatt_procedure_complete; + +/** + * This event is generated when an Error Response is received from the server. The error response can be given + * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended + * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. + */ +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +typedef __packed struct _evt_gatt_error_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t req_opcode; /**< The request that generated this error response. */ + uint16_t attr_handle; /**< The attribute handle that generated this error response. */ + uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ +} PACKED evt_gatt_error_resp; + +/** + * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using + * Characteristic UUID" procedure. + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. + */ +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + /** + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. + */ + uint8_t attr_value[VARIABLE_SIZE]; +} PACKED evt_gatt_disc_read_char_by_uuid_resp; + +/** + * This event is given to the application when a write request, write command or signed write command + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * If the write is rejected by the application, then the value of the attribute will not be modified. + * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. + * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef __packed struct _evt_gatt_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_write_permit_req; + +/** + * This event is given to the application when a read request or read blob request is received by the server + * from the client. This event will be given to the application only if the event bit for this event generation + * is set when the characteristic was added. + * On receiving this event, the application can update the value of the handle if it desires and when done + * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef __packed struct _evt_gatt_read_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ + uint8_t data_length; /**< Length of offset field. */ + uint16_t offset; /**< Contains the offset from which the read has been requested */ +} PACKED evt_gatt_read_permit_req; + +/** + * This event is given to the application when a read multiple request or read by type request is received + * by the server from the client. This event will be given to the application only if the event bit for this + * event generation is set when the characteristic was added. + * On receiving this event, the application can update the values of the handles if it desires and when done + * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_multi_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) +typedef __packed struct _evt_gatt_read_multi_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ +} PACKED evt_gatt_read_multi_permit_req; + +/** + * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2). + * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES. + * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value(). + * See @ref evt_gatt_tx_pool_vailable. + * + */ +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE (0x0C16) +typedef __packed struct _evt_gatt_tx_pool_available{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t available_buffers; /**< Length of data field. */ +} PACKED evt_gatt_tx_pool_available; + +/** + * This event is raised on the server when the client confirms the reception of an indication. + */ +#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT (0x0C17) +typedef __packed struct _evt_gatt_server_confirmation{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ +} PACKED evt_gatt_server_confirmation; +/** + * This event is given to the application when a prepare write request + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * Based on the response from the application, the attribute value will be modified by the stack. + * If the write is rejected by the application, then the value of the attribute will not be modified + * and an error response will be sent to the client, with the error code as specified by the application. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ (0x0C18) +typedef __packed struct _evt_gatt_prepare_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint16_t offset; /**< The offset from which the prepare write has been requested */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_prepare_write_permit_req; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,229 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gatt_server.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GATT server layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BNRG_GATT_SERVER_H__ +#define __BNRG_GATT_SERVER_H__ + +#include "ble_compiler.h" +#include "ble_status.h" + +/** + *@addtogroup GATT GATT + *@{ + */ + +/** + * @anchor Well-Known_UUIDs + * @name Well-Known UUIDs + * @{ + */ +#define PRIMARY_SERVICE_UUID (0x2800) +#define SECONDARY_SERVICE_UUID (0x2801) +#define INCLUDE_SERVICE_UUID (0x2802) +#define CHARACTERISTIC_UUID (0x2803) +#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) +#define CHAR_USER_DESC_UUID (0x2901) +#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) +#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) +#define CHAR_FORMAT_DESC_UUID (0x2904) +#define CHAR_AGGR_FMT_DESC_UUID (0x2905) +#define GATT_SERVICE_UUID (0x1801) +#define GAP_SERVICE_UUID (0x1800) +#define SERVICE_CHANGED_UUID (0x2A05) +/** + * @} + */ + +/** + * @anchor Access_permissions + * @name Access permissions + * Access permissions for an attribute + * @{ + */ +#define ATTR_NO_ACCESS (0x00) +#define ATTR_ACCESS_READ_ONLY (0x01) +#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) +#define ATTR_ACCESS_READ_WRITE (0x03) +#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) +#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) +/** + * Allows all write procedures + */ +#define ATTR_ACCESS_WRITE_ANY (0x0E) +/** + * @} + */ + +/** + * @anchor Char_properties + * @name Characteristic properties. + * @{ + */ +#define CHAR_PROP_BROADCAST (0x01) +#define CHAR_PROP_READ (0x02) +#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) +#define CHAR_PROP_WRITE (0x08) +#define CHAR_PROP_NOTIFY (0x10) +#define CHAR_PROP_INDICATE (0x20) +#define CHAR_PROP_SIGNED_WRITE (0x40) +#define CHAR_PROP_EXT (0x80) +/** + * @} + */ + + +/** + * @anchor Security_permissions + * @name Security permissions for an attribute. + * @{ + */ +#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ +#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ +#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ +#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ +/** + * @} + */ + +/** + * @anchor UUID_Types + * @name Type of UUID (16 bit or 128 bit). + * @{ + */ +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) +/** + * @} + */ + +/** + * @anchor Service_type + * @name Type of service (primary or secondary) + * @{ + */ +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) +/** + * @} + */ + +/** + * @anchor Gatt_Event_Mask + * @name Gatt Event Mask + * Type of event generated by GATT server + * @{ + */ +#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ +#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. + An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ +#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd + or a signed write cmd are received by the server for this attribute. + An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ +#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is + received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ +/** + * @} + */ + +/** + * @name Type of characteristic length + * See aci_gatt_add_char() + * @{ + */ +#define CHAR_VALUE_LEN_CONSTANT (0x00) +#define CHAR_VALUE_LEN_VARIABLE (0x01) +/** + * @} + */ + + +/** + * @name Encryption key size + * @{ + */ +/** + * Minimum encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Maximum encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) +/** + * @} + */ + +/** + * @name Characteristic Presentation Format + * @{ + */ +typedef __packed struct _charactFormat { + uint8_t format; + int8_t exp; + uint16_t unit; + uint8_t name_space; + uint16_t desc; +} PACKED charactFormat; + +/** + * @} + */ + +/** + * @name Format + * @{ + */ +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F +/** + * @} + */ + +/** + * @name Unit + * @{ + */ +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 +/** + * @} + */ + + +/** + * ATT MTU size + */ +#define ATT_MTU (23) + +/** + * @} + */ + + /** + * @name Update type of aci_gatt_upd_char_val_ext(). + * @{ + */ + +#define NOTIFICATION 1 +#define INDICATION 2 + +#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,385 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hal_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with HCI commands for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_HAL_ACI_H__ +#define __BLUENRG_HAL_ACI_H__ + +/** + *@addtogroup HAL HAL + *@brief Hardware Abstraction Layer. + *@{ + */ + +/** + * @defgroup HAL_Functions HAL functions + * @brief API for BlueNRG HAL layer. + * @{ + */ + +/** + * @brief This command retrieves the buid number of the firmware. + * @param[out] build_number Build number identifying the firmware release. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number); + +/** + * @brief This command writes a value to a low level configure data structure. + * @note It is useful to setup directly some low level parameters for the system at runtime. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * + * @param len Length of data to be written + * @param[out] val Data to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val); + +/** + * @brief This command requests the value in the low level configure data structure. + * The number of read bytes changes for different Offset. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * @param data_len Length of the data buffer + * @param[out] data_len_out_p length of the data returned by the read. + * @param[out] data Read data + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data); + +/** + * @brief This command sets the TX power level of the BlueNRG. + * @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines + * the output power level (dBm). + * When the system starts up or reboots, the default TX power level will be used, which is + * the maximum value of 8dBm. Once this command is given, the output power will be changed + * instantly, regardless if there is Bluetooth communication going on or not. For example, + * for debugging purpose, the BlueNRG can be set to advertise all the time and use this + * command to observe the signal strength changing. The system will keep the last received + * TX power level from the command, i.e. the 2nd command overwrites the previous TX power + * level. The new TX power level remains until another Set TX Power command, or the system + * reboots.\n + * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the + * right value, depending on the selected hardware configuration for the RF network: + * normal mode or high power mode. + * @param pa_level Can be from 0 to 7. Set the PA level value. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +/** + * @brief This command returns the number of packets sent in Direct Test Mode. + * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets + * have been transmitted. This command can be used to check how many packets have been sent + * during the Direct TX test.\n + * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again. + * The counter is not cleared until the next Direct TX test starts. + * @param[out] number_of_packets Number of packets sent during the last Direct TX test. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets); + +/** + * @brief Put the device in standby mode. + * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the + * device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode, + * the device can still wake up itself with the internal timer. But in standby mode, this timer is + * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command + * sent via SPI bus. + * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code + * ERR_COMMAND_DISALLOWED will be returned. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_device_standby(void); + +/** + * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. + * @note The frequency sine wave at the specific channel may be used for test purpose only. + * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. + * This command shouldn't be used when normal Bluetooth activities are ongoing. + * The tone should be stopped by aci_hal_tone_stop() command. + * + * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the + * channel central frequency minus 250 kHz. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +/** + * This command is used to stop the previously started aci_hal_tone_start() command. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_stop(void); + +/** + * @brief This command returns the status of all the connections. + * @note This command returns the status of the 8 Bluetooth low energy links managed by the device. + * @param[out] link_status Array of link status (8 links). See @ref Link_Status. + * @param[out] conn_handle Array of connection handles for each link. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]); + +/** + * @brief This command returns the anchor period and the largest available slot. + * @note This command returns information about the anchor period to help application in selecting + * slot timings when operating in multi-link scenarios. + * @param anchor_period Current anchor period (multiple of 0.625 ms). + * @param max_free_slot Maximum available time (multiple of 0.625 ms) that can be allocated for a new slot. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot); + +/** + * @} + */ + +/** + * @defgroup HAL_Events HAL events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_HAL_INITIALIZED (0x0001) +typedef __packed struct _evt_hal_initialized{ + uint8_t reason_code; /**< Reset reason. See @ref Reset_Reasons */ +} PACKED evt_hal_initialized; + +/** + * This event is generated when an overflow occurs in the event queue read by the external microcontroller. + * This is normally caused when the external microcontroller does not read pending events. + * The returned bitmap indicates which event has been lost. Please note that one bit set to 1 indicates one or + * more occurrences of the particular events. The event EVT_BLUE_HAL_EVENTS_LOST cannot be lost and it will + * be inserted in the event queue as soon as a position is freed in the event queue. This event should not + * happen under normal operating condition where external microcontroller promptly reads events signaled by + * IRQ pin. It is provided to detected unexpected behavior of the external microcontroller or to allow + * application to recover situations where critical events are lost. + */ +#define EVT_BLUE_HAL_EVENTS_LOST_IDB05A1 (0x0002) +typedef __packed struct _evt_hal_events_lost{ + uint8_t lost_events[8]; /**< Bitmap of lost events. Each bit indicates one or more occurrences of the specific event. See @ref Lost_Events */ +} PACKED evt_hal_events_lost_IDB05A1; + + +/** + * This event is given to the application after the @ref ACI_BLUE_INITIALIZED_EVENT + * when a system crash is detected. This events returns system crash information for debugging purposes. + * Information reported are useful to understand the root cause of the crash. + */ +#define EVT_BLUE_HAL_CRASH_INFO_IDB05A1 (0x0003) +typedef __packed struct _evt_hal_crash_info{ + uint8_t crash_type; /**< Type of crash: Assert failed (0), NMI Fault (1), Hard Fault (2) */ + uint32_t sp; /**< SP register */ + uint32_t r0; /**< R0 register */ + uint32_t r1; /**< R1 register */ + uint32_t r2; /**< R2 register */ + uint32_t r3; /**< R3 register */ + uint32_t r12; /**< R12 register */ + uint32_t lr; /**< LR register */ + uint32_t pc; /**< PC register */ + uint32_t xpsr; /**< xPSR register */ + uint8_t debug_data_len; /**< length of debug_data field */ + uint8_t debug_data[VARIABLE_SIZE]; /**< Debug data */ +} PACKED evt_hal_crash_info_IDB05A1; + + +/** + * @} + */ + + +/** + * @anchor Reset_Reasons + * @name Reset Reasons + * See @ref EVT_BLUE_HAL_INITIALIZED. + * @{ + */ +#define RESET_NORMAL 1 /**< Normal startup. */ +#define RESET_UPDATER_ACI 2 /**< Updater mode entered with ACI command */ +#define RESET_UPDATER_BAD_FLAG 3 /**< Updater mode entered due to a bad BLUE flag */ +#define RESET_UPDATER_PIN 4 /**< Updater mode entered with IRQ pin */ +#define RESET_WATCHDOG 5 /**< Reset caused by watchdog */ +#define RESET_LOCKUP 6 /**< Reset due to lockup */ +#define RESET_BROWNOUT 7 /**< Brownout reset */ +#define RESET_CRASH 8 /**< Reset caused by a crash (NMI or Hard Fault) */ +#define RESET_ECC_ERR 9 /**< Reset caused by an ECC error */ +/** + * @} + */ + + +/** + * @defgroup Config_vals Offsets and lengths for configuration values. + * @brief Offsets and lengths for configuration values. + * See aci_hal_write_config_data(). + * @{ + */ + +/** + * @name Configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ +#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ +#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ +#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ +#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. + It can be written only if aci_hal_write_config_data() is the first command after reset. */ +#define CONFIG_DATA_RANDOM_ADDRESS (0x80) /**< Stored static random address. Read-only. */ + +/** + * Select the BlueNRG mode configurations.\n + * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) + * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) + * @li Mode 3: master/slave, 8 connections, RAM1 and RAM2. + * @li Mode 4: master/slave, 4 connections, RAM1 and RAM2 simultaneous scanning and advertising. + */ +#define CONFIG_DATA_MODE_OFFSET (0x2D) + +#define CONFIG_DATA_WATCHDOG_DISABLE (0x2F) /**< Set to 1 to disable watchdog. It is enabled by default. */ +/** + * @} + */ + +/** + * @name Length for configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_LEN (6) +#define CONFIG_DATA_DIV_LEN (2) +#define CONFIG_DATA_ER_LEN (16) +#define CONFIG_DATA_IR_LEN (16) +#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) +#define CONFIG_DATA_MODE_LEN (1) +#define CONFIG_DATA_WATCHDOG_DISABLE_LEN (1) +/** + * @} + */ + +/** + * @anchor Link_Status + * @name Status of the link + * See @ref aci_hal_get_link_status(). + * @{ + */ +#define STATUS_IDLE 0 +#define STATUS_ADVERTISING 1 +#define STATUS_CONNECTED_AS_SLAVE 2 +#define STATUS_SCANNING 3 +#define STATUS_CONNECTED_AS_MASTER 5 +#define STATUS_TX_TEST 6 +#define STATUS_RX_TEST 7 +/** + * @} + */ + +/** + * @} + */ + + /** + * @anchor Lost_Events + * @name Lost events bitmap + * See @ref EVT_BLUE_HAL_EVENTS_LOST. + * @{ + */ +#define EVT_DISCONN_COMPLETE_BIT 0 +#define EVT_ENCRYPT_CHANGE_BIT 1 +#define EVT_READ_REMOTE_VERSION_COMPLETE_BIT 2 +#define EVT_CMD_COMPLETE_BIT 3 +#define EVT_CMD_STATUS_BIT 4 +#define EVT_HARDWARE_ERROR_BIT 5 +#define EVT_NUM_COMP_PKTS_BIT 6 +#define EVT_ENCRYPTION_KEY_REFRESH_BIT 7 +#define EVT_BLUE_HAL_INITIALIZED_BIT 8 +#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE_BIT 9 +#define EVT_BLUE_GAP_PAIRING_CMPLT_BIT 10 +#define EVT_BLUE_GAP_PASS_KEY_REQUEST_BIT 11 +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST_BIT 12 +#define EVT_BLUE_GAP_SECURITY_REQ_INITIATED_BIT 13 +#define EVT_BLUE_GAP_BOND_LOST_BIT 14 +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE_BIT 15 +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_BIT 16 +#define EVT_BLUE_L2CAP_CONN_UPDATE_RESP_BIT 17 +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT_BIT 18 +#define EVT_BLUE_L2CAP_CONN_UPDATE_REQ_BIT 19 +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_BIT 20 +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT_BIT 21 +#define EVT_BLUE_EXCHANGE_MTU_RESP_BIT 22 +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP_BIT 23 +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP_BIT 24 +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP_BIT 25 +#define EVT_BLUE_ATT_READ_RESP_BIT 26 +#define EVT_BLUE_ATT_READ_BLOB_RESP_BIT 27 +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP_BIT 28 +#define EVT_BLUE_ATT_READ_BY_GROUP_RESP_BIT 29 +#define EVT_BLUE_ATT_WRITE_RESP_BIT 30 +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP_BIT 31 +#define EVT_BLUE_ATT_EXEC_WRITE_RESP_BIT 32 +#define EVT_BLUE_GATT_INDICATION_BIT 33 +#define EVT_BLUE_GATT_NOTIFICATION_BIT 34 +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE_BIT 35 +#define EVT_BLUE_GATT_ERROR_RESP_BIT 36 +#define EVT_BLUE_GATT_DISC_READ_CHARAC_BY_UUID_RESP_BIT 37 +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ_BIT 38 +#define EVT_BLUE_GATT_READ_PERMIT_REQ_BIT 39 +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ_BIT 40 +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_BIT 41 +#define EVT_BLUE_GATT_SERVER_RX_CONFIRMATION_BIT 42 +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ_BIT 43 +#define EVT_LL_CONNECTION_COMPLETE_BIT 44 +#define EVT_LL_ADVERTISING_REPORT_BIT 45 +#define EVT_LL_CONNECTION_UPDATE_COMPLETE_BIT 46 +#define EVT_LL_READ_REMOTE_USED_FEATURES_BIT 47 +#define EVT_LL_LTK_REQUEST_BIT 48 +/** + * @} + */ + +/** + * @name Hardware error event codes + * See @ref EVT_HARDWARE_ERROR. + * @{ + */ +/** + * Error on the SPI bus has been detected, most likely caused by incorrect SPI configuration on the external micro-controller. + */ +#define SPI_FRAMING_ERROR 0 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define RADIO_STATE_ERROR 1 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define TIMER_OVERRUN_ERROR 2 + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,166 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_l2cap_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with L2CAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_L2CAP_ACI_H__ +#define __BLUENRG_L2CAP_ACI_H__ + +/** + *@addtogroup L2CAP L2CAP + *@brief L2CAP layer. + *@{ + */ + +/** + *@defgroup L2CAP_Functions L2CAP functions + *@brief API for L2CAP layer. + *@{ + */ + +/** + * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. + * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request + * (accepts or rejects). + * @param conn_handle Connection handle on which the connection parameter update request has to be sent. + * @param interval_min Defines minimum value for the connection event interval in the following manner: + * connIntervalMin = interval_min x 1.25ms + * @param interval_max Defines maximum value for the connection event interval in the following manner: + * connIntervalMax = interval_max x 1.25ms + * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). + * @param timeout_multiplier Defines connection timeout parameter in the following manner: + * timeout_multiplier x 10ms. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier); +/** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param min_ce_length Minimum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_ce_length Maximum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept); + /** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept); + +/** + * @} + */ + +/** + * @defgroup L2CAP_Events L2CAP events + * @{ + */ + +/** + * This event is generated when the master responds to the L2CAP connection update request packet. + * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. + */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef __packed struct _evt_l2cap_conn_upd_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ +/** + * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. + * @li 0x01 in case of Command Reject. + */ + uint8_t code; + uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ + uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ +/** + * Result code (parameters accepted or rejected) in case of Connection Parameter Update + * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). + */ + uint16_t result; +} PACKED evt_l2cap_conn_upd_resp; + +/** + * This event is generated when the master does not respond to the connection update request + * within 30 seconds. + */ +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) +typedef __packed struct _evt_l2cap_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */ +} PACKED evt_l2cap_procedure_timeout; + +/** + * The event is given by the L2CAP layer when a connection update request is received from the slave. + * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). + */ +#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) +typedef __packed struct _evt_l2cap_conn_upd_req{ +/** + * Handle of the connection for which the connection update request has been received. + * The same handle has to be returned while responding to the event with the command + * aci_l2cap_connection_parameter_update_response(). + */ + uint16_t conn_handle; + uint8_t event_data_length; /**< Length of following data. */ +/** + * This is the identifier which associates the request to the + * response. The same identifier has to be returned by the upper + * layer in the command aci_l2cap_connection_parameter_update_response(). + */ + uint8_t identifier; + uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ + uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ +} PACKED evt_l2cap_conn_upd_req; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_updater_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with updater commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_UPDATER_ACI_H__ +#define __BLUENRG_UPDATER_ACI_H__ + +#include <ble_compiler.h> + +/** + * @defgroup Updater Updater + * @brief Updater. + * @{ + */ + +/** + * @defgroup Updater_Functions Updater functions + * @brief API for BlueNRG Updater. + * @{ + */ + +tBleStatus aci_updater_start(void); + +tBleStatus aci_updater_reboot(void); + +tBleStatus aci_get_updater_version(uint8_t *version); + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); + +tBleStatus aci_erase_blue_flag(void); + +tBleStatus aci_reset_blue_flag(void); + +tBleStatus aci_updater_erase_sector(uint32_t address); + +tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); + +tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); + +tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); + +tBleStatus aci_updater_hw_version(uint8_t *version); + +/** + * @} + */ + +/** + * @defgroup Updater_Events Updater events + * @{ + */ +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_INITIALIZED (0x0001) +typedef __packed struct _evt_blue_initialized{ + uint8_t reason_code; +} PACKED evt_blue_initialized; +/** + * @} + */ + +/** + * @} + */ + + + +#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,204 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_utils.h +* Author : AMS - VMA, RF Application Team +* Version : V1.0.1 +* Date : 03-October-2014 +* Description : Header file for BlueNRG utility functions +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + * @file bluenrg_utils.h + * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description + * + * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> +**/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLUENRG_UTILS_H +#define __BLUENRG_UTILS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ble_hal_types.h" +#include "ble_compiler.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct{ + uint8_t stack_mode; + uint8_t day; + uint8_t month; + uint8_t year; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint16_t hs_startup_time; /* In system time units*/ +} IFR_config2_TypeDef; + +/** + * Structure inside IFR for configuration options. + */ +typedef __packed struct{ + uint8_t cold_ana_act_config_table[64]; + uint8_t hot_ana_config_table[64]; + uint8_t stack_mode; + uint8_t gpio_config; + uint8_t rsrvd1[2]; + uint32_t rsrvd2[3]; + uint32_t max_conn_event_time; + uint32_t ls_crystal_period; + uint32_t ls_crystal_freq; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint8_t rsrvd3; + uint16_t hs_startup_time; /* In system time units*/ + uint8_t rsrvd4[2]; + uint32_t uid; + uint8_t rsrvd5; + uint8_t year; + uint8_t month; + uint8_t day; + uint32_t unused[5]; +} PACKED IFR_config_TypeDef; + +/* Exported constants --------------------------------------------------------*/ +extern const IFR_config_TypeDef IFR_config; + +/* Exported macros -----------------------------------------------------------*/ +#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)+1) +#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) + +/* Convert 2 digit BCD number to an integer */ +#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) + +/* Convert 2 digit number to a BCD number */ +#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) + +/** + * Return values + */ +#define BLE_UTIL_SUCCESS 0 +#define BLE_UTIL_UNSUPPORTED_VERSION 1 +#define BLE_UTIL_WRONG_IMAGE_SIZE 2 +#define BLE_UTIL_ACI_ERROR 3 +#define BLE_UTIL_CRC_ERROR 4 +#define BLE_UTIL_PARSE_ERROR 5 +#define BLE_UTIL_WRONG_VERIFY 6 + +/* Exported functions ------------------------------------------------------- */ +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int program_device(const uint8_t *fw_image, uint32_t fw_size); + +/** + * @brief Read raw data from IFR (3 64-bytes blocks). + * @param data Pointer to the buffer that will contain the read data. + * Its size must be 192 bytes. This data can be parsed by + * parse_IFR_data_config(). + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION) + */ +int read_IFR(uint8_t data[192]); + +/** + * @brief Verify raw data from IFR (3 64-bytes blocks). + * @param ifr_data Pointer to the buffer that will contain the data to verify. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) + */ +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); + +/** + * @brief Program raw data to IFR (3 64-bytes blocks). + * @param ifr_image Pointer to the buffer that will contain the data to program. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful + */ +int program_IFR(const IFR_config_TypeDef *ifr_image); + +/** + * @brief Parse IFR raw data. + * @param data Pointer to the raw data: last 64 bytes read from IFR sector. + * @param IFR_config Data structure that will be filled with parsed data. + * @retval None + */ +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); + +/** + * @brief Check for the correctness of parsed data. + * @param IFR_config Data structure filled with parsed data. + * @retval int It returns 0 if successful, or PARSE_ERROR in case data is + * not correct. + */ +int IFR_validate(IFR_config2_TypeDef *IFR_config); + +/** + * @brief Modify IFR data. (Last 64-bytes block). + * @param IFR_config Structure that contains the new parameters inside the + * IFR configuration data. + * @note It is highly recommended to parse the IFR configuration from + * a working IFR block (this should be done with parse_IFR_data_config()). + * Then it is possible to write the new parameters inside the IFR_config + * structure. + * @param data Pointer to the buffer that contains the original data. It + * will be modified according to the new data in the IFR_config + * structure. Then this data must be written in the last + * 64-byte block in the IFR. + * Its size must be 64 bytes. + * @retval None + */ +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); + +/** + * @brief Get BlueNRG hardware and firmware version + * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). + * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN + * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. + * @retval Status of the call + */ +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); + +/** + * @brief Get BlueNRG updater version + * @param version This parameter returns the updater version. If the updadter version is 0x03 + * the chip has the updater old, needs to update the bootloader. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterVersion(uint8_t *version); + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version); + +/** + * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on + * the HW bootloader related to the 32 MHz external crystal oscillator. + * @retval TRUE if the HW bootloader is already patched, FALSE otherwise + */ +uint8_t isHWBootloader_Patched(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__BLUENRG_UTILS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file bluenrg_targets.h + * @author AST / EST + * @version V0.0.1 + * @date 24-July-2015 + * @brief This header file is intended to manage the differences between + * the different supported base-boards which might mount the + * X_NUCLEO_IDB0XA1 BlueNRG BLE Expansion Board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent from recursive inclusion --------------------------------*/ +#ifndef _BLUENRG_TARGETS_H_ +#define _BLUENRG_TARGETS_H_ + +#if !defined(BLUENRG_PIN_SPI_MOSI) +#define BLUENRG_PIN_SPI_MOSI (D11) +#endif +#if !defined(BLUENRG_PIN_SPI_MISO) +#define BLUENRG_PIN_SPI_MISO (D12) +#endif +#if !defined(BLUENRG_PIN_SPI_nCS) +#define BLUENRG_PIN_SPI_nCS (A1) +#endif +#if !defined(BLUENRG_PIN_SPI_RESET) +#define BLUENRG_PIN_SPI_RESET (D7) +#endif +#if !defined(BLUENRG_PIN_SPI_IRQ) +#define BLUENRG_PIN_SPI_IRQ (A0) +#endif + +/* NOTE: Refer to README for further details regarding BLUENRG_PIN_SPI_SCK */ +#if !defined(BLUENRG_PIN_SPI_SCK) +#define BLUENRG_PIN_SPI_SCK (D3) +#endif + +/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv) + * Mode 0x01: slave or master, 1 connection + * Mode 0x02: slave or master, 1 connection + * Mode 0x03: master/slave, 8 connections + * Mode 0x04: master/slave, 4 connections (simultaneous scanning and advertising) + * Check Table 285 of + * BlueNRG-MS Bluetooth LE stack application command interface (ACI) User Manual (UM1865) at st.com + */ +#if !defined(BLUENRG_STACK_MODE) +#define BLUENRG_STACK_MODE (0x04) +#endif + +#endif // _BLUENRG_TARGTES_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef _BTLE_H_ +#define _BTLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "bluenrg_aci.h" +#include "ble_hci_const.h" +#include "bluenrg_hal_aci.h" +#include "stm32_bluenrg_ble.h" +#include "bluenrg_gap.h" +#include "bluenrg_gatt_server.h" + +extern uint16_t g_gap_service_handle; +extern uint16_t g_appearance_char_handle; +extern uint16_t g_device_name_char_handle; +extern uint16_t g_preferred_connection_parameters_char_handle; + +void btleInit(void); +void SPI_Poll(void); +void User_Process(void); +void setConnectable(void); +void setVersionString(uint8_t hwVersion, uint16_t fwVersion); +const char* getVersionString(void); +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type); + + +extern int btle_handler_pending; +extern void btle_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.h + * @author CL + * @version V1.0.1 + * @date 15-June-2014 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_BLUENRG_BLE_H +#define __STM32_BLUENRG_BLE_H + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdint.h> +#include "ble_gp_timer.h" +#include "ble_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup X-NUCLEO-IDB04A1 + * @{ + */ + +/** @addtogroup STM32_BLUENRG_BLE + * @{ + */ + +/** @defgroup STM32_BLUENRG_BLE_Exported_Functions + * @{ + */ + +// FIXME: add prototypes for BlueNRG here +void BlueNRG_RST(void); +uint8_t BlueNRG_DataPresent(void); +void BlueNRG_HW_Bootloader(void); +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size); +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, + uint8_t Nb_bytes1, + uint8_t Nb_bytes2); +void Clear_SPI_EXTI_Flag(void); + +void print_csv_time(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_BLUENRG_BLE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_debug.h" + +#ifndef __PAYLOAD_H__ +#define __PAYLOAD_H__ + +class UnitPayload +{ +public: + uint8_t length; + uint8_t id; + uint8_t *data; + uint8_t *idptr; + + + + void set_length(uint8_t l) { + length=l; + } + + void set_id(uint8_t i) { + id=i; + } + + void set_data(uint8_t* data1) { + for(int j=0;j<length;j++) + { + data[j]=data1[j]; + } + } + + uint8_t get_length() { + return length; + } + + uint8_t get_id() { + return id; + } + + uint8_t* get_data() { + return data; + } + +}; + +class Payload { + UnitPayload *payload; + int stringLength; + int payloadUnitCount; + +public: + Payload(const uint8_t *tokenString, uint8_t string_ength); + Payload(); + ~Payload(); + uint8_t getPayloadUnitCount(); + + uint8_t getIDAtIndex(int index); + uint8_t getLengthAtIndex(int index); + uint8_t* getDataAtIndex(int index); + int8_t getInt8AtIndex(int index); + uint16_t getUint16AtIndex(int index); + uint8_t* getSerializedAdDataAtIndex(int index); +}; + + +class PayloadUnit { +private: + uint8_t* lenPtr; + uint8_t* adTypePtr; + uint8_t* dataPtr; + +public: + PayloadUnit() { + lenPtr = NULL; + adTypePtr = NULL; + dataPtr = NULL; + } + + PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { + lenPtr = len; + adTypePtr = adType; + dataPtr = data; + } + + void setLenPtr(uint8_t *len) { + lenPtr = len; + } + + void setAdTypePtr(uint8_t *adType) { + adTypePtr = adType; + } + + void setDataPtr(uint8_t *data) { + dataPtr = data; + } + + uint8_t* getLenPtr() { + return lenPtr; + } + + uint8_t* getAdTypePtr() { + return adTypePtr; + } + + uint8_t* getDataPtr() { + return dataPtr; + } + + void printDataAsHex() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("0x%x ", dataPtr[i]); + } + PRINTF("\n"); + } + + void printDataAsString() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("%c", dataPtr[i]); + } + PRINTF("\n"); + } + +}; + +class PayloadPtr { +private: + PayloadUnit *unit; + int payloadUnitCount; +public: + PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + int stringLength = string_ength; + payloadUnitCount = 0; + + int index = 0; + while(index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + // allocate memory to unit + unit = new PayloadUnit[payloadUnitCount]; + int i = 0; + int nextUnitOffset = 0; + + while(i<payloadUnitCount) { + unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); + unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); + unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); + + nextUnitOffset += *unit[i].getLenPtr()+1; + i++; + + } + } + + PayloadUnit getUnitAtIndex(int index) { + return unit[index]; + } + + int getPayloadUnitCount() { return payloadUnitCount; } + + ~PayloadPtr() { + if(unit) delete[] unit; + + unit = NULL; + } +}; + +#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include "ble_status.h" +#include "ble_hal_types.h" + +#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do {\ + uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ + }while(0) + + +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); + +#endif // __UTIL_H__ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/mbed_lib.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "bluenrg", + "target_overrides": { + "K64F": { + "target.macros_add": ["BLUENRG_PIN_SPI_SCK=D13"] + }, + "DISCO_L475VG_IOT01A": { + "target.macros_add": ["BLUENRG_PIN_SPI_MOSI=PC_12", + "BLUENRG_PIN_SPI_MISO=PC_11", + "BLUENRG_PIN_SPI_nCS=PD_13", + "BLUENRG_PIN_SPI_RESET=PA_8", + "BLUENRG_PIN_SPI_IRQ=PE_6", + "BLUENRG_PIN_SPI_SCK=PC_10"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,37 @@ +{ + "name": "x-nucleo-idb0xa1", + "version": "2.2.0", + "description": "ST driver for the mbed BLE API.", + "keywords": [ + "expansion", + "board", + "x-nucleo", + "nucleo", + "ST", + "STM", + "Bluetooth", + "BLE" + ], + "author": "Andrea Palmieri", + "repository": { + "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git", + "type": "git" + }, + "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "extraIncludes": [ + "x-nucleo-idb0xa1", + "x-nucleo-idb0xa1/utils", + "x-nucleo-idb0xa1/platform", + "x-nucleo-idb0xa1/bluenrg-hci" + ], + "dependencies": { + "mbed-drivers": ">=0.11.3", + "ble": "^2.7.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,474 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.cpp + * @author STMicroelectronics + * @brief Implementation of BLEDeviceInstanceBase + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGDevice + * @brief BlueNRG BLE_API Device Adaptation + * @{ + */ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGDevice.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" + +#include "btle.h" +#include "ble_utils.h" +#include "ble_osal.h" + +#include "ble_debug.h" +#include "stm32_bluenrg_ble.h" + +extern "C" { + #include "ble_hci.h" + #include "bluenrg_utils.h" +} + +#define HEADER_SIZE 5 +#define MAX_BUFFER_SIZE 255 + +/** + * The singleton which represents the BlueNRG transport for the BLEDevice. + * + * See file 'bluenrg_targets.h' for details regarding the peripheral pins used! + */ +#include "bluenrg_targets.h" + +BlueNRGDevice bluenrgDeviceInstance(BLUENRG_PIN_SPI_MOSI, + BLUENRG_PIN_SPI_MISO, + BLUENRG_PIN_SPI_SCK, + BLUENRG_PIN_SPI_nCS, + BLUENRG_PIN_SPI_RESET, + BLUENRG_PIN_SPI_IRQ); + +/** +* BLE-API requires an implementation of the following function in order to +* obtain its transport handle. +*/ +BLEInstanceBase * +createBLEInstance(void) +{ + return (&bluenrgDeviceInstance); +} + +/**************************************************************************/ +/** + @brief Constructor + * @param mosi mbed pin to use for MOSI line of SPI interface + * @param miso mbed pin to use for MISO line of SPI interface + * @param sck mbed pin to use for SCK line of SPI interface + * @param cs mbed pin to use for not chip select line of SPI interface + * @param rst mbed pin to use for BlueNRG reset + * @param irq mbed pin for BlueNRG IRQ +*/ +/**************************************************************************/ +BlueNRGDevice::BlueNRGDevice(PinName mosi, + PinName miso, + PinName sck, + PinName cs, + PinName rst, + PinName irq) : + isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq) +{ + // Setup the spi for 8 bit data, low clock polarity, + // 1-edge phase, with an 8MHz clock rate + spi_.format(8, 0); + spi_.frequency(8000000); + + // Deselect the BlueNRG chip by keeping its nCS signal high + nCS_ = 1; + + wait_us(500); + + // Prepare communication between the host and the BlueNRG SPI interface + HCI_Init(); + + // Set the interrupt handler for the device + irq_.mode(PullDown); // set irq mode + irq_.rise(&HCI_Isr); +} + +/**************************************************************************/ +/** + @brief Destructor +*/ +/**************************************************************************/ +BlueNRGDevice::~BlueNRGDevice(void) +{ +} + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param hw_version The HW version is written to this parameter + * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise + */ +uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version) +{ + uint8_t status; + + status = getBlueNRGUpdaterHWVersion(hw_version); + + return (status); +} + +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns BLE_STATUS_SUCCESS on success, or a number + * not equal to 0 in case of error + * (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size) +{ + int status = program_device(fw_image, fw_size); + + return (status); +} + + +/** + * @brief Initialises anything required to start using BLE + * @param[in] instanceID + * The ID of the instance to initialize. + * @param[in] callback + * A callback for when initialization completes for a BLE + * instance. This is an optional parameter set to NULL when not + * supplied. + * + * @return BLE_ERROR_NONE if the initialization procedure was started + * successfully. + */ +ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback) +{ + if (isInitialized) { + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_ALREADY_INITIALIZED + }; + callback.call(&context); + return BLE_ERROR_ALREADY_INITIALIZED; + } + + // Init the BlueNRG/BlueNRG-MS stack + btleInit(); + + isInitialized = true; + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_NONE + }; + callback.call(&context); + + return BLE_ERROR_NONE; +} + + +/** + @brief Resets the BLE HW, removing any existing services and + characteristics + @param[in] void + @returns void +*/ +void BlueNRGDevice::reset(void) +{ + /* Reset BlueNRG SPI interface. Hold reset line to 0 for 1500us */ + rst_ = 0; + wait_us(1500); + rst_ = 1; + + /* Wait for the radio to come back up */ + wait_us(5000); +} + +/*! + @brief Wait for any BLE Event like BLE Connection, Read Request etc. + @param[in] void + @returns char * +*/ +void BlueNRGDevice::waitForEvent(void) +{ + bool must_return = false; + + do { + bluenrgDeviceInstance.processEvents(); + + if(must_return) return; + + __WFE(); /* it is recommended that SEVONPEND in the + System Control Register is NOT set */ + must_return = true; /* after returning from WFE we must guarantee + that conrol is given back to main loop before next WFE */ + } while(true); + +} + +/*! + @brief get GAP version + @brief Get the BLE stack version information + @param[in] void + @returns char * + @returns char * +*/ +const char *BlueNRGDevice::getVersion(void) +{ + return getVersionString(); +} + +/**************************************************************************/ +/*! + @brief get reference to GAP object + @param[in] void + @returns Gap& +*/ +/**************************************************************************/ +Gap &BlueNRGDevice::getGap() +{ + return BlueNRGGap::getInstance(); +} + +const Gap &BlueNRGDevice::getGap() const +{ + return BlueNRGGap::getInstance(); +} + +/**************************************************************************/ +/*! + @brief get reference to GATT server object + @param[in] void + @returns GattServer& +*/ +/**************************************************************************/ +GattServer &BlueNRGDevice::getGattServer() +{ + return BlueNRGGattServer::getInstance(); +} + +const GattServer &BlueNRGDevice::getGattServer() const +{ + return BlueNRGGattServer::getInstance(); +} + +/**************************************************************************/ +/*! + @brief shut down the BLE device + @param[out] error if any +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::shutdown(void) { + PRINTF("BlueNRGDevice::reset\n"); + + if (!isInitialized) { + return BLE_ERROR_INITIALIZATION_INCOMPLETE; + } + + /* Reset the BlueNRG device first */ + reset(); + + /* Shutdown the BLE API and BlueNRG glue code */ + ble_error_t error; + + /* GattServer instance */ + error = BlueNRGGattServer::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* GattClient instance */ + error = BlueNRGGattClient::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* Gap instance */ + error = BlueNRGGap::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + isInitialized = false; + + PRINTF("BlueNRGDevice::reset complete\n"); + return BLE_ERROR_NONE; + +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size) +{ + uint16_t byte_count; + uint8_t len = 0; + uint8_t char_ff = 0xff; + volatile uint8_t read_char; + + uint8_t i = 0; + volatile uint8_t tmpreg; + + uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00}; + uint8_t header_slave[HEADER_SIZE]; + + /* Select the chip */ + nCS_ = 0; + + /* Read the header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = (uint8_t)(tmpreg); + } + + if (header_slave[0] == 0x02) { + /* device is ready */ + byte_count = (header_slave[4]<<8)|header_slave[3]; + + if (byte_count > 0) { + + /* avoid to read more data that size of the buffer */ + if (byte_count > buff_size){ + byte_count = buff_size; + } + + for (len = 0; len < byte_count; len++){ + read_char = spi_.write(char_ff); + buffer[len] = read_char; + } + } + } + /* Release CS line to deselect the chip */ + nCS_ = 1; + + // Add a small delay to give time to the BlueNRG to set the IRQ pin low + // to avoid a useless SPI read at the end of the transaction + for(volatile int i = 0; i < 2; i++)__NOP(); + +#ifdef PRINT_CSV_FORMAT + if (len > 0) { + print_csv_time(); + for (int i=0; i<len; i++) { + PRINT_CSV(" %02x", buffer[i]); + } + PRINT_CSV("\n"); + } +#endif + + return len; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRGDevice::spiWrite(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t result = 0; + uint32_t i; + volatile uint8_t tmpreg; + + unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00}; + + disable_irq(); + + /* CS reset */ + nCS_ = 0; + + /* Exchange header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = tmpreg; + } + + if (header_slave[0] == 0x02) { + /* SPI is ready */ + if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { + + /* Buffer is big enough */ + for (i = 0; i < Nb_bytes1; i++) { + spi_.write(*(data1 + i)); + } + for (i = 0; i < Nb_bytes2; i++) { + spi_.write(*(data2 + i)); + } + } else { + /* Buffer is too small */ + result = -2; + } + } else { + /* SPI is not ready */ + result = -1; + } + + /* Release CS line */ + //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); + nCS_ = 1; + + enable_irq(); + + return result; +} + +bool BlueNRGDevice::dataPresent() +{ + return (irq_ == 1); +} + +void BlueNRGDevice::disable_irq() +{ + irq_.disable_irq(); +} + +void BlueNRGDevice::enable_irq() +{ + irq_.enable_irq(); +} + +void BlueNRGDevice::processEvents() { + btle_handler(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,68 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattClient.h" + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + uuid = uuidIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + + void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) { + lastHandle = lastHandleIn; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1477 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file BlueNRGGap.cpp + * @author STMicroelectronics + * @brief Implementation of BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGap + * @brief BlueNRG BLE_API GAP Adaptation + * @{ + */ + +#include "BlueNRGDevice.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_payload.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/* + * Utility to process GAP specific events (e.g., Advertising timeout) + */ +void BlueNRGGap::Process(void) +{ + if(AdvToFlag) { + AdvToFlag = false; + stopAdvertising(); + } + + if(ScanToFlag) { + ScanToFlag = false; + stopScan(); + } +} + +/**************************************************************************/ +/*! + @brief Sets the advertising parameters and payload for the device. + Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API + + @params[in] advData + The primary advertising data payload + @params[in] scanResponse + The optional Scan Response payload if the advertising + type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED + in \ref GapAdveritinngParams + + @returns \ref ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @retval BLE_ERROR_BUFFER_OVERFLOW + The proposed action would cause a buffer overflow. All + advertising payloads must be <= 31 bytes, for example. + + @retval BLE_ERROR_NOT_IMPLEMENTED + A feature was requested that is not yet supported in the + nRF51 firmware or hardware. + + @retval BLE_ERROR_PARAM_OUT_OF_RANGE + One of the proposed values is outside the valid range. + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) +{ + PRINTF("BlueNRGGap::setAdvertisingData\n\r"); + /* Make sure we don't exceed the advertising payload length */ + if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + PRINTF("Exceeded the advertising payload length\n\r"); + return BLE_ERROR_BUFFER_OVERFLOW; + } + + /* Make sure we have a payload! */ + if (advData.getPayloadLen() != 0) { + PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); + + /* Align the GAP Service Appearance Char value coherently + This setting is duplicate (see below GapAdvertisingData::APPEARANCE) + since BLE API has an overloaded function for appearance + */ + STORE_LE_16(deviceAppearance, advData.getAppearance()); + setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0])); + + + for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { + loadPtr.getUnitAtIndex(index); + + PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); + PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); + + switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { + /**< TX Power Level (in dBm) */ + case GapAdvertisingData::TX_POWER_LEVEL: + { + PRINTF("Advertising type: TX_POWER_LEVEL\n\r"); + int8_t enHighPower = 0; + int8_t paLevel = 0; + + int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); + tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); +#ifdef DEBUG + PRINTF("dbm=%d, ret=%d\n\r", dbm, ret); + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); +#endif + if(ret == BLE_STATUS_SUCCESS) { + aci_hal_set_tx_power_level(enHighPower, paLevel); + } + break; + } + /**< Appearance */ + case GapAdvertisingData::APPEARANCE: + { + PRINTF("Advertising type: APPEARANCE\n\r"); + + GapAdvertisingData::Appearance appearanceP; + memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2); + + PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]); + /* Align the GAP Service Appearance Char value coherently */ + setAppearance(appearanceP); + break; + } + + } // end switch + + } //end for + + } + + // update the advertising data in the shield if advertising is running + if (state.advertising == 1) { + tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS != ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload()); + if (ret) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + } + + _advData = advData; + _scanResponse = scanResponse; + + return BLE_ERROR_NONE; +} + +/* + * Utility to set ADV timeout flag + */ +void BlueNRGGap::setAdvToFlag(void) { + AdvToFlag = true; + signalEventsToProcess(); +} + +/* + * ADV timeout callback + */ +#ifdef AST_FOR_MBED_OS +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().stopAdvertising(); +} +#else +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().setAdvToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getAdvTimeout(); + t.detach(); /* disable the callback from the timeout */ +} +#endif /* AST_FOR_MBED_OS */ + +/* + * Utility to set SCAN timeout flag + */ +void BlueNRGGap::setScanToFlag(void) { + ScanToFlag = true; + signalEventsToProcess(); +} + +static void scanTimeoutCB(void) +{ + BlueNRGGap::getInstance().setScanToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getScanTimeout(); + t.detach(); /* disable the callback from the timeout */ +} + +/**************************************************************************/ +/*! + @brief Starts the BLE HW, initialising any services that were + added before this function was called. + + @param[in] params + Basic advertising details, including the advertising + delay, timeout and how the device should be advertised + + @note All services must be added before calling this function! + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ + +ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) +{ + tBleStatus ret; + int err; + + /* Make sure we support the advertising type */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { + /* ToDo: This requires a proper security implementation, etc. */ + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /* Check interval range */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { + /* Min delay is slightly longer for unconnectable devices */ + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } else { + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } + + /* Check timeout is zero for Connectable Directed */ + if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { + /* Timeout must be 0 with this type, although we'll never get here */ + /* since this isn't implemented yet anyway */ + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* Check timeout for other advertising types */ + if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && + (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* + * Advertising filter policy setting + * FIXME: the Security Manager should be implemented + */ + AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode(); + if(mode != ADV_POLICY_IGNORE_WHITELIST) { + ret = aci_gap_configure_whitelist(); + if(ret != BLE_STATUS_SUCCESS) { + PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret); + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } + + uint8_t advFilterPolicy = NO_WHITE_LIST_USE; + switch(mode) { + case ADV_POLICY_FILTER_SCAN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN; + break; + case ADV_POLICY_FILTER_CONN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN; + break; + case ADV_POLICY_FILTER_ALL_REQS: + advFilterPolicy = WHITE_LIST_FOR_ALL; + break; + default: + advFilterPolicy = NO_WHITE_LIST_USE; + break; + } + + /* Check the ADV type before setting scan response data */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED || + params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) { + + /* set scan response data */ + PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen()); + ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS!=ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + } else { + hci_le_set_scan_resp_data(0, NULL); + } + + setAdvParameters(); + PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType()); + + err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload()); + + if (err) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + + tBDAddr dummy_addr = { 0 }; + uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval; + uint16_t advIntervalMax = advIntervalMin + 1; + + err = hci_le_set_advertising_parameters( + advIntervalMin, + advIntervalMax, + params.getAdvertisingType(), + addr_type, + 0x00, + dummy_addr, + /* all channels */ 7, + advFilterPolicy + ); + + if (err) { + PRINTF("impossible to set advertising parameters\n\r"); + PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1); + PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy); + return BLE_ERROR_INVALID_PARAM; + } + + err = hci_le_set_advertise_enable(0x01); + if (err) { + PRINTF("impossible to start advertising\n\r"); + return BLE_ERROR_UNSPECIFIED; + } + + if(params.getTimeout() != 0) { + PRINTF("!!! attaching adv to!!!\n"); +#ifdef AST_FOR_MBED_OS + minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000)); +#else + advTimeout.attach(advTimeoutCB, params.getTimeout()); +#endif + } + + return BLE_ERROR_NONE; + +} + + +/**************************************************************************/ +/*! + @brief Stops the BLE HW and disconnects from any devices + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::stopAdvertising(void) +{ + if(state.advertising == 1) { + + int err = hci_le_set_advertise_enable(0); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + PRINTF("Advertisement stopped!!\n\r") ; + //Set GapState_t::advertising state + state.advertising = 0; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason) +{ + tBleStatus ret; + + ret = aci_gap_terminate(connectionHandle, reason); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_COMMAND_DISALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason) +{ + return disconnect(m_connectionHandle, reason); +} + +/**************************************************************************/ +/*! + @brief Sets the 16-bit connection handle + + @param[in] conn_handle + Connection Handle which is set in the Gap Instance + + @returns void +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionHandle(uint16_t conn_handle) +{ + m_connectionHandle = conn_handle; +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit connection handle + + @param[in] void + + @returns uint16_t + Connection Handle of the Gap Instance +*/ +/**************************************************************************/ +uint16_t BlueNRGGap::getConnectionHandle(void) +{ + return m_connectionHandle; +} + +/**************************************************************************/ +/*! + @brief Sets the BLE device address. SetAddress will reset the BLE + device and re-initialize BTLE. Will not start advertising. + + @param[in] type + Type of Address + + @param[in] address[6] + Value of the Address to be set + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address) +{ + if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if(type == BLEProtocol::AddressType::PUBLIC){ + tBleStatus ret = aci_hal_write_config_data( + CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + address + ); + if(ret != BLE_STATUS_SUCCESS) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } else if (type == BLEProtocol::AddressType::RANDOM_STATIC) { + // ensure that the random static address is well formed + if ((address[5] & 0xC0) != 0xC0) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // thanks to const correctness of the API ... + tBDAddr random_address = { 0 }; + memcpy(random_address, address, sizeof(random_address)); + int err = hci_le_set_random_address(random_address); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // It is not possible to get the bluetooth address when it is set + // store it locally in class data member + memcpy(bdaddr, address, sizeof(bdaddr)); + } else { + // FIXME random addresses are not supported yet + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + // if we're here then the address was correctly set + // commit it inside the addr_type + addr_type = type; + isSetAddress = true; + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Returns boolean if the address of the device has been set + or not + + @returns bool + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +bool BlueNRGGap::getIsSetAddress() +{ + return isSetAddress; +} + +/**************************************************************************/ +/*! + @brief Returns the address of the device if set + + @returns Pointer to the address if Address is set else NULL + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) +{ + uint8_t bdaddr[BDADDR_SIZE]; + uint8_t data_len_out; + + // precondition, check that pointers in input are valid + if (typeP == NULL || address == NULL) { + return BLE_ERROR_INVALID_PARAM; + } + + if (addr_type == BLEProtocol::AddressType::PUBLIC) { + tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr); + if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) { + return BLE_ERROR_UNSPECIFIED; + } + } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) { + // FIXME hci_read_bd_addr and + // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1 + // does not work, use the address stored in class data member + memcpy(bdaddr, this->bdaddr, sizeof(bdaddr)); + } else { + // FIXME: should be implemented with privacy features + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + *typeP = addr_type; + memcpy(address, bdaddr, BDADDR_SIZE); + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief obtains preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + + if (!g_preferred_connection_parameters_char_handle) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // Peripheral preferred connection parameters are an array of 4 uint16_t + uint8_t parameters_packed[parameter_size * 4]; + uint16_t bytes_read = 0; + + tBleStatus err = aci_gatt_read_handle_value( + g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE, + sizeof(parameters_packed), + &bytes_read, + parameters_packed + ); + + PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read); + + // check that the read succeed and the result have the expected length + if (err || bytes_read != sizeof(parameters_packed)) { + return BLE_ERROR_UNSPECIFIED; + } + + // memcpy field by field + memcpy(¶ms->minConnectionInterval, parameters_packed, parameter_size); + memcpy(¶ms->maxConnectionInterval, ¶meters_packed[parameter_size], parameter_size); + memcpy(¶ms->slaveLatency, ¶meters_packed[2 * parameter_size], parameter_size); + memcpy(¶ms->connectionSupervisionTimeout, ¶meters_packed[3 * parameter_size], parameter_size); + + return BLE_ERROR_NONE; +} + + +/**************************************************************************/ +/*! + @brief sets preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + uint8_t parameters_packed[parameter_size * 4]; + + // ensure that parameters are correct + // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC + if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) && + params->minConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) && + params->maxConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (params->slaveLatency > 0x01F3) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) && + params->connectionSupervisionTimeout != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // copy the parameters inside the byte array + memcpy(parameters_packed, ¶ms->minConnectionInterval, parameter_size); + memcpy(¶meters_packed[parameter_size], ¶ms->maxConnectionInterval, parameter_size); + memcpy(¶meters_packed[2 * parameter_size], ¶ms->slaveLatency, parameter_size); + memcpy(¶meters_packed[3 * parameter_size], ¶ms->connectionSupervisionTimeout, parameter_size); + + tBleStatus err = aci_gatt_update_char_value( + g_gap_service_handle, + g_preferred_connection_parameters_char_handle, + /* offset */ 0, + sizeof(parameters_packed), + parameters_packed + ); + + if (err) { + PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ; + switch (err) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief updates preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) +{ + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(gapRole == Gap::CENTRAL) { + ret = aci_gap_start_connection_update(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout, + CONN_L1, CONN_L2); + } else { + ret = aci_l2cap_connection_parameter_update_request(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout); + } + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case ERR_COMMAND_DISALLOWED: + case BLE_STATUS_NOT_ALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sets the Device Name Characteristic + + @param[in] deviceName + pointer to device name to be set + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) +{ + tBleStatus ret; + uint8_t nameLen = 0; + + nameLen = strlen((const char*)deviceName); + PRINTF("DeviceName Size=%d\n\r", nameLen); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_device_name_char_handle, + 0, + nameLen, + deviceName); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Gets the Device Name Characteristic + + @param[in] deviceName + pointer to device name + + @param[in] lengthP + pointer to device name length + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) +{ + tBleStatus ret; + + ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + *lengthP, + (uint16_t *)lengthP, + deviceName); + PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } +} + +/**************************************************************************/ +/*! + @brief Sets the Device Appearance Characteristic + + @param[in] appearance + device appearance + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance) +{ + tBleStatus ret; + uint8_t deviceAppearance[2]; + + STORE_LE_16(deviceAppearance, appearance); + PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_appearance_char_handle, + 0, 2, (uint8_t *)deviceAppearance); + if (BLE_STATUS_SUCCESS == ret){ + return BLE_ERROR_NONE; + } + + PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Gets the Device Appearance Characteristic + + @param[in] appearance + pointer to device appearance value + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) +{ + tBleStatus ret; + uint16_t lengthP = 2; + + ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + lengthP, + &lengthP, + (uint8_t*)appearanceP); + PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + +} + +GapScanningParams* BlueNRGGap::getScanningParams(void) +{ + return &_scanningParams; +} + +static void makeConnection(void) +{ + BlueNRGGap::getInstance().createConnection(); +} + +void BlueNRGGap::Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI) +{ + switch (reason) { + case DEVICE_FOUND: + { + GapAdvertisingParams::AdvertisingType_t type; + bool isScanResponse = false; + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * Private Random Address + * => scan_results = FALSE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type); + if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV || + (addr_type == RESOLVABLE_PRIVATE_ADDR || + addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) { + return; + } + + switch(adv_type) { + case ADV_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + break; + case ADV_DIRECT_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED; + break; + case ADV_SCAN_IND: + case SCAN_RSP: + type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED; + isScanResponse = true; + break; + case ADV_NONCONN_IND: + type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED; + break; + default: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + } + + PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n", + *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + if(!_connecting) { + processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data); + } + PRINTF("!!!After processAdvertisementReport\n\r"); + } + break; + + case DISCOVERY_COMPLETE: + // The discovery is complete. If this is due to a stop scanning (i.e., the device + // we are interested in has been found) and a connection has been requested + // then we start the device connection. + PRINTF("DISCOVERY_COMPLETE\n\r"); + _scanning = false; + + // Since the DISCOVERY_COMPLETE event can be received during the scanning interval, + // we need to delay the starting of connection + uint16_t delay = (_scanningParams.getInterval()*0.625); + +#ifdef AST_FOR_MBED_OS + if(_connecting) { + minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay)); + } +#else + Clock_Wait(delay); + if(_connecting) { + makeConnection(); + } +#endif /* AST_FOR_MBED_OS */ + + break; + } +} + +ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) +{ + + tBleStatus ret = BLE_STATUS_SUCCESS; + + // Stop ADV before scanning + /* + if (state.advertising == 1) { + stopAdvertising(); + } + */ + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * White List is empty + * => scan operation = FAILURE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + uint8_t whiteListSize = whitelistAddresses.size; + if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + ret = btleStartRadioScan(scanningParams.getActiveScanning(), + scanningParams.getInterval(), + scanningParams.getWindow(), + addr_type); + + PRINTF("Scanning...\n\r"); + PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000); + PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000); + //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval()); + //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1); + //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2); + if (BLE_STATUS_SUCCESS == ret){ + PRINTF("Observation Procedure Started\n"); + _scanning = true; + + if(scanningParams.getTimeout() != 0) { + PRINTF("!!! attaching scan to!!!\n"); + scanTimeout.attach(scanTimeoutCB, scanningParams.getTimeout()); + } + + return BLE_ERROR_NONE; + } + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + switch (ret) { + case BLE_STATUS_INVALID_CID: + PRINTF("Observation Procedure not implemented!!!\n\r"); + return BLE_ERROR_NOT_IMPLEMENTED; + default: + PRINTF("Observation Procedure failed (0x%02X)\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } + +} + +ble_error_t BlueNRGGap::stopScan() { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(_scanning) { + ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC); + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Discovery Procedure Terminated\n"); + return BLE_ERROR_NONE; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief set Tx power level + @param[in] txPower Transmission Power level + @returns ble_error_t +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setTxPower(int8_t txPower) +{ + tBleStatus ret; + + int8_t enHighPower = 0; + int8_t paLevel = 0; + + ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + ret = aci_hal_set_tx_power_level(enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief get permitted Tx power values + @param[in] values pointer to pointer to permitted power values + @param[in] num number of values +*/ +/**************************************************************************/ +void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { + static const int8_t permittedTxValues[] = { + -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8 + }; + + *valueArrayPP = permittedTxValues; + *countP = sizeof(permittedTxValues) / sizeof(int8_t); +} + +/**************************************************************************/ +/*! + @brief Set advertising parameters according to the current state + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setAdvParameters(void) +{ + uint32_t advIntMS; + + if(state.connected == 1) { + advIntMS = (conn_min_interval*1.25)-GUARD_INT; + advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS); + + PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval); + } else { + advInterval = _advParams.getIntervalInADVUnits(); + } +} + +/**************************************************************************/ +/*! + @brief Set connection parameters according to the current state (ADV and/or SCAN) + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionParameters(void) +{ + if (state.connected == 1) { + + PRINTF("state.connected=1\r\n"); + scanInterval = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(conn_min_interval*1.25); + scanWindow = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(((conn_min_interval*1.25)/100)*60); // scanWin ~= 60%(scanInt) + + } else if (state.advertising == 1) { + + if (_scanningParams.getInterval() < advInterval) { + PRINTF("state.adv=1 scanInterval<advInterval\r\n"); + scanInterval = advInterval; + scanWindow = advInterval; + } else { + PRINTF("state.adv=1 scanInterval>=advInterval\r\n"); + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + } + + if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms + conn_min_interval = MAX_INT_CONN; + conn_max_interval = MAX_INT_CONN; + } else { + conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + } + + } else { + + PRINTF("state.adv = 0\r\n"); + + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) || + SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms + conn_min_interval = DEF_INT_CONN; + conn_max_interval = DEF_INT_CONN; + } else { + conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + } + } + PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval)); + PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow)); + PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25)); + PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25)); + +} + +ble_error_t BlueNRGGap::createConnection () +{ + tBleStatus ret; + + /* + Before creating connection, set parameters according + to previous or current procedure (ADV and/or SCAN) + */ + setConnectionParameters(); + + /* + Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, + Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max + */ + ret = aci_gap_create_connection(scanInterval, + scanWindow, + _peerAddrType, + (unsigned char*)_peerAddr, + addr_type, + conn_min_interval, conn_max_interval, 0, + SUPERV_TIMEOUT, CONN_L1, CONN_L1); + + //_connecting = false; + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Connection started.\n"); + _connecting = false; + return BLE_ERROR_NONE; + } +} + +ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) +{ + /* avoid compiler warnings about unused variables */ + (void)connectionParams; + + setScanParams(scanParams->getInterval(), + scanParams->getWindow(), + scanParams->getTimeout(), + scanParams->getActiveScanning() + ); + + // Save the peer address + for(int i=0; i<BDADDR_SIZE; i++) { + _peerAddr[i] = peerAddr[i]; + } + _peerAddrType = peerAddrType; + + _connecting = true; + + if(_scanning) { + stopScan(); + } else { + PRINTF("Calling createConnection from connect()\n\r"); + return createConnection(); + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the advertising policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode) +{ + advertisingPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the scanning policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode) +{ + scanningPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Get the current advertising policy filter mode. + + @returns The advertising policy filter mode. +*/ +/**************************************************************************/ +Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const +{ + return advertisingPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Get the current scanning policy filter mode. + + @returns The scanning policy filter mode. + +*/ +/**************************************************************************/ +Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const +{ + return scanningPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGap's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::reset(void) +{ + PRINTF("BlueNRGGap::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (Gap::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + AdvToFlag = false; + ScanToFlag = false; + + /* Clear derived class members */ + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + return BLE_ERROR_NONE; +} + +void BlueNRGGap::setConnectionInterval(uint16_t interval) { + conn_min_interval = interval; + conn_max_interval = interval; +} + +Gap::Role_t BlueNRGGap::getGapRole(void) +{ + return (gapRole); +} + +void BlueNRGGap::setGapRole(Gap::Role_t role) +{ + gapRole = role; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,403 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTClient + * @brief BlueNRG BLE_API GattClient Adaptation + * @{ + */ + +#include "BlueNRGGattClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +#include <new> +#include <assert.h> + +ble_error_t BlueNRGGattClient::createGattConnectionClient(Gap::Handle_t connectionHandle) +{ + if(MAX_ACTIVE_CONNECTIONS <= _numConnections) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + for(uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + + if(_connectionPool[i] == NULL) { + BlueNRGGattConnectionClient *gattConnectionClient = new(std::nothrow) BlueNRGGattConnectionClient(this, connectionHandle); + + if (gattConnectionClient == NULL) { + return BLE_ERROR_NO_MEM; + } + + _connectionPool[i] = gattConnectionClient; + _connectionPool[i]->onServiceDiscoveryTermination(terminationCallback); + _numConnections++; + + PRINTF("createGattConnectionClient: _connectionPool index=%d\r\n", i); + PRINTF("createGattConnectionClient: succesfully added new gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + break; + } + } + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattClient::removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason) +{ + + PRINTF("removeGattConnectionClient: connectionHandle=%d reason=0x%x\r\n", connectionHandle, reason); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("removeGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("removeGattConnectionClient: Found gattConnectionClient\r\n"); + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + PRINTF("removeGattConnectionClient: succesfully removed gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + + break; + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + + return BLE_ERROR_NONE; +} + +BlueNRGGattConnectionClient * BlueNRGGattClient::getGattConnectionClient(Gap::Handle_t connectionHandle) { + PRINTF("getGattConnectionClient\r\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("getGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("getGattConnectionClient: Found gattConnectionClient\r\n"); + return _connectionPool[i]; + } + } + + return NULL; +} + +void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code) { + + if(error_code != BLE_STATUS_SUCCESS) { + return; + } + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->gattProcedureCompleteCB(error_code); +} + +void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServicesCB(event_data_length, + attribute_data_length, + attribute_data_list); +} + +void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServiceCB(event_data_length, + handles_info_list); +} + +ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->findServiceChars(); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharsCB(event_data_length, + handle_value_pair_length, + handle_value_pair); +} + +void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharByUUIDCB(event_data_length, + attr_handle, + attr_value); +} + +void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->discAllCharacDescCB(event_data_length, + format, + handle_uuid_pair); +} + +void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charReadCB(event_data_length, + attribute_value); +} + +void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWritePrepareCB(event_data_length, + attribute_handle, + offset, + part_attr_value); +} + +void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWriteExecCB(event_data_length); +} + +ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattClient launchServiceDiscovery\n\r"); + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->launchServiceDiscovery(sc, cc, matchingServiceUUID, matchingCharacteristicUUIDIn); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, matchingServiceUUID); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, startHandle, endHandle); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +bool BlueNRGGattClient::isServiceDiscoveryActive(void) const +{ + bool isSDActive = false; + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + isSDActive |= _connectionPool[i]->isServiceDiscoveryActive(); + } + } + + return isSDActive; +} + +void BlueNRGGattClient::terminateServiceDiscovery(void) +{ + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + _connectionPool[i]->terminateServiceDiscovery(); + } + } +} + +void BlueNRGGattClient::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; ++i) { + if (_connectionPool[i]) { + _connectionPool[i]->onServiceDiscoveryTermination(callback); + } + } +} + +ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->read(attributeHandle, offset); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->write(cmd, attributeHandle, length, value); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(characteristic.getConnectionHandle()); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverCharacteristicDescriptors(characteristic, discoveryCallback, terminationCallback); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattClient's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattClient::reset(void) +{ + PRINTF("BlueNRGGattClient::reset\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if(_connectionPool[i] != NULL) { + _connectionPool[i]->reset(); + + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + } + } + + return BLE_ERROR_NONE; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,816 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGattConnectionClient + * @brief BlueNRG GattConnectionClient Adaptation + * @{ + */ + +#include "BlueNRGGattConnectionClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" +#include "ble_debug.h" + +// #define PRINTF printf + +static uint8_t props_mask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 + }; + +void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code) +{ + if(error_code != BLE_STATUS_SUCCESS) { + _currentState = GATT_IDLE; + return; + } + + // Service Discovery complete +/* + if(_currentState != GATT_IDLE && + _currentState != GATT_DISCOVERY_TERMINATED && + _currentState != GATT_WRITE_CHAR && + _currentState != GATT_READ_CHAR) { +*/ + if(_currentState == GATT_SERVICE_DISCOVERY) { + findServiceChars(); + return; + } + + if(_currentState == GATT_CHAR_DESC_DISCOVERY) { + _currentState = GATT_IDLE; + if(charDescTerminationCallback != NULL) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { + _characteristic, + BLE_ERROR_NONE + }; + charDescTerminationCallback(¶ms); + } + return; + } + + // Read complete + if(_currentState == GATT_READ_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processReadResponse(&readCBParams); + free((void*)(readCBParams.data)); + readCBParams.data = NULL; + return; + } + + // Write complete + if(_currentState == GATT_WRITE_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); + return; + } +} + +void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numAttr; + + numAttr = (event_data_length - 1) / attribute_data_length; + + offset = 0; + for (i=0; i<numAttr; i++) { + startHandle = attribute_data_list[offset]; + endHandle = attribute_data_list[offset+2]; + + // UUID Type + if (attribute_data_length == 6) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4]; + PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(attribute_data_list+offset+4, UUID::LSB); + +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + + } + + PRINTF("Setup serviceIndex = %d\n\r", _numServices); + discoveredService[_numServices].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += attribute_data_length; + } + + PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr); + +} + +void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numHandlePairs; + + numHandlePairs = (event_data_length - 1) / 2; + + offset = 0; + for (i=0; i<numHandlePairs; i++) { + startHandle = handles_info_list[offset]; + endHandle = handles_info_list[offset+2]; + + PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle); + + + if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle); + uuid = _matchingServiceUUID.getShortUUID(); + } else { +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02x", longUUIDBytes[i]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB); + } + + discoveredService[i].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += 4; + } +} + +void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) +{ + // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + uint8_t i, numChar, offset; + + numChar = (event_data_length - 1) / handle_value_pair_length; + + PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar); + + offset = 0; + for (i=0; i<numChar; i++) { + // UUID Type + if (handle_value_pair_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(handle_value_pair+offset+5, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & handle_value_pair[offset+2]); + p._read = (props_mask[1] & handle_value_pair[offset+2])>>1; + p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2; + p._write = (props_mask[3] & handle_value_pair[offset+2])>>3; + p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4; + p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5; + p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = handle_value_pair[offset+2]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = handle_value_pair[offset]; + valueHandle = handle_value_pair[offset+3]; + lastHandle = valueHandle+1; + PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle); + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; + + offset += handle_value_pair_length; + } +} + +void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) +{ + // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + + PRINTF("serviceCharByUUIDCB\n\r"); + + // UUID Type + if (event_data_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = attr_value[4]<<8|attr_value[3]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(attr_value+3, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & attr_value[0]); + p._read = (props_mask[1] & attr_value[0])>>1; + p._writeWoResp = (props_mask[2] & attr_value[0])>>2; + p._write = (props_mask[3] & attr_value[0])>>3; + p._notify = (props_mask[4] & attr_value[0])>>4; + p._indicate = (props_mask[5] & attr_value[0])>>5; + p._authSignedWrite = (props_mask[6] & attr_value[0])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = attr_value[0]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = attr_handle; + valueHandle = attr_value[1]; + lastHandle = valueHandle+1; + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + // update the last handle and call the characteristic discovery callback for previous char + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; +} + +ble_error_t BlueNRGGattConnectionClient::findServiceChars(void) +{ + PRINTF("findServiceChars\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + + DiscoveredService *service; + + // complete the discovery of the last characteristic of the previous service. + // Its last handle wasn't known before this point + // update the handle and call the characteristic discovery callback. + if (_servIndex != 0 && _numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle()); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars = 0; + + // We finished chars discovery for all services + if(_servIndex >= _numServices) { + PRINTF("!!!We finished chars discovery for all services!!!\n\r"); + //_currentState = GATT_CHARS_DISCOVERY_COMPLETE; + + terminateServiceDiscovery(); + + return BLE_ERROR_NONE; + } + + service = &discoveredService[_servIndex]; + /* + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID()); + } else { + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); + } + */ + + if(serviceDiscoveryCallback) { + serviceDiscoveryCallback(service); + } + + PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex); + //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle()); + + if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) { + PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r"); + ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle()); + } else { + + uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID()); + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; +#ifdef DEBUG + PRINTF("findServiceChars C UUID-"); + for(unsigned i = 0; i < 2; i++) { + PRINTF("%02X", short_uuid[i]); + } + PRINTF("\n\r"); +#endif + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID(); +#ifdef DEBUG + PRINTF("(findServiceChars) C UUID-"); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", uuid[i]); + } + PRINTF("\r\n"); +#endif + } + + ret = aci_gatt_disc_charac_by_uuid(_connectionHandle, + service->getStartHandle(), + service->getEndHandle(), + uuid_type, + uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _servIndex++; + } + + PRINTF("findServiceChars ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + unsigned j; + + if(isServiceDiscoveryActive()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if(!sc && !cc) { + // nothing to do + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r"); + return BLE_ERROR_NONE; + } + + serviceDiscoveryCallback = sc; + characteristicDiscoveryCallback = cc; + _matchingServiceUUID = matchingServiceUUID; + _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn; + + //reset services + _numServices = 0; + _numChars = 0; + _servIndex = 0; + for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) { + discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE); + } + + if(matchingServiceUUID == BLE_UUID_UNKNOWN) { + + // Wildcard: search for all services + PRINTF("Wildcard: search for all services\r\n"); + ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle); + + } else { + PRINTF("search for specific services\r\n"); + + uint8_t type = matchingServiceUUID.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID()); +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x"); + for(j = 0; j < 2; j++) { + PRINTF("%02X", short_uuid[j]); + } + PRINTF("\n\r"); +#endif + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; + + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)matchingServiceUUID.getBaseUUID(); + +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x"); + for(j = 0; j < 16; j++) { + PRINTF("%02X", uuid[j]); + } + PRINTF("\n\r"); +#endif + } + + // search for specific service by UUID + ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_SERVICE_DISCOVERY; + } + + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)matchingServiceUUID; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)startHandle; + (void)endHandle; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const +{ + if(_currentState == GATT_SERVICE_DISCOVERY) { + return true; + } + + return false; +} + +void BlueNRGGattConnectionClient::terminateServiceDiscovery(void) +{ + _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED; + + if (terminationCallback) { + terminationCallback(_connectionHandle); + } +} + +void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value) +{ + // copy the data read, they will be forwarded to the user once the procedure + // has completed + readCBParams.connHandle = _connectionHandle; + readCBParams.offset = 0; + readCBParams.len = event_data_length; + readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length)); + memcpy((void*)(readCBParams.data), attribute_value, event_data_length); +} + +ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + /* avoid compiler warnings about unused variables */ + (void)offset; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // Save the attribute_handle not provided by evt_att_read_resp + gattc->readCBParams.handle = attributeHandle; + + ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle); + + if(ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_READ_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } +} + +void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) +{ + // Update the write response params + writeCBParams.handle = attribute_handle; + writeCBParams.offset = offset; + writeCBParams.len = event_data_length-4; //(?) + writeCBParams.data = part_attr_value; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length) +{ + /* avoid compiler warnings about unused variables */ + (void)event_data_length; + + writeCBParams.connHandle = _connectionHandle; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + /* avoid compiler warnings about unused variables */ + (void)cmd; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // We save the write response params (used by the callback) because + // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE + gattc->writeCBParams.connHandle = _connectionHandle; + gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD; + gattc->writeCBParams.handle = attributeHandle; + gattc->writeCBParams.offset = 0; + gattc->writeCBParams.len = length; + gattc->writeCBParams.data = value; + + ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); + + if (ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_WRITE_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } + +} + +void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + GattAttribute::Handle_t attHandle; + UUID uuid; + uint8_t i, numCharacDesc, offset, handle_uuid_length; + + handle_uuid_length = 4; //Handle + UUID_16 + if (format == 2) + handle_uuid_length = 18; //Handle + UUID_128 + + numCharacDesc = (event_data_length - 1) / handle_uuid_length; + + offset = 0; + + PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n", + event_data_length, format); + + + for (i=0; i<numCharacDesc; i++) { + memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle)); + + // UUID Type + if (handle_uuid_length == 4) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2]; + PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB); +#ifdef DEBUG + PRINTF("D UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + } + + if(charDescDiscoveryCallback != NULL) { + CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { + _characteristic, + DiscoveredCharacteristicDescriptor( + _characteristic.getGattClient(), + _connectionHandle, + attHandle, + uuid + ) + }; + charDescDiscoveryCallback(¶ms); + } + + _numCharDesc++; + + offset += handle_uuid_length; + } +} + +ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { + + tBleStatus ret; + + if(_currentState != GATT_IDLE) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + charDescDiscoveryCallback = discoveryCallback; + charDescTerminationCallback = terminationCallback; + + GattAttribute::Handle_t valueHandle = characteristic.getValueHandle(); + GattAttribute::Handle_t lastHandle = characteristic.getLastHandle(); + + PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle); + ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle); + + if (ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_CHAR_DESC_DISCOVERY; + _characteristic = characteristic; + return BLE_ERROR_NONE; + } + switch (ret) { + case BLE_STATUS_INVALID_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattConnectionClient::reset(void) { + PRINTF("BlueNRGGattConnectionClient::reset\n"); + + /* Clear all state, including private members */ + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + _numServices = 0; + _servIndex = 0; + _numChars = 0; + _numCharDesc = 0; + + /* Clear class members */ + memset(discoveredService, 0, sizeof(discoveredService)); + memset(discoveredChar, 0, sizeof(discoveredChar)); + + // free response if allocated + if(readCBParams.data) { + free((void*)(readCBParams.data)); + } + + return BLE_ERROR_NONE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,755 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTSERVER + * @brief BlueNRG BLE_API GattServer Adaptation + * @{ + */ + +#include "BlueNRGGattServer.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/**************************************************************************/ +/*! + @brief Adds a new service to the GATT table on the peripheral + + @params[in] service + Pointer to instance of the Gatt Server to add + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::addService(GattService &service) +{ + /* ToDo: Make sure we don't overflow the array, etc. */ + /* ToDo: Make sure this service UUID doesn't already exist (?) */ + /* ToDo: Basic validation */ + + tBleStatus ret; + uint8_t type; + uint16_t short_uuid; + uint8_t primary_short_uuid[2]; + uint8_t primary_base_uuid[16]; + uint8_t char_base_uuid[16]; + const uint8_t *base_uuid; + const uint8_t *base_char_uuid; + + uint8_t charsCount = service.getCharacteristicCount(); + const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount; + + // check that there is enough characteristics left in the + // characteristic array. + if (charsCount > available_characteristics) { + PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics); + return BLE_ERROR_NO_MEM; + } + + const uint16_t maxAttrRecords = computeAttributesRecord(service); + + type = (service.getUUID()).shortOrLong(); + PRINTF("AddService(): Type:%d\n\r", type); + + /* Add the service to the BlueNRG */ + short_uuid = (service.getUUID()).getShortUUID(); + STORE_LE_16(primary_short_uuid, short_uuid); + + if(type==UUID::UUID_TYPE_LONG) { + base_uuid = (service.getUUID()).getBaseUUID(); + + COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]); + } + + ret = BLE_STATUS_SUCCESS; + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_serv(UUID_TYPE_16, + primary_short_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_serv(UUID_TYPE_128, + primary_base_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_OUT_OF_HANDLE: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case ERR_UNSPECIFIED_ERROR: + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_ERROR: + default: + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + + + service.setHandle(servHandle); + //serviceHandleVector.push_back(servHandle); + PRINTF("added servHandle handle =%u\n\r", servHandle); + uint16_t bleCharacteristic; + + //iterate to include all characteristics + for (uint8_t i = 0; i < charsCount; i++) { + GattCharacteristic *p_char = service.getCharacteristic(i); + uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); + + uint8_t int_8_uuid[2]; + STORE_LE_16(int_8_uuid, char_uuid); + + type = (p_char->getValueAttribute().getUUID()).shortOrLong(); + + if(type==UUID::UUID_TYPE_LONG) { + base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); +#ifdef DEBUG + for(uint8_t j=0; j<16; j++) { + PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]); + } + PRINTF("\n\r"); +#endif + COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]); + } + + PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); + /* + * Gatt_Evt_Mask -> HardCoded (0) + * Encryption_Key_Size -> Hardcoded (16) + * isVariable (variable length value field) -> Hardcoded (1) + */ + uint8_t Gatt_Evt_Mask = 0x0; + + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP; + } + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; + } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_16, + int_8_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_128, + char_base_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + case BLE_STATUS_CHARAC_ALREADY_EXISTS: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); + + p_characteristics[characteristicCount++] = p_char; + /* Set the characteristic value handle */ + p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE); + PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle()); + + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + ble_error_t err = write(p_char->getValueAttribute().getHandle(), + p_char->getValueAttribute().getValuePtr(), + p_char->getValueAttribute().getLength(), false /* localOnly */); + if (err) { + PRINTF("ERROR HERE !!!!\r\n"); + return err; + } + } + + // add descriptors now + uint16_t descHandle = 0; + PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); + + for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { + GattAttribute *descriptor = p_char->getDescriptor(descIndex); + uint8_t desc_uuid[16] = { 0 }; + + + uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT; + STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID()); + + if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) { + desc_uuid_type = CHAR_DESC_TYPE_128_BIT; + const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID(); + + COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]); + } + + ret = aci_gatt_add_char_desc(service.getHandle(), + bleCharacteristic, + desc_uuid_type, + desc_uuid, + descriptor->getMaxLength(), + descriptor->getLength(), + descriptor->getValuePtr(), + CHAR_DESC_SECURITY_PERMISSION, + CHAR_DESC_ACCESS_PERMISSION, + GATT_NOTIFY_ATTRIBUTE_WRITE, + MIN_ENCRY_KEY_SIZE, + CHAR_ATTRIBUTE_LEN_IS_FIXED, + &descHandle); + PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); + + switch (ret) { + case BLE_STATUS_SUCCESS: + PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); + descriptor->setHandle(descHandle); + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_INVALID_OPERATION: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + } + + serviceCount++; + + //FIXME: There is no GattService pointer array in GattServer. + // There should be one? (Only the user is aware of GattServices!) Report to forum. + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on char handle + + @param[in] attributeHandle + The handle of the GattCharacteristic to read from + @param[in] buffer + Buffer to hold the the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes read into the buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) +{ + tBleStatus ret; + uint16_t charHandle = attributeHandle; + + ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer); + + if(ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on the connection + and char handle + + @param[in] connectionHandle + The handle of the connection + @param[in] attributeHandle + The handle of the GattCharacteristic to write to + @param[in] buffer + Data to use when updating the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes in buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + uint8_t buffer[], + uint16_t *lengthP) { + + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)attributeHandle; + (void)buffer; + (void)lengthP; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t, + const uint8_t[], + uint16_t, bool localOnly) { + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)localOnly; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly) +{ + /* avoid compiler warnings about unused variables */ + (void)localOnly; + + // check that the len of the data to write are compatible with the characteristic + GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle); + if (!characteristic) { + PRINTF("characteristic not found\r\n"); + return BLE_ERROR_INVALID_PARAM; + } + + // if the attribute handle is the attribute handle of the characteristic value then + // write the value + if (attributeHandle == characteristic->getValueHandle()) { + // assert the len in input is correct for this characteristic + const GattAttribute& value_attribute = characteristic->getValueAttribute(); + + // reject write if the lenght exceed the maximum lenght of this attribute + if (value_attribute.getMaxLength() < len) { + PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + // reject write if the attribute size is fixed and the lenght in input is different than the + // length of the attribute. + if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) { + PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + tBleStatus ret; + + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + + PRINTF("updating bleCharacteristic valueHandle=%u,\ + corresponding serviceHandle=%u len=%d\n\r", + attributeHandle, bleCharHandleMap.find(charHandle)->second, len); + + /* + * If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. + */ + ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } else { + // write this handle has a descriptor handle + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + uint16_t service_handle = bleCharHandleMap.find(charHandle)->second; + + tBleStatus ret = aci_gatt_set_desc_value( + service_handle, + charHandle, + attributeHandle, + 0, + len, + buffer + ); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } +} + +/**************************************************************************/ +/*! + @brief Reads a value according to the handle provided + + @param[in] attributeHandle + The handle of the attribute to read from + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle) +{ + uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); + + GattReadCallbackParams readParams; + readParams.handle = attributeHandle; + + //PRINTF("readParams.handle = %d\n\r", readParams.handle); + HCIDataReadEvent(&readParams); + + //EXIT: + if(gapConnectionHandle != 0){ + //PRINTF("Calling aci_gatt_allow_read\n\r"); + aci_gatt_allow_read(gapConnectionHandle); + } + + return BLE_ERROR_NONE; +} + +// ask if the write request should be accepted of rejected +// return 0 in case of success or an ATT error response in +// case of faillure +uint8_t BlueNRGGattServer::Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length, + const uint8_t* data) { + + GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle); + if(!characteristic) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF; + } + + // check if the data length is in range + if (characteristic->getValueAttribute().getMaxLength() < data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + // if the length of the characteristic value is fixed + // then the data in input should be of that length + if (characteristic->getValueAttribute().hasVariableLength() == false && + characteristic->getValueAttribute().getMaxLength() != data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + GattWriteAuthCallbackParams params = { + connection_handle, + attr_handle, + /* offset */ 0, + data_length, + data, + /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED + }; + + return characteristic->authorizeWrite(¶ms) & 0xFF; +} + +/**************************************************************************/ +/*! + @brief Returns the GattCharacteristic according to the handle provided + + @param[in] attrHandle + The handle of the attribute + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) +{ + GattCharacteristic *p_char = NULL; + int i; + uint16_t handle, handle_1; + + PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle); + for(i=0; i<characteristicCount; i++) + { + handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + PRINTF("handle(%d)=%d\n\r", i, handle); + if(i==characteristicCount-1)//Last Characteristic check + { + if(attrHandle>=handle) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); + break; + } + } + else { + handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + //Testing if attribute handle is between two Characteristic Handles + if(attrHandle>=handle && attrHandle<handle_1) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); + break; + } else continue; + } + } + + return p_char; +} + +void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { + this->handleDataWrittenEvent(params); +} + +void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { + PRINTF("Called HCIDataReadEvent\n\r"); + this->handleDataReadEvent(params); +} + +void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { + this->handleEvent(type, charHandle); +} + +void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { + this->handleDataSentEvent(count); +} + + +ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { + // <TODO> + return (ble_error_t)0; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::reset(void) +{ + PRINTF("BlueNRGGattServer::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (GattServer::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + /* Clear class members */ + memset(p_characteristics, 0, sizeof(p_characteristics)); + memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles)); + serviceCount = 0; + characteristicCount = 0; + + return BLE_ERROR_NONE; +} + + +/// compute the number of attributes needed by this service. +uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) { + uint16_t attribute_records = 1; + + for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) { + // add two attributes, one for the characteristic declaration + // and the other for the characteristic value. + attribute_records += 2; + + const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index); + const uint8_t properties = characteristic->getProperties(); + // if notify or indicate are present, two attributes are + // needed + if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) || + (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { + attribute_records += 2; + } + + // if broadcast is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) { + attribute_records += 2; + } + + // if extended properties flag is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) { + attribute_records += 2; + } + + attribute_records += characteristic->getDescriptorCount(); + } + + // for some reason, if there is just a service, this value should + // be equal to 5 + if (attribute_records == 1) { + attribute_records = 5; + } + + return attribute_records; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,421 @@ +/** + ****************************************************************************** + * @file ble_hci.c + * @author AMS/HESA Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "ble_gp_timer.h" +#include "ble_debug.h" + +#include "stm32_bluenrg_ble.h" + +#if BLE_CONFIG_DBG_ENABLE +#undef PRINTF +#endif + +#define HCI_LOG_ON 0 + +#define HCI_READ_PACKET_NUM_MAX (0x40) + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tListNode hciReadPktPool; +tListNode hciReadPktRxQueue; + +// betzw - DEBUG: +//#define POOL_CNT +#ifdef POOL_CNT +#include <stdio.h> +static unsigned int nr_hciReadPktPool; +static unsigned int lowest_nr_hciReadPktPool; +#endif // POOL_CNT + +/* pool of hci read packets */ +static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; + +static volatile uint8_t hci_timer_id; +static volatile uint8_t hci_timeout; + +void hci_timeout_callback(void) +{ + hci_timeout = 1; + return; +} + +void HCI_Init(void) +{ + uint8_t index; + +#ifdef POOL_CNT + nr_hciReadPktPool = 0; +#endif // POOL_CNT + + /* Initialize list heads of ready and free hci data packet queues */ + list_init_head (&hciReadPktPool); + list_init_head (&hciReadPktRxQueue); + + /* Initialize the queue of free hci data packets */ + for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) + { + list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif // POOL_CNT + } + +#ifdef POOL_CNT + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif // POOL_CNT +} + +#define HCI_PCK_TYPE_OFFSET 0 +#define EVENT_PARAMETER_TOT_LEN_OFFSET 2 + +/** + * Verify if HCI packet is correctly formatted. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * @return 0 if HCI packet is as expected + */ +int HCI_verify(const tHciDataPacket * hciReadPacket) +{ + const uint8_t *hci_pckt = hciReadPacket->dataBuff; + + if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) + return 1; /* Incorrect type. */ + + if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) + return 2; /* Wrong length (packet truncated or too long). */ + + return 0; +} + +void HCI_Process(void) +{ + tHciDataPacket * hciReadPacket = NULL; + +#ifdef POOL_CNT + printf("betzw(%s, %d): nr_hciReadPktPool = %u (lowest = %u)\r\n", __func__, __LINE__, + nr_hciReadPktPool, lowest_nr_hciReadPktPool); +#endif // POOL_CNT + + Disable_SPI_IRQ(); + uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); + /* process any pending events read */ + while(list_empty == FALSE) + { + list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + Enable_SPI_IRQ(); + HCI_Event_CB(hciReadPacket->dataBuff); + Disable_SPI_IRQ(); + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + list_empty = list_is_empty(&hciReadPktRxQueue); + } + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG. */ + HCI_HandleSPI(); + Enable_SPI_IRQ(); +} + +BOOL HCI_Queue_Empty(void) +{ + return list_is_empty(&hciReadPktRxQueue); +} + +/** + * When an interrupt is raised by BlueNRG, + * just signal that a new event (availability of SPI data to be read) + * needs to be processed. + */ +void HCI_Isr(void) +{ + signalEventsToProcess(); +} + +/** + * Now, SPI Data are handled in user space. + * In case it has to be called in ISR, take care to + * call Disable_SPI_IRQ/Enable_SPI_IRQ in a proper way. + * The calls Disable_SPI_IRQ/Enable_SPI_IRQ have not been removed + * from this code for backward compatibility. + */ +void HCI_HandleSPI(void) +{ + tHciDataPacket * hciReadPacket = NULL; + uint8_t data_len; + + Clear_SPI_EXTI_Flag(); + while(BlueNRG_DataPresent()){ + if (list_is_empty (&hciReadPktPool) == FALSE){ + + /* enqueueing a packet for read */ + list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool--; + if(nr_hciReadPktPool < lowest_nr_hciReadPktPool) + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif + + data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); + if(data_len > 0){ + hciReadPacket->data_len = data_len; + if(HCI_verify(hciReadPacket) == 0) { + list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); + } else { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else { + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else{ + // HCI Read Packet Pool is empty, wait for a free packet. + Clear_SPI_EXTI_Flag(); + return; + } + + Clear_SPI_EXTI_Flag(); + } +} + +void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){ +#if HCI_LOG_ON + PRINTF("HCI <- "); + for(int i=0; i < n_bytes1; i++) + PRINTF("%02X ", *((uint8_t*)data1 + i)); + for(int i=0; i < n_bytes2; i++) + PRINTF("%02X ", *((uint8_t*)data2 + i)); + PRINTF("\n"); +#endif + + Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); +} + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) +{ + hci_command_hdr hc; + + hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); + hc.plen= plen; + + uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; + header[0] = HCI_COMMAND_PKT; + Osal_MemCpy(header+1, &hc, sizeof(hc)); + + hci_write(header, param, sizeof(header), plen); +} + +static void move_list(tListNode * dest_list, tListNode * src_list) +{ + pListNode tmp_node; + + while(!list_is_empty(src_list)){ + list_remove_tail(src_list, &tmp_node); + list_insert_head(dest_list, tmp_node); + } +} + + /* It ensures that we have at least half of the free buffers in the pool. */ +static void free_event_list(void) +{ + tHciDataPacket * pckt; + + Disable_SPI_IRQ(); + + while(list_get_size(&hciReadPktPool) < HCI_READ_PACKET_NUM_MAX/2){ + list_remove_head(&hciReadPktRxQueue, (tListNode **)&pckt); + list_insert_tail(&hciReadPktPool, (tListNode *)pckt); + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG */ + HCI_HandleSPI(); + } + + Enable_SPI_IRQ(); +} + +int hci_send_req(struct hci_request *r, BOOL async) +{ + uint8_t *ptr; + uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + hci_event_pckt *event_pckt; + hci_uart_pckt *hci_hdr; + int to = DEFAULT_TIMEOUT; + struct timer t; + tHciDataPacket * hciReadPacket = NULL; + tListNode hciTempQueue; + + list_init_head(&hciTempQueue); + + free_event_list(); + + hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); + + if(async){ + return 0; + } + + /* Minimum timeout is 1. */ + if(to == 0) + to = 1; + + Timer_Set(&t, to); + + while(1) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + evt_le_meta_event *me; + int len; + + while(1){ + + Disable_SPI_IRQ(); + HCI_HandleSPI(); + Enable_SPI_IRQ(); + + if(Timer_Expired(&t)){ + goto failed; + } + if(!HCI_Queue_Empty()){ + break; + } + } + + /* Extract packet from HCI event queue. */ + Disable_SPI_IRQ(); + list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + + hci_hdr = (void *)hciReadPacket->dataBuff; + + if(hci_hdr->type == HCI_EVENT_PKT){ + + event_pckt = (void *) (hci_hdr->data); + + ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); + len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); + + switch (event_pckt->evt) { + + case EVT_CMD_STATUS: + cs = (void *) ptr; + + if (cs->opcode != opcode) + goto failed; + + if (r->event != EVT_CMD_STATUS) { + if (cs->status) { + goto failed; + } + break; + } + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_CMD_COMPLETE: + cc = (void *) ptr; + + if (cc->opcode != opcode) + goto failed; + + ptr += EVT_CMD_COMPLETE_SIZE; + len -= EVT_CMD_COMPLETE_SIZE; + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_LE_META_EVENT: + me = (void *) ptr; + + if (me->subevent != r->event) + break; + + len -= 1; + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, me->data, r->rlen); + goto done; + + case EVT_HARDWARE_ERROR: + goto failed; + + default: + break; + } + } + + /* If there are no more packets to be processed, be sure there is at list one + packet in the pool to process the expected event. + If no free packets are available, discard the processed event and insert it + into the pool. */ + if(list_is_empty(&hciReadPktPool) && list_is_empty(&hciReadPktRxQueue)){ + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); + hciReadPacket=NULL; + } + else { + /* Insert the packet in a different queue. These packets will be + inserted back in the main queue just before exiting from send_req(), so that + these events can be processed by the application. + */ + list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); + hciReadPacket = NULL; + } + + HCI_HandleSPI(); + + Enable_SPI_IRQ(); + + } + +failed: + if(hciReadPacket != NULL) { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + move_list(&hciReadPktRxQueue, &hciTempQueue); + Enable_SPI_IRQ(); + return -1; + +done: + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + move_list(&hciReadPktRxQueue, &hciTempQueue); + + Enable_SPI_IRQ(); + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,837 @@ +/** + ****************************************************************************** + * @file ble_hci_le.c + * @author AMG RF Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +int hci_reset(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_RESET; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_disconnect(uint16_t handle, uint8_t reason) +{ + struct hci_request rq; + disconnect_cp cp; + uint8_t status; + + cp.handle = handle; + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) +{ + struct hci_request rq; + read_local_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + + *hci_version = resp.hci_version; + *hci_revision = btohs(resp.hci_revision); + *lmp_pal_version = resp.lmp_pal_version; + *manufacturer_name = btohs(resp.manufacturer_name); + *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); + + return 0; +} + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) +{ + struct hci_request rq; + le_read_buffer_size_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_BUFFER_SIZE; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *pkt_len = resp.pkt_len; + *max_pkt = resp.max_pkt; + + return 0; +} + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter) +{ + struct hci_request rq; + le_set_adv_parameters_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.min_interval = min_interval; + adv_cp.max_interval = max_interval; + adv_cp.advtype = advtype; + adv_cp.own_bdaddr_type = own_bdaddr_type; + adv_cp.direct_bdaddr_type = direct_bdaddr_type; + if(direct_bdaddr != NULL) + Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); + adv_cp.chan_map = chan_map; + adv_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_PARAMETERS; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_adv_data_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.length = length; + Osal_MemCpy(adv_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_DATA; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertise_enable(uint8_t enable) +{ + struct hci_request rq; + le_set_advertise_enable_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.enable = enable?1:0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter) +{ + struct hci_request rq; + le_set_scan_parameters_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.type = type; + scan_cp.interval = interval; + scan_cp.window = window; + scan_cp.own_bdaddr_type = own_bdaddr_type; + scan_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) +{ + struct hci_request rq; + le_set_scan_enable_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.enable = enable?1:0; + scan_cp.filter_dup = filter_dup; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_ENABLE; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_rand(uint8_t random_number[8]) +{ + struct hci_request rq; + le_rand_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_RAND; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + Osal_MemCpy(random_number, resp.random, 8); + + return 0; +} + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_scan_response_data_cp scan_resp_cp; + uint8_t status; + + Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); + scan_resp_cp.length = length; + Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; + rq.cparam = &scan_resp_cp; + rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) +{ + struct hci_request rq; + le_read_adv_channel_tx_power_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *tx_power_level = resp.level; + + return 0; +} + +int hci_le_set_random_address(tBDAddr bdaddr) +{ + struct hci_request rq; + le_set_random_address_cp set_rand_addr_cp; + uint8_t status; + + Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); + Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; + rq.cparam = &set_rand_addr_cp; + rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_read_bd_addr(tBDAddr bdaddr) +{ + struct hci_request rq; + read_bd_addr_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_BD_ADDR; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_BD_ADDR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); + + return 0; +} + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) +{ + struct hci_request rq; + le_create_connection_cp create_cp; + uint8_t status; + + Osal_MemSet(&create_cp, 0, sizeof(create_cp)); + create_cp.interval = interval; + create_cp.window = window; + create_cp.initiator_filter = initiator_filter; + create_cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); + create_cp.own_bdaddr_type = own_bdaddr_type; + create_cp.min_interval=min_interval; + create_cp.max_interval=max_interval; + create_cp.latency = latency; + create_cp.supervision_timeout=supervision_timeout; + create_cp.min_ce_length=min_ce_length; + create_cp.max_ce_length=max_ce_length; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN; + rq.cparam = &create_cp; + rq.clen = LE_CREATE_CONN_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_create_connection_cancel(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN_CANCEL; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) +{ + struct hci_request rq; + le_encrypt_cp params; + le_encrypt_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemCpy(params.key, key, 16); + Osal_MemCpy(params.plaintext, plaintextData, 16); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ENCRYPT; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + le_ltk_neg_reply_cp params; + le_ltk_neg_reply_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + params.handle = 1; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_LTK_NEG_REPLY; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CLEAR_WHITE_LIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0){ + return BLE_STATUS_TIMEOUT; + } + + return status; +} + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) +{ + struct hci_request rq; + le_add_device_to_white_list_cp params; + uint8_t status; + + params.bdaddr_type = bdaddr_type; + Osal_MemCpy(params.bdaddr, bdaddr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; + rq.cparam = ¶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/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1309 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB05A1 cp; + gap_init_rp resp; + + cp.role = role; + cp.privacy_enabled = privacy_enabled; + cp.device_name_char_len = device_name_char_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} +tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB04A1 cp; + gap_init_rp resp; + + cp.role = role; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + SlaveConnIntervMin = htobs(SlaveConnIntervMin); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + SlaveConnIntervMax = htobs(SlaveConnIntervMax); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB05A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.directed_adv_type = directed_adv_type; + cp.adv_interv_min = adv_interv_min; + cp.adv_interv_max = adv_interv_max; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB04A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_io_capability(uint8_t io_capability) +{ + struct hci_request rq; + uint8_t status; + gap_set_io_capability_cp cp; + + cp.io_capability = io_capability; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_IO_CAPABILITY; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode) +{ + struct hci_request rq; + gap_set_auth_requirement_cp cp; + uint8_t status; + + cp.mitm_mode = mitm_mode; + cp.oob_enable = oob_enable; + Osal_MemCpy(cp.oob_data, oob_data, 16); + cp.min_encryption_key_size = min_encryption_key_size; + cp.max_encryption_key_size = max_encryption_key_size; + cp.use_fixed_pin = use_fixed_pin; + cp.fixed_pin = htobl(fixed_pin); + cp.bonding_mode = bonding_mode; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) +{ + struct hci_request rq; + gap_set_author_requirement_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorization_enable = authorization_enable; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) +{ + struct hci_request rq; + gap_passkey_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.passkey = htobl(passkey); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_PASSKEY_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) +{ + struct hci_request rq; + gap_authorization_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorize = authorize; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB05A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + cp.own_address_type = own_address_type; + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB04A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) +{ + struct hci_request rq; + gap_set_undirected_connectable_cp cp; + uint8_t status; + + cp.own_addr_type = own_addr_type; + cp.adv_filter_policy = adv_filter_policy; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) +{ + struct hci_request rq; + gap_slave_security_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.bonding = bonding; + cp.mitm_protection = mitm_protection; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[32]; + uint8_t indx = 0; + + if (AdvLen > (sizeof(buffer)-1)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvLen; + indx++; + + Osal_MemCpy(buffer + indx, AdvData, AdvLen); + indx += AdvLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_UPDATE_ADV_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) +{ + struct hci_request rq; + gap_delete_ad_type_cp cp; + uint8_t status; + + cp.ad_type = ad_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_DELETE_AD_TYPE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required) +{ + struct hci_request rq; + gap_get_security_level_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; + rq.rparam = &resp; + rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *mitm_protection = resp.mitm_protection; + *bonding = resp.bonding; + *oob_data = resp.oob_data; + *passkey_required = resp.passkey_required; + + return resp.status; +} + +tBleStatus aci_gap_configure_whitelist(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) +{ + struct hci_request rq; + gap_terminate_cp cp; + uint8_t status; + + cp.handle = htobs(conn_handle); + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_clear_security_database(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) +{ + struct hci_request rq; + gap_allow_rebond_cp_IDB05A1 cp; + uint8_t status; + + cp.conn_handle = conn_handle; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_allow_rebond_IDB04A1(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_limited_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_general_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_name_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = use_reconn_addr; + indx++; + + Osal_MemCpy(buffer + indx, reconn_addr, 6); + indx += 6; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB05A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB04A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.use_reconn_addr = use_reconn_addr; + Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_start_selective_conn_establish_proc_cp cp; + uint8_t status; + + if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.num_whitelist_entries = num_whitelist_entries; + + Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_create_connection_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CREATE_CONNECTION; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; + rq.cparam = &procedure_code; + rq.clen = 1; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_connection_update_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) +{ + struct hci_request rq; + gap_send_pairing_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.force_rebond = force_rebond; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + gap_resolve_private_address_rp rp; + + Osal_MemCpy(cp.address, private_address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); + + return 0; +} +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + uint8_t status; + + Osal_MemCpy(cp.address, address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_set_broadcast_mode_cp cp; + uint8_t status; + uint8_t indx = 0; + uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; + + if (variable_size > sizeof(cp.var_len_data) ) + return BLE_STATUS_INVALID_PARAMS; + + cp.adv_interv_min = htobs(adv_interv_min); + cp.adv_interv_max = htobs(adv_interv_max); + cp.adv_type = adv_type; + cp.own_addr_type = own_addr_type; + + cp.var_len_data[indx] = adv_data_length; + indx++; + Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); + indx += adv_data_length; + cp.var_len_data[indx] = num_whitelist_entries; + indx ++; + Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_BROADCAST_MODE; + rq.cparam = &cp; + rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_observation_proc_cp cp; + uint8_t status; + + cp.scan_interval = scan_interval; + cp.scan_window = scan_window; + cp.scan_type = scan_type; + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_OBSERVATION_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) +{ + struct hci_request rq; + gap_is_device_bonded_cp cp; + uint8_t status; + + cp.peer_address_type = peer_address_type; + Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_IS_DEVICE_BONDED; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) +{ + struct hci_request rq; + gap_get_bonded_devices_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_BONDED_DEVICES; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (rp.status) { + return rp.status; + } + + *num_devices = rp.num_addr; + if(device_list != NULL) + Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1505 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.c +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : File with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_gatt_init(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INIT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[19]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, service_uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = service_type; + indx++; + + buffer[indx] = max_attr_records; + indx++; + + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle) +{ + struct hci_request rq; + gatt_include_serv_rp resp; + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + service_handle = htobs(service_handle); + Osal_MemCpy(buffer, &service_handle, 2); + indx += 2; + + included_start_handle = htobs(included_start_handle); + Osal_MemCpy(buffer+indx, &included_start_handle, 2); + indx += 2; + + included_end_handle = htobs(included_end_handle); + Osal_MemCpy(buffer+indx, &included_end_handle, 2); + indx += 2; + + if(included_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } else { + uuid_len = 16; + } + + buffer[indx] = included_uuid_type; + indx++; + + Osal_MemCpy(buffer + indx, included_uuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INCLUDE_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *included_handle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[25]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + buffer[indx] = charValueLen; + indx++; + + buffer[indx] = charProperties; + indx++; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *charHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle) +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = descValueMaxLen; + indx++; + + buffer[indx] = descValueLen; + indx++; + + if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + Osal_MemCpy(buffer + indx, descValue, descValueLen); + indx += descValueLen; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = accPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR_DESC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *descHandle = btohs(resp.handle); + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = charValOffset; + indx++; + + buffer[indx] = charValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charValue, charValueLen); + indx += charValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_char_cp cp; + + cp.service_handle = htobs(servHandle); + cp.char_handle = htobs(charHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_CHAR; + rq.cparam = &cp; + rq.clen = GATT_DEL_CHAR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_service(uint16_t servHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_serv_cp cp; + + cp.service_handle = htobs(servHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_inc_serv_cp cp; + + cp.service_handle = htobs(servHandle); + cp.inc_serv_handle = htobs(includeServHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_INC_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_INC_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) +{ + struct hci_request rq; + uint8_t status; + gatt_set_evt_mask_cp cp; + + cp.evt_mask = htobs(event_mask); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_EVT_MASK; + rq.cparam = &cp; + rq.clen = GATT_SET_EVT_MASK_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_exchange_config_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_EXCHANGE_CONFIG; + rq.cparam = &cp; + rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) +{ + struct hci_request rq; + uint8_t status; + att_find_info_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_INFO_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_find_by_type_value_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + Osal_MemCpy(cp.uuid, uuid, 2); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_group_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_prepare_write_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.value_offset = htobs(value_offset); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) +{ + struct hci_request rq; + uint8_t status; + att_execute_write_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.execute = execute; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_prim_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_prim_service_by_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; + rq.cparam = &cp; + rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, + uint16_t end_service_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_find_included_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_service_handle); + cp.end_handle = htobs(end_service_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_of_serv_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_attr_handle = htobs(start_attr_handle); + cp.end_attr_handle = htobs(end_attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t charUuidType, + const uint8_t* charUuid) +{ + struct hci_request rq; + uint8_t status; + + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + start_handle = htobs(start_handle); + Osal_MemCpy(buffer + indx, &start_handle, 2); + indx += 2; + + end_handle = htobs(end_handle); + Osal_MemCpy(buffer + indx, &end_handle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == 0x01){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_descriptors_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.char_val_handle = htobs(char_val_handle); + cp.char_end_handle = htobs(char_end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_read_using_charac_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; + rq.cparam = &cp; + rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles) +{ + struct hci_request rq; + uint8_t status; + gatt_read_multiple_charac_val_cp cp; + + if(num_handles*2 > sizeof(cp.set_of_handles)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.num_handles = htobs(num_handles); + Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_long_charac_val_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; + rq.cparam = &cp; + rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_signed_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_confirm_indication_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_CONFIRM_INDICATION; + rq.cparam = &cp; + rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = write_status; + indx += 1; + + buffer[indx] = err_code; + indx += 1; + + buffer[indx] = att_val_len; + indx += 1; + + Osal_MemCpy(buffer + indx, att_val, att_val_len); + indx += att_val_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(uint16_t conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ALLOW_READ; + rq.cparam = &cp; + rq.clen = GATT_ALLOW_READ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission) +{ + struct hci_request rq; + gatt_set_security_permission_cp cp; + uint8_t status; + + cp.service_handle = htobs(service_handle); + cp.attr_handle = htobs(attr_handle); + cp.security_permission = security_permission; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; + rq.cparam = &cp; + rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + charDescHandle = htobs(charDescHandle); + Osal_MemCpy(buffer + indx, &charDescHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charDescValOffset, 2); + indx += 2; + + buffer[indx] = charDescValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); + indx += charDescValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_DESC_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_cp cp; + gatt_read_handle_val_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = btohs(rp.value_len); + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_offset_cp cp; + gatt_read_handle_val_offset_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rp.value_len; + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value) +{ + struct hci_request rq; + uint8_t status; + gatt_upd_char_val_ext_cp cp; + + if(value_length > sizeof(cp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.service_handle = htobs(service_handle); + cp.char_handle = htobs(char_handle); + cp.update_type = update_type; + cp.char_length = htobs(char_length); + cp.value_offset = htobs(value_offset); + cp.value_length = value_length; + Osal_MemCpy(cp.value, value, value_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL_EXT; + rq.cparam = &cp; + rq.clen = GATT_UPD_CHAR_VAL_EXT_CP_SIZE + value_length; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,266 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number) +{ + struct hci_request rq; + hal_get_fw_build_number_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_FW_BUILD_NUMBER; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *build_number = rp.build_number; + + return 0; +} + +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((len+2) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = offset; + indx++; + + buffer[indx] = len; + indx++; + + Osal_MemCpy(buffer + indx, val, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + hal_read_config_data_cp cp; + hal_read_config_data_rp rp; + + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_READ_CONFIG_DATA; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rq.rlen-1; + + Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) +{ + struct hci_request rq; + hal_set_tx_power_level_cp cp; + uint8_t status; + + cp.en_high_power = en_high_power; + cp.pa_level = pa_level; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets) +{ + struct hci_request rq; + hal_le_tx_test_packet_number_rp resp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_LE_TX_TEST_PACKET_NUMBER; + rq.rparam = &resp; + rq.rlen = sizeof(resp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *number_of_packets = btohl(resp.number_of_packets); + + return 0; +} + +tBleStatus aci_hal_device_standby(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_DEVICE_STANDBY; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_start(uint8_t rf_channel) +{ + struct hci_request rq; + hal_tone_start_cp cp; + uint8_t status; + + cp.rf_channel = rf_channel; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_START; + rq.cparam = &cp; + rq.clen = HAL_TONE_START_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_stop(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_STOP; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]) +{ + struct hci_request rq; + hal_get_link_status_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_LINK_STATUS; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(link_status,rp.link_status,sizeof(link_status)); + for(int i = 0; i < 8; i++) + conn_handle[i] = btohs(rp.conn_handle[i]); + + return 0; +} + +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot) +{ + struct hci_request rq; + hal_get_anchor_period_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_ANCHOR_PERIOD; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *anchor_period = btohl(rp.anchor_period); + *max_free_slot = btohl(rp.max_free_slot); + + return 0; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,117 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB05A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.min_ce_length = htobs(min_ce_length); + cp.max_ce_length = htobs(max_ce_length); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB04A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,269 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_updater_aci.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_updater_reboot(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_get_updater_version(uint8_t *version) +{ + struct hci_request rq; + get_updater_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_VERSION; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) +{ + struct hci_request rq; + get_updater_bufsize_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_BUFSIZE; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_reset_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = htobl(address); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_SECTOR; + rq.cparam = &cp; + rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_program_data_block(uint32_t address, + uint16_t len, + const uint8_t *data) +{ + struct hci_request rq; + uint8_t status; + updater_prog_data_block_cp cp; + + if( len > sizeof(cp.data)) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(len); + Osal_MemCpy(cp.data, data, len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_read_data_block(uint32_t address, + uint16_t data_len, + uint8_t *data) +{ + struct hci_request rq; + updater_read_data_block_cp cp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + + if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(data_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; + rq.rparam = buffer; + rq.rlen = data_len + 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + // First byte is status + Osal_MemCpy(data, buffer+1, data_len); + + return buffer[0]; +} + +tBleStatus aci_updater_calc_crc(uint32_t address, + uint8_t num_sectors, + uint32_t *crc) +{ + struct hci_request rq; + updater_calc_crc_cp cp; + updater_calc_crc_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + cp.address = htobl(address); + cp.num_sectors = num_sectors; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_CALC_CRC; + rq.cparam = &cp; + rq.clen = UPDATER_CALC_CRC_CP_SIZE; + rq.rparam = &resp; + rq.rlen = UPDATER_CALC_CRC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *crc = btohl(resp.crc); + + return resp.status; +} + +tBleStatus aci_updater_hw_version(uint8_t *version) +{ + struct hci_request rq; + updater_hw_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_HW_VERSION; + rq.rparam = &resp; + rq.rlen = UPDATER_HW_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,423 @@ + +#include "ble_hal.h" +#include "ble_hal_types.h" +#include "ble_status.h" +#include "bluenrg_aci.h" +#include "bluenrg_utils.h" +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "ble_osal.h" +#include "string.h" +#include "stm32_bluenrg_ble.h" + +#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 +#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 + +#define BASE_ADDRESS 0x10010000 + +#define FW_OFFSET (2*1024) // 2 KB +#define FW_OFFSET_MS 0 +#define FULL_STACK_SIZE (66*1024) // 66 KB +#define BOOTLOADER_SIZE (2*1024) // 2 kB +#define SECTOR_SIZE (2*1024) // 2 KB + +// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + +// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 +#define CRC_POLY 0x04C11DB7 // the poly without the x**32 + +#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC + +#define IFR_SIZE 192 +#define IFR_BASE_ADDRESS 0x10020000 +#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data + +#if BLUENRG_MS +#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET +#else +#define IFR_WRITE_OFFSET_BEGIN 0 +#endif + + +#define BLUE_FLAG_OFFSET 0x8C0 +#define MAX_ERASE_RETRIES 2 +#define MAX_WRITE_RETRIES 2 +#define MIN_WRITE_BLOCK_SIZE 4 +#define MAX_WRITE_BLOCK_SIZE 64 // 64 bytes +#define READ_BLOCK_SIZE 64 // 64 bytes + +#define RETRY_COMMAND(func, num_ret, error) \ +{ \ + uint8_t num_retries; \ + num_retries = 0; \ + error = 0; \ + while (num_retries++ < num_ret) { \ + if (func == BLE_STATUS_SUCCESS) \ + break; \ + if (num_retries == num_ret) \ + error = BLE_UTIL_ACI_ERROR; \ + } \ +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, + they are extended with 0xFF until sector size is reached +*/ +static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) +{ + uint32_t i, j, a1; + uint32_t crc, value; + + crc = 0; + for (i = 0; i < SECTOR_SIZE; i += 4) { + uint8_t *dataw = (uint8_t *) &value; + + dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; + dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; + dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; + dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; + + crc = crc ^ value; + for (j = 0; j < 32; j ++) { + a1 = (crc >> 31) & 0x1; + crc = (crc << 1) ^ (a1 * CRC_POLY); + } + } + + return crc; +} + +int program_device(const uint8_t *fw_image, uint32_t fw_size) +{ + uint8_t version, num_erase_retries, status, write_block_size; + uint32_t address; + uint32_t crc, crc2, crc_size; + uint32_t fw_offset = FW_OFFSET; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + if(aci_updater_hw_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version==0x31){ + // It does not contain bootloader inside first sector. It may contain code. + fw_offset = FW_OFFSET_MS; + } + + if (fw_size != FULL_STACK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + if (fw_size % MIN_WRITE_BLOCK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + + /*********************************************************************** + * Erase BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + /*********************************************************************** + * Erase and Program sectors + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE) { + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(BASE_ADDRESS + i); + for (int j=i; ((j<i+SECTOR_SIZE)&&(j<fw_size)); j += write_block_size) { + + write_block_size = MIN(fw_size-j, MAX_WRITE_BLOCK_SIZE); + + RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, write_block_size, fw_image+j), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + break; + } + if (status == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + } + + /*********************************************************************** + * Verify firmware + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE){ + address = BASE_ADDRESS + i; + if(aci_updater_calc_crc(address, 1, &crc)) + return BLE_UTIL_ACI_ERROR; + + crc_size = MIN(fw_size-i,SECTOR_SIZE); + + crc2 = updater_calc_crc(fw_image+i,crc_size); + if(crc!=crc2) + return BLE_UTIL_CRC_ERROR; + } + + /*********************************************************************** + * Write BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +int read_IFR(uint8_t *data) +{ + uint8_t version, offset; + tBleStatus ret; + + offset = 0; + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + /*********************************************************************** + * Reading last 3 IFR 64-byte blocks + ************************************************************************/ + for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(BASE_ADDRESS+i, READ_BLOCK_SIZE, (data+offset)); + offset += READ_BLOCK_SIZE; + if(ret) return BLE_UTIL_ACI_ERROR; + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; + +} + +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) +{ + IFR_config->stack_mode = data[0]; + IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); + IFR_config->master_sca = data[30]; + IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); + IFR_config->year = BCD_TO_INT(data[41]); + IFR_config->month = BCD_TO_INT(data[42]); + IFR_config->day = BCD_TO_INT(data[43]); +} + +int IFR_validate(IFR_config2_TypeDef *IFR_config) +{ +#if BLUENRG_MS + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) +#else + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) +#endif + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode + if(IFR_config->master_sca > 7) + return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->day > 31 || IFR_config->day < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + + return BLE_STATUS_SUCCESS; +} + +/* TODO: Function to generate data from given options. */ + +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) +{ + data[0] = IFR_config->stack_mode; + HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); + data[30] = IFR_config->master_sca; + HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); + data[41] = INT_TO_BCD(IFR_config->year); + data[42] = INT_TO_BCD(IFR_config->month); + data[43] = INT_TO_BCD(IFR_config->day); +} + + +int program_IFR(const IFR_config_TypeDef *ifr_image) +{ + uint8_t version, num_erase_retries; + tBleStatus ret; +#if BLUENRG_MS + const uint8_t *ifr_data = (uint8_t *)ifr_image; +#else + uint8_t ifr_data[SECTOR_SIZE]; +#endif + uint8_t hwVersion; + uint16_t fwVersion; + + if(getBlueNRGVersion(&hwVersion, &fwVersion)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + +#ifndef BLUENRG_MS + /*********************************************************************** + * READ IFR data + ************************************************************************/ + for(int i = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_data+i); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + } +#endif + + /*********************************************************************** + * Erase & Flashing IFR sectors + ************************************************************************/ +#ifndef BLUENRG_MS + Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); +#endif + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(IFR_BASE_ADDRESS); + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += MAX_WRITE_BLOCK_SIZE, j += MAX_WRITE_BLOCK_SIZE) { + RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, MAX_WRITE_BLOCK_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); + if (ret != BLE_STATUS_SUCCESS) + break; + } + if (ret == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + + /*********************************************************************** + * Verify IFR + ************************************************************************/ + { + uint8_t ifr_updated[READ_BLOCK_SIZE]; + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE, j += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ifr_data+j, READ_BLOCK_SIZE) != 0) + return BLE_UTIL_WRONG_VERIFY; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) +{ + uint8_t ifr_updated[READ_BLOCK_SIZE]; + uint8_t version, ret = BLE_STATUS_SUCCESS; + + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + for(int i = 0; i < IFR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, READ_BLOCK_SIZE) != 0) + { + ret = BLE_UTIL_WRONG_VERIFY; + break; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return ret; +} + +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) +{ + uint8_t status; + uint8_t hci_version, lmp_pal_version; + uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; + + status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, + &manufacturer_name, &lmp_pal_subversion); + + if (status == BLE_STATUS_SUCCESS) { + *hwVersion = hci_revision >> 8; + *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number + *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number + *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number + } + + return status; +} + +uint8_t getBlueNRGUpdaterVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(version)) + return BLE_UTIL_ACI_ERROR; + + if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_updater_hw_version(version)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t isHWBootloader_Patched(void) +{ + uint8_t status, version; + uint32_t crc, address = 0x10010000; + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); + if (status != BLE_STATUS_SUCCESS) + return 0; + + if (crc == BOOTLOADER_CRC_NOT_PATCHED) + return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +#include "ble_gp_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function sets a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * @param[in] t A pointer to the timer + * @param[in] interval The interval before the timer expires. + * + */ +void +Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +Timer_Expired(struct timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + tClockTime diff = (Clock_Time() - t->start) + 1; + return t->interval < diff; + +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +tClockTime +Timer_Remaining(struct timer *t) +{ + return t->start + t->interval - Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +#ifdef __DMA_LP__ + +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID) +{ + TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, + (pf_TIMER_TimerCallBack_t) timercb); + TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); + + return (BLE_STATUS_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) +{ + TIMER_Delete(timerID); + + return (BLE_STATUS_SUCCESS); +} + +#endif /* __DMA_LP__ */ +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,119 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Circular Linked List Implementation. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/****************************************************************************** + * Include Files +******************************************************************************/ +#include <ble_hal_types.h> +#include "ble_list.h" + +/****************************************************************************** + * Function Definitions +******************************************************************************/ +void list_init_head (tListNode * listHead) +{ + listHead->next = listHead; + listHead->prev = listHead; +} + +uint8_t list_is_empty (tListNode * listHead) +{ + return ((listHead->next == listHead)? TRUE:FALSE); +} + +void list_insert_head (tListNode * listHead, tListNode * node) +{ + node->next = listHead->next; + node->prev = listHead; + listHead->next = node; + (node->next)->prev = node; +} + + +void list_insert_tail (tListNode * listHead, tListNode * node) +{ + node->next = listHead; + node->prev = listHead->prev; + listHead->prev = node; + (node->prev)->next = node; +} + + +void list_remove_node (tListNode * node) +{ + (node->prev)->next = node->next; + (node->next)->prev = node->prev; +} + + +void list_remove_head (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->next; + list_remove_node (listHead->next); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_remove_tail (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->prev; + list_remove_node (listHead->prev); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_insert_node_after (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node->next; + node->prev = ref_node; + ref_node->next = node; + (node->next)->prev = node; +} + + +void list_insert_node_before (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node; + node->prev = ref_node->prev; + ref_node->prev = node; + (node->prev)->next = node; +} + + +int list_get_size (tListNode * listHead) +{ + int size = 0; + tListNode * temp = listHead->next; + while (temp != listHead) + { + size++; + temp = temp->next; + } + return (size); +} + +void list_get_next_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->next; +} + + +void list_get_prev_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->prev; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,72 @@ +/** +****************************************************************************** +* @file ble_osal.c +* @author AMS - HEA&RF BU / CL +* @version V1.0.0 +* @date 04-July-2014 +* @brief Implementation of OS abstraction layer functions used by the +* library. +****************************************************************************** +* @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> +#include <ble_osal.h> + + /** + * @brief Osal_MemCpy + * @param dest: Pointer to the destination buffer + * @param src : Pointer to the source buffer + * @param size: Number of bytes to copy from the source to the destination + * buffer + * @retval Pointer to the destination buffer + */ +void* Osal_MemCpy(void *dest, const void *src, unsigned int size) +{ + return(memcpy(dest,src,size)); +} + +/** + * @brief Osal_MemSet + * @param ptr : Pointer to block of memory to fill + * @param value: Value to assign to each byte of the memory block + * @param size : Number of bytes to be set to "value" + * @retval Pointer to the filled block of memory + */ +void* Osal_MemSet(void *ptr, int value, unsigned int size) +{ + return(memset(ptr,value,size)); +} + +/****************************************************************************** + * local Functions + *****************************************************************************/ + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ + +#include "ble_clock.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/wait_api.h" + #include "mbed-drivers/rtc_time.h" +#else + #include "wait_api.h" + #include "rtc_time.h" +#endif + +const uint32_t CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + //Not Used +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return clock(); +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,715 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file btle.cpp + * @author STMicroelectronics + * @brief Implementation BlueNRG Init and helper functions. + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + + +#include "btle.h" +#include "ble/Gap.h" +#include "ble/GapEvents.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" + +#include "bluenrg_targets.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* C File Includes ------------------------------------------------------------------*/ +#include <stdio.h> +#include <string.h> +#include "ble_hci.h" +#include "ble_hci_const.h" +#include "bluenrg_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" +#include "bluenrg_utils.h" + +#include "ble_hal_types.h" +#include "ble_hal.h" +#include "ble_gp_timer.h" +#include "ble_osal.h" +#include "ble_sm.h" +#include "ble_debug.h" + +#ifdef __cplusplus +} +#endif + +#define IDB04A1 0 +#define IDB05A1 1 + +/* See file 'bluenrg_targets.h' for details regarding the BLUENRG_STACK_MODE */ +#define STACK_MODE BLUENRG_STACK_MODE + +void HCI_Input(tHciDataPacket * hciReadPacket); + +uint16_t g_gap_service_handle = 0; +uint16_t g_appearance_char_handle = 0; +uint16_t g_device_name_char_handle = 0; +uint16_t g_preferred_connection_parameters_char_handle = 0; + +/* Private variables ---------------------------------------------------------*/ +volatile uint8_t set_connectable = 1; + +static char versionString[32]; +uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ + +/**************************************************************************/ +/*! + @brief Init the BTLE stack with the specified role + @returns void +*/ +/**************************************************************************/ +void btleInit(void) +{ + PRINTF("btleInit>>\n\r"); + + int ret; + uint8_t hwVersion; + uint16_t fwVersion; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* get the BlueNRG HW and FW versions */ + getBlueNRGVersion(&hwVersion, &fwVersion); + + /* + * Reset BlueNRG again otherwise we won't + * be able to change its MAC address. + * aci_hal_write_config_data() must be the first + * command after reset otherwise it will fail. + */ + BlueNRG_RST(); + + if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ + bnrg_expansion_board = IDB05A1; + } + + /* set BLE version string */ + setVersionString(hwVersion, fwVersion); + + if (bnrg_expansion_board == IDB05A1) { + uint8_t stackMode = STACK_MODE; + ret = aci_hal_write_config_data(CONFIG_DATA_MODE_OFFSET, + CONFIG_DATA_MODE_LEN, + &stackMode); + } + + ret = aci_gatt_init(); + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GATT_Init failed.\n"); + } + if (bnrg_expansion_board == IDB05A1) { + ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1, + 0, + 0x18, + &service_handle, + &dev_name_char_handle, + &appearance_char_handle); + } else { + // IDB04A1 is configured as peripheral by default + ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + } + + // read the default static address and inject it into the GAP object + { + Gap::Address_t BLE_address_BE = { 0 }; + uint8_t data_len_out; + aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS, BDADDR_SIZE, &data_len_out, BLE_address_BE); + // FIXME error handling of this function + BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE); + } + + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GAP_Init failed.\n"); + } + + //FIXME: Security and passkey set by default + ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, + OOB_AUTH_DATA_ABSENT, + NULL, + 7, + 16, + USE_FIXED_PIN_FOR_PAIRING, + 123456, + BONDING); + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Auth Req set failed.\n"); + } + + aci_hal_set_tx_power_level(1,4); + + g_gap_service_handle = service_handle; + g_appearance_char_handle = appearance_char_handle; + g_device_name_char_handle = dev_name_char_handle; + //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API + /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, + strlen(name), (tHalUint8 *)name);*/ + + signalEventsToProcess(); + // update the peripheral preferred conenction parameters handle + // This value is hardcoded at the moment. + g_preferred_connection_parameters_char_handle = 10; + + return; +} + +/**************************************************************************/ +/*! + @brief mbedOS + + @param[in] void + + @returns +*/ +/**************************************************************************/ +int btle_handler_pending = 0; + +void btle_handler(void) +{ + btle_handler_pending = 0; + BlueNRGGap::getInstance().Process(); + HCI_HandleSPI(); + HCI_Process(); +} + +/* set BLE Version string */ +void setVersionString(uint8_t hwVersion, uint16_t fwVersion) +{ + if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) { + snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u", + hwVersion>>4, (hwVersion&0x0F), + fwVersion>>8, (fwVersion&0x00F0)>>4); + } else { + snprintf(versionString, sizeof(versionString), "ST (unknown spec)"); + } +} + +/* get BLE Version string */ +const char* getVersionString(void) +{ + return versionString; +} + +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type) +{ + tBleStatus ret; + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + if(bnrg_expansion_board == IDB05A1) { + PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window); + PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type); + ret = aci_gap_start_observation_procedure(scan_interval, + scan_window, + scan_type, + own_address_type, + 0); // 1 to filter duplicates + } else { + ret = BLE_STATUS_INVALID_CID; + } + + return ret; + +} + +/*! + @brief Not Used + + @param[in] void + + @returns +*/ +void SPI_Poll(void) +{ + //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); + return; +} + +void Attribute_Modified_CB(evt_blue_aci *blue_evt) +{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t *att_data; + uint8_t offset; + + if (bnrg_expansion_board == IDB05A1) { + evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = evt->offset; + } else { + evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = 0; + } + + //Extract the GattCharacteristic from p_characteristics[] and find the properties mask + GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle); + if(p_char!=NULL) { + GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE; + PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]); + PRINTF("getProperties 0x%x\n\r",p_char->getProperties()); + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; + } + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; + } + PRINTF("currentHandle %d\n\r", currentHandle); + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && + currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { + + GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1; + + PRINTF("*****NOTIFICATION CASE\n\r"); + //Now Check if data written in Enable or Disable + if((uint16_t)att_data[0]==1) { + //PRINTF("Notify ENABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle); + } else { + //PRINTF("Notify DISABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle); + } + return; + } + + //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) && + currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) { + + PRINTF("*****WRITE CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = p_char->getValueAttribute().getHandle(); + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle); + //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + BlueNRGGattServer::getInstance().write( + p_char->getValueAttribute().getHandle(), + (uint8_t*)att_data, + data_length, + false + ); + } + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } else { + PRINTF("*****WRITE DESCRIPTOR CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = attr_handle; + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } + } + +} + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************************/ + /*! + @brief Handle HCI Stack Event + + @param[in] pckt + Event Packet sent by the stack to be decoded + + @returns + */ + /**************************************************************************/ + extern void HCI_Event_CB(void *pckt) { + hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; + hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; + + if(hci_pckt->type != HCI_EVENT_PKT) + return; + + switch(event_pckt->evt){ + + case EVT_DISCONN_COMPLETE: + { + PRINTF("EVT_DISCONN_COMPLETE\n"); + + evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data; + + if(BlueNRGGap::getInstance().getGapRole() == Gap::CENTRAL) { + BlueNRGGattClient::getInstance().removeGattConnectionClient(evt->handle, evt->reason); + } + + BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason); + } + break; + + case EVT_LE_META_EVENT: + { + PRINTF("EVT_LE_META_EVENT\n"); + + evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; + + switch(evt->subevent){ + + case EVT_LE_CONN_COMPLETE: + { + PRINTF("EVT_LE_CONN_COMPLETE\n"); + Gap::Address_t ownAddr; + Gap::AddressType_t ownAddrType; + BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr); + + Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + Gap::Role_t role; + + evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; + + BlueNRGGap::getInstance().setConnectionHandle(cc->handle); + BlueNRGGap::ConnectionParams_t connectionParams = { + /* minConnectionInterval = */ cc->interval, + /* maxConnectionInterval = */ cc->interval, + /* slaveLatency = */ cc->latency, + /* connectionSupervisionTimeout = */ cc->supervision_timeout + }; + + BlueNRGGap::getInstance().setConnectionInterval(cc->interval); + + switch (cc->peer_bdaddr_type) { + case PUBLIC_ADDR: + peerAddrType = BLEProtocol::AddressType::PUBLIC; + break; + case STATIC_RANDOM_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + break; + case RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE; + break; + case NON_RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE; + break; + } + //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role); + switch (cc->role) { + case 0: //master + role = Gap::CENTRAL; + BlueNRGGattClient::getInstance().createGattConnectionClient(cc->handle); + break; + case 1: + role = Gap::PERIPHERAL; + break; + default: + role = Gap::PERIPHERAL; + break; + } + + BlueNRGGap::getInstance().setGapRole(role); + + BlueNRGGap::getInstance().processConnectionEvent(cc->handle, + role, + peerAddrType, + cc->peer_bdaddr, + ownAddrType, + ownAddr, + &connectionParams); + } + break; + + case EVT_LE_ADVERTISING_REPORT: + PRINTF("EVT_LE_ADVERTISING_REPORT\n\r"); + /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */ + // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT) + // Formally the structure related to both events are identical except that for the ADV REPORT + // there is one more field (number of reports) which is not forwarded to upper layer. + // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT. + le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1); + PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + break; + } + } + break; + + case EVT_VENDOR: + { + evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; + //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode); + + switch(blue_evt->ecode){ + + case EVT_BLUE_GATT_WRITE_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_WRITE_PERMIT_REQ\r\n"); + evt_gatt_write_permit_req* write_req = (evt_gatt_write_permit_req*)blue_evt->data; + + // ask the local server if the write operation is authorized + uint8_t err_code = BlueNRGGattServer::getInstance().Write_Request_CB( + write_req->conn_handle, + write_req->attr_handle, + write_req->data_length, + write_req->data + ); + uint8_t write_status = err_code == 0 ? 0 : 1; + + // reply to the shield + aci_gatt_write_response( + write_req->conn_handle, + write_req->attr_handle, + write_status, + err_code, + write_req->data_length, + write_req->data + ); + } + break; + + case EVT_BLUE_GATT_READ_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r"); + evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle); + BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle); + } + break; + + case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: + { + PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r"); + /* this callback is invoked when a GATT attribute is modified + extract callback data and pass to suitable handler function */ + Attribute_Modified_CB(blue_evt); + } + break; + + //Any cases for Data Sent Notifications? + case EVT_BLUE_GATT_NOTIFICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_NOTIFICATION"); + break; + case EVT_BLUE_GATT_INDICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_INDICATION"); + break; + + case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r"); + evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_data_length, + pr->attribute_data_list); + } + break; + case EVT_BLUE_ATT_READ_BY_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r"); + evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle, + pr->event_data_length, + pr->handle_value_pair_length, + pr->handle_value_pair); + } + break; + case EVT_BLUE_ATT_READ_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_RESP\n\r"); + evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_value); + } + break; + case EVT_BLUE_ATT_EXEC_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle, + pr->event_data_length); + } + break; + case EVT_BLUE_ATT_PREPARE_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_handle, + pr->offset, + pr->part_attr_value); + } + break; + case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP: + { + PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r"); + evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle, + pr->event_data_length, + pr->attr_handle, + pr->attr_value); + } + break; + case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r"); + evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle, + pr->event_data_length, + pr->handles_info_list); + } + break; + case EVT_BLUE_ATT_FIND_INFORMATION_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r"); + evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle, + pr->event_data_length, + pr->format, + pr->handle_uuid_pair); + } + break; + case EVT_BLUE_GATT_PROCEDURE_COMPLETE: + { + evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code); + BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code); + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_REQ: + { + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_REQ\r\n"); + evt_l2cap_conn_upd_req *evt = (evt_l2cap_conn_upd_req*)blue_evt->data; + if(bnrg_expansion_board == IDB05A1) { + // we assume the application accepts the request from the slave + aci_l2cap_connection_parameter_update_response_IDB05A1(evt->conn_handle, + evt->interval_min, + evt->interval_max, + evt->slave_latency, + evt->timeout_mult, + CONN_L1, CONN_L2, + evt->identifier, + 0x0000); + } + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_RESP: + { + evt_l2cap_conn_upd_resp *evt = (evt_l2cap_conn_upd_resp*)blue_evt->data; + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_RESP code=0x%x, result=0x%x\r\n", evt->code, evt->result); + } + break; + + case EVT_LE_CONN_UPDATE_COMPLETE: + { + evt_le_connection_update_complete *evt = (evt_le_connection_update_complete*)blue_evt->data; + PRINTF("EVT_LE_CONN_UPDATE_COMPLETE status=0x%x\r\n", evt->status); + } + break; + + case EVT_BLUE_GAP_DEVICE_FOUND: + { + evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data; + PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + } + break; + + case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + { + evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data; + //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code); + + switch(pr->procedure_code) { + case GAP_OBSERVATION_PROC_IDB05A1: + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL); + break; + } + } + break; + } + } + break; + } + return ; + } + + +#ifdef __cplusplus +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,217 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.cpp + * @author CL + * @version V1.0.0 + * @date 15-June-2015 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRGGap.h" +#include "BlueNRGDevice.h" +#include "btle.h" + +// FIXME: find a better way to get the instance of the BlueNRG device +extern BlueNRGDevice bluenrgDeviceInstance; + + +//////////////////////////////////////// +// Start of C function wrappers +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32_bluenrg_ble.h" +#include "ble_debug.h" + + +void BlueNRG_RST(void) +{ + bluenrgDeviceInstance.reset(); +} + +uint8_t BlueNRG_DataPresent(void) +{ + return (bluenrgDeviceInstance.dataPresent()); +} + + +/** + * @brief This function is a utility to print the log time +* in the format HH:MM:SS:MSS (DK GUI time format) + * @param None + * @retval None + */ +void print_csv_time(void){ +#ifdef PRINT_CSV_FORMAT + uint32_t ms = 0;//ms_counter; + PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000); +#endif +} + +/** + * @brief Writes data to a serial interface. + * @param data1 : 1st buffer + * @param data2 : 2nd buffer + * @param n_bytes1: number of bytes in 1st buffer + * @param n_bytes2: number of bytes in 2nd buffer + * @retval None + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, + int32_t n_bytes2) +{ + struct timer t; + + Timer_Set(&t, CLOCK_SECOND/10); + +#ifdef PRINT_CSV_FORMAT + print_csv_time(); + for (int i=0; i<n_bytes1; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data1)[i]); + } + for (int i=0; i<n_bytes2; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data2)[i]); + } + PRINT_CSV("\n"); +#endif + + while(1){ + if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; + if(Timer_Expired(&t)){ + break; + } + } +} + + +/** + * @brief Activate internal bootloader using pin. + * @param None + * @retval None + */ +void BlueNRG_HW_Bootloader(void) +{ + // Reset BlueNRG SPI interface + BlueNRG_RST(); + + // Send an ACI command to reboot BlueNRG in bootloader mode + // The safest way to get in bootloader mode is keeping high + // the interrupt pin during reset, but this would require many + // changes to the current mbed driver + aci_updater_start(); +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size) +{ + int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size); + + return ret; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2); + + return ret; +} + +/** + * @brief Enable SPI IRQ. + * @param None + * @retval None + */ +void Enable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.enable_irq(); +} + +void signalEventsToProcess(void) { + if(btle_handler_pending == 0) { + btle_handler_pending = 1; + bluenrgDeviceInstance.signalEventsToProcess(BLE::DEFAULT_INSTANCE); + } +} + +/** + * @brief Disable SPI IRQ. + * @param None + * @retval None + */ +void Disable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.disable_irq(); +} + +/** + * @brief Clear Pending SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_IRQ(void) +{ +} + +/** + * @brief Clear EXTI (External Interrupt) line for SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_EXTI_Flag(void) +{ +} + + + + +#ifdef __cplusplus +} +#endif +// End of C function wrappers +//////////////////////////////////////// + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <ble_payload.h> + +Payload::Payload() { + stringLength = 0; + payloadUnitCount = 0; + payload = NULL; +} + +Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + stringLength = string_ength; + payloadUnitCount = 0; + payload = NULL; + + int index = 0; + while( index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + UnitPayload *obj = new UnitPayload[payloadUnitCount]; + int i=0; + int c=0; + int j,k; + + while(i<payloadUnitCount) + { + obj[i].length=tokenString[c]; + obj[i].id=tokenString[c+1]; + + obj[i].data = new uint8_t[obj[i].length]; + for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) + { + obj[i].data[k]=tokenString[j]; + + } + + c=c+obj[i].length+1; + i++; + + } + payload = obj; +} + +uint8_t Payload::getPayloadUnitCount() { + return payloadUnitCount; +} + +uint8_t Payload::getIDAtIndex(int index) { + return payload[index].get_id(); +} + +uint8_t Payload::getLengthAtIndex(int index) { + return payload[index].get_length(); +} + +uint8_t* Payload::getDataAtIndex(int index) { + return payload[index].get_data(); +} + +int8_t Payload::getInt8AtIndex(int index) { + uint8_t* str = payload[index].get_data(); + int8_t value = (int8_t)str[0]; + return value; +} + +uint16_t Payload::getUint16AtIndex(int index) { + uint16_t* str = (uint16_t*)payload[index].get_data(); + uint16_t value = str[0]; + return value; +} + +uint8_t* Payload::getSerializedAdDataAtIndex(int index) { + uint8_t length = payload[index].get_length(); + uint8_t* data = payload[index].get_data(); + uint8_t id = payload[index].get_id(); + uint8_t *serializedAdData = new uint8_t[length]; + + serializedAdData[0] = id; + for(int i=0; i<length-1; i++) { + serializedAdData[i+1] = data[i]; + } + return serializedAdData; +} + +Payload::~Payload() { + int i = 0; + + if(payload) { + while(i<payloadUnitCount) { + if(payload->data) { + delete[] payload->data; + payload->data = NULL; + } + } + delete[] payload; + payload = NULL; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_GattServer/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,93 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ble_utils.h" + +/**************************************************************************/ +/*! + @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power + +*/ +/**************************************************************************/ +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(dBMLevel==-18) { + EN_HIGH_POWER = 0; + PA_LEVEL = 0; + } + else if(dBMLevel==-15) { + EN_HIGH_POWER = 0; + PA_LEVEL = 1; + } + else if(dBMLevel==-14) { + EN_HIGH_POWER = 1; + PA_LEVEL = 0; + } + else if(dBMLevel==-12) { + EN_HIGH_POWER = 0; + PA_LEVEL = 2; + } + else if(dBMLevel==-11) { + EN_HIGH_POWER = 1; + PA_LEVEL = 1; + } + else if(dBMLevel==-9) { + EN_HIGH_POWER = 0; + PA_LEVEL = 3; + } + else if(dBMLevel==-8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 2; + } + else if(dBMLevel==-6) { + EN_HIGH_POWER = 0; + PA_LEVEL = 4; + } + else if(dBMLevel==-5) { + EN_HIGH_POWER = 1; + PA_LEVEL = 3; + } + else if(dBMLevel==-2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 4; + } + else if(dBMLevel==0) { + EN_HIGH_POWER = 0; + PA_LEVEL = 6; + } + else if(dBMLevel==2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 5; + } + else if(dBMLevel==4) { + EN_HIGH_POWER = 1; + PA_LEVEL = 6; + } + else if(dBMLevel==5) { + EN_HIGH_POWER = 0; + PA_LEVEL = 7; + } + else if(dBMLevel==8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + else { + ret = ERR_INVALID_HCI_CMD_PARAMS; + } + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/.mbed Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,3 @@ +TARGET=NRF51_DK +TOOLCHAIN=GCC_ARM +ROOT=.
Binary file mbed-os-example-ble-master/BLE_HeartRate/img/connection.png has changed
Binary file mbed-os-example-ble-master/BLE_HeartRate/img/discovery.png has changed
Binary file mbed-os-example-ble-master/BLE_HeartRate/img/notifications.png has changed
Binary file mbed-os-example-ble-master/BLE_HeartRate/img/register_to_notifications.png has changed
Binary file mbed-os-example-ble-master/BLE_HeartRate/img/scan_result.png has changed
Binary file mbed-os-example-ble-master/BLE_HeartRate/img/start_scan.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/mbed-os.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/mbed_app.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "target_overrides": { + "K64F": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "NUCLEO_F401RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "DISCO_L475VG_IOT01A": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "ble-heartrate", + "version": "0.0.1", + "description": "BLE Heartreate example, building with yotta", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "dependencies": { + "ble": "^2.0.0" + }, + "targetDependencies": {}, + "bin": "./source" +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/readme.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,66 @@ +# BLE Heart Rate Monitor + +This application transmits a heart rate value using the [Bluetooth SIG Heart Rate Profile](https://developer.bluetooth.org/TechnologyOverview/Pages/HRP.aspx). The heart rate value is provided by the application itself, not by a sensor, so that you don't have to get a sensor just to run the example. + +Technical details are better presented [in the mbed Classic equivalent of this example](https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_HeartRate/). + +# Running the application + +## Requirements + +To see the heart rate information on your phone, download Panobike for [iOS](https://itunes.apple.com/gb/app/panobike/id567403997?mt=8) or [Android](https://play.google.com/store/apps/details?id=com.topeak.panobike&hl=en). + +You could also use a generic BLE scanners: + +- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. + +- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Checking for success + +**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. + +1. Build the application and install it on your board as explained in the building instructions. +1. Open the BLE scanner on your phone. +1. Start a scan. + +  + + **figure 1** How to start scan using nRF Master Control Panel 4.0.5 + +1. Find your device; it should be named `HRM`. + +  + + **figure 2** Scan results using nRF Master Control Panel 4.0.5 + +1. Establish a connection with your device. + +  + + **figure 3** How to establish a connection using Master Control Panel 4.0.5 + +1. Discover the services and the characteristics on the device. The *Heart Rate* service has the UUID `0x180D` and includes the *Heart Rate Measurement* characteristic which has the UUID `0x2A37`. + +  + + **figure 4** Representation of the Heart Rate service using Master Control Panel 4.0.5 + +1. Register for the notifications sent by the *Heart Rate Measurement* characteristic. + +  + + **figure 5** How to register to notifications using Master Control Panel 4.0.5 + + +1. You should see the heart rate value change every half second. It begins at 100, goes up to 175 (in steps of 1), resets to 100 and so on. + +  + + **figure 6** Notifications view using Master Control Panel 4.0.5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/#b630517008bbe47592927cc8e5dfcd2e5b9de968
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/.gitignore Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,9 @@ +# vim temporary files +*.sw* + +# yotta files +build +yotta_modules +yotta_targets +.yotta.json +upload.tar.gz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,34 @@ +# BLE-X-NUCLEO-IDB0XA1 + +BLE_API wrapper Library for X-NUCLEO-IDB05A1 BlueNRG (Bluetooth Low Energy) Expansion Board + +## Introduction + +This firmware package implements the port of BLE_API to STMicroelectronics' [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) Bluetooth Low Energy Nucleo Expansion Board. + +### Arduino Connector Compatibility Warning + +X-NUCLEO-IDB05A1 is Arduino compatible with an exception: instead of using pin **D13** for the SPI clock, pin **D3** is used. +The default configuration for this library is having the SPI clock on pin **D3**. + +To be fully Arduino compatible, X-NUCLEO-IDB05A1 needs a small HW patch. + +For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor **R4** and instead soldering zero resistor **R6**. + +In case you patch your board, then you also have to configure this library to use pin **D13** to drive the SPI clock. To this aim you need to compile this driver with macro `BLUENRG_PIN_SPI_SCK=D13` defined. + +If you use pin **D13** for the SPI clock, please be aware that on STM32 Nucleo boards you may **not** drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin **D13**. + +Referring to the current list of tested platforms (see [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) page), the patch is required by [ST-Nucleo-F103RB](https://developer.mbed.org/platforms/ST-Nucleo-F103RB/); [ST-Nucleo-F302R8](https://developer.mbed.org/platforms/ST-Nucleo-F302R8/); [ST-Nucleo-F411RE](https://developer.mbed.org/platforms/ST-Nucleo-F411RE/); [ST-Nucleo-F446RE](https://developer.mbed.org/platforms/ST-Nucleo-F446RE/); and [FRDM-K64F](https://developer.mbed.org/platforms/FRDM-K64F/). + +### Firmware update + +For better performance and compatibility with latest mbed API, you should update firmware of X-NUCLEO-IDB05A1 component by using this simple [application](https://developer.mbed.org/teams/ST/code/BlueNRG-MS-Stack-Updater). + +### Driver configuration + +In order to use the BlueNRG-MS module together with other targets, you need to set the macros defined in file [bluenrg_targets.h](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/bluenrg/bluenrg_targets.h). Please, update the [mbed_lib.json](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/mbed_lib.json) to include the list of extra macros that configure the driver for your target. + +## Example Applications + +To run BLE example applications using X-NUCLEO-IDB05A1 Expansion Board based on mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli), please refer to section [Using ST shield on other targets](https://github.com/ARMmbed/mbed-os-example-ble#using-st-nucleo-shield-on-other-targets) in the official [mbed-os-example-ble](https://github.com/ARMmbed/mbed-os-example-ble) page.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.h + * @author STMicroelectronics + * @brief Header file for BLEDeviceInstanceBase based BlueNRGDevice + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_DEVICE_H__ +#define __BLUENRG_DEVICE_H__ + +#define BLUENRG +#define DEBUG_BLUENRG_USER + +#include "btle.h" + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "ble/BLEInstanceBase.h" +#include "ble/BLE.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" + + +class BlueNRGDevice : public BLEInstanceBase +{ + +public: + BlueNRGDevice(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, PinName irq); + virtual ~BlueNRGDevice(void); + + virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback); + virtual ble_error_t shutdown(void); + virtual const char *getVersion(void); + virtual Gap& getGap(); + virtual const Gap& getGap() const; + virtual GattServer& getGattServer(); + virtual const GattServer& getGattServer() const; + virtual void waitForEvent(void); + + virtual GattClient& getGattClient() { + return BlueNRGGattClient::getInstance(); + } + + virtual SecurityManager& getSecurityManager() { + return *sm; + } + + virtual const SecurityManager& getSecurityManager() const { + return *sm; + } + void reset(void); + virtual bool hasInitialized(void) const { + return isInitialized; + } + + uint8_t getUpdaterHardwareVersion(uint8_t *hw_version); + int updateFirmware(const uint8_t *fw_image, uint32_t fw_size); + bool dataPresent(); + int32_t spiRead(uint8_t *buffer, uint8_t buff_size); + int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2); + void disable_irq(); + void enable_irq(); + + virtual void processEvents(); + +private: + bool isInitialized; + + SPI spi_; + DigitalOut nCS_; + DigitalOut rst_; + InterruptIn irq_; + + //FIXME: TBI (by now just placeholders to let build + /*** betzw: placeholders ***/ + SecurityManager *sm; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ +#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ + +#include "ble/DiscoveredCharacteristic.h" + +class BlueNRGGattClient; /* forward declaration */ + +class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic { +public: + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + + void setLastHandle(GattAttribute::Handle_t lastHandleIn); +}; + +#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGGap.h + * @author STMicroelectronics + * @brief Header file for BlueNRG BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GAP_H__ +#define __BLUENRG_GAP_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/Gap.h" + +#define BLE_CONN_HANDLE_INVALID 0x0 +#define BDADDR_SIZE 6 + +#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020) +#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000) +#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0) + +// Scanning and Connection Params used by Central for creating connection +#define GAP_OBSERVATION_PROC (0x80) + +#define SCAN_P (0x0010) +#define SCAN_L (0x0010) +#define SUPERV_TIMEOUT (0xC80) +#define CONN_P(x) ((int)((x)/1.25f)) +#define CONN_L(x) ((int)((x)/0.625f)) +#define CONN_P1 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_P2 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_L1 (0x0008) +#define CONN_L2 (0x0008) +#define GUARD_INT 5 //msec +#define MIN_INT_CONN 0x0006 //=>7.5msec +#define MAX_INT_CONN 0x0C80 //=>4000msec +#define DEF_INT_CONN 0x0140 //=>400msec (default value for connection interval) + +/**************************************************************************/ +/*! + \brief + +*/ +/**************************************************************************/ +class BlueNRGGap : public Gap +{ +public: + static BlueNRGGap &getInstance() { + static BlueNRGGap m_instance; + return m_instance; + } + + enum Reason_t { + DEVICE_FOUND, + DISCOVERY_COMPLETE + }; + + /* Functions that must be implemented from Gap */ + virtual ble_error_t setAddress(addr_type_t type, const BLEProtocol::AddressBytes_t address); + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address); + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &); + virtual ble_error_t startAdvertising(const GapAdvertisingParams &); + virtual ble_error_t stopAdvertising(void); + virtual ble_error_t stopScan(); + virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);} + virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);} + virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);} + virtual ble_error_t disconnect(DisconnectionReason_t reason); + virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason); + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params); + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); + + virtual ble_error_t setDeviceName(const uint8_t *deviceName); + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); + virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance); + virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP); + + virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode); + virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode); + virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const; + virtual ScanningPolicyMode_t getScanningPolicyMode(void) const; + + virtual ble_error_t setTxPower(int8_t txPower); + virtual void getPermittedTxPowerValues(const int8_t **, size_t *); + + virtual ble_error_t connect(const Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams); + + virtual ble_error_t reset(void); + + void Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI); + ble_error_t createConnection(void); + + void setConnectionHandle(uint16_t con_handle); + uint16_t getConnectionHandle(void); + + bool getIsSetAddress(); + + // ADV timeout handling + Timeout& getAdvTimeout(void) { + return advTimeout; + } + uint8_t getAdvToFlag(void) { + return AdvToFlag; + } + void setAdvToFlag(void); + + // SCAN timeout handling + Timeout& getScanTimeout(void) { + return scanTimeout; + } + uint8_t getScanToFlag(void) { + return ScanToFlag; + } + void setScanToFlag(void); + + void Process(void); + + GapScanningParams* getScanningParams(void); + + virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams); + + void setConnectionInterval(uint16_t interval); + Gap::Role_t getGapRole(void); + void setGapRole(Gap::Role_t role); + +private: + uint16_t m_connectionHandle; + Role_t gapRole; + AddressType_t addr_type; + Address_t _peerAddr; + AddressType_t _peerAddrType; + uint8_t bdaddr[BDADDR_SIZE]; + bool _scanning; + bool _connecting; + bool isSetAddress; + uint8_t deviceAppearance[2]; + + // ADV timeout handling + Timeout advTimeout; + bool AdvToFlag; + + // SCAN timeout handling + Timeout scanTimeout; + bool ScanToFlag; + + static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) { + return (duration * 625) / 1000; + } + + uint16_t scanInterval; + uint16_t scanWindow; + uint16_t advInterval; + uint16_t slaveConnIntervMin; + uint16_t slaveConnIntervMax; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + void setAdvParameters(void); + void setConnectionParameters(void); + + Gap::AdvertisingPolicyMode_t advertisingPolicyMode; + Gap::ScanningPolicyMode_t scanningPolicyMode; + + Whitelist_t whitelistAddresses; + + ble_error_t updateAdvertisingData(void); + + BlueNRGGap() : AdvToFlag(false), ScanToFlag(false) { + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + addr_type = BLEProtocol::AddressType::RANDOM_STATIC; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + isSetAddress = false; + memset(deviceAppearance, 0, sizeof(deviceAppearance)); + } + + BlueNRGGap(BlueNRGGap const &); + void operator=(BlueNRGGap const &); + + GapAdvertisingData _advData; + GapAdvertisingData _scanResponse; +}; + +#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,157 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattClient.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CLIENT_H__ +#define __BLUENRG_GATT_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattConnectionClient.h" + +using namespace std; + +#define MAX_ACTIVE_CONNECTIONS 7 + +class BlueNRGGattClient : public GattClient +{ +public: + static BlueNRGGattClient &getInstance() { + static BlueNRGGattClient m_instance; + return m_instance; + } + + ble_error_t createGattConnectionClient(Gap::Handle_t connectionHandle); + ble_error_t removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason); + + /* Functions that must be implemented from GattClient */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + virtual bool isServiceDiscoveryActive(void) const; + virtual void terminateServiceDiscovery(void); + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback); + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + virtual ble_error_t write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + virtual ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + virtual ble_error_t reset(void); + + void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code); + + void primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(Gap::Handle_t connectionHandle); + + void serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length); + + +protected: + + BlueNRGGattClient(): _connectionPool() {}; + + ServiceDiscovery::TerminationCallback_t terminationCallback; + +private: + + BlueNRGGattClient(BlueNRGGattClient const &); + void operator=(BlueNRGGattClient const &); + + BlueNRGGattConnectionClient *_connectionPool[MAX_ACTIVE_CONNECTIONS]; + uint8_t _numConnections; + + BlueNRGGattConnectionClient * getGattConnectionClient(Gap::Handle_t connectionHandle); + +}; + +#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,185 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattConnectionClient.cpp + * @author STMicroelectronics + * @brief Header file for BlueNRGGattConnectionClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CONNECTION_CLIENT_H__ +#define __BLUENRG_GATT_CONNECTION_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" + +using namespace std; + +#define BLE_TOTAL_DISCOVERED_SERVICES 10 +#define BLE_TOTAL_DISCOVERED_CHARS 10 + +class BlueNRGGattConnectionClient +{ +public: + + enum { + GATT_IDLE, + GATT_SERVICE_DISCOVERY, + GATT_CHAR_DESC_DISCOVERY, + //GATT_CHARS_DISCOVERY_COMPLETE, + //GATT_DISCOVERY_TERMINATED, + GATT_READ_CHAR, + GATT_WRITE_CHAR + }; + + /* Functions that must be implemented from GattClient */ + ble_error_t launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + bool isServiceDiscoveryActive(void) const; + void terminateServiceDiscovery(void); + void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + } + ble_error_t read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + ble_error_t write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + ble_error_t reset(void); + + void gattProcedureCompleteCB(uint8_t error_code); + + void primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(void); + + void serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(uint8_t event_data_length); + +protected: + + BlueNRGGattConnectionClient(BlueNRGGattClient *gattClient, Gap::Handle_t connectionHandle): + discoveredService(), + discoveredChar(), + readCBParams(), + writeCBParams(), + _characteristic() { + + //PRINTF("BlueNRGGattConnectionClient construtor: connHandle=%d\n\r", connectionHandle); + + _gattClient = gattClient; + _connectionHandle = connectionHandle; + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + } + + ServiceDiscovery::ServiceCallback_t serviceDiscoveryCallback; + ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback; + ServiceDiscovery::TerminationCallback_t terminationCallback; + CharacteristicDescriptorDiscovery::DiscoveryCallback_t charDescDiscoveryCallback; + CharacteristicDescriptorDiscovery::TerminationCallback_t charDescTerminationCallback; + +private: + + BlueNRGGattConnectionClient(BlueNRGGattConnectionClient const &); + void operator=(BlueNRGGattConnectionClient const &); + ~BlueNRGGattConnectionClient() {}; + + BlueNRGGattClient *_gattClient; + + Gap::Handle_t _connectionHandle; + DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES]; + BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS]; + + GattReadCallbackParams readCBParams; + GattWriteCallbackParams writeCBParams; + + // The char for which the descriptor discovery has been launched + DiscoveredCharacteristic _characteristic; + + UUID _matchingServiceUUID; + UUID _matchingCharacteristicUUIDIn; + uint8_t _currentState; + uint8_t _numServices, _servIndex; + uint8_t _numChars; + uint8_t _numCharDesc; + + friend class BlueNRGGattClient; +}; + +#endif /* __BLUENRG_GATT_CONNECTION_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_SERVER_H__ +#define __BLUENRG_GATT_SERVER_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattService.h" +#include "ble/GattServer.h" +#include <vector> +#include <map> + +#define BLE_TOTAL_CHARACTERISTICS 10 + +using namespace std; + +class BlueNRGGattServer : public GattServer +{ +public: + static BlueNRGGattServer &getInstance() { + static BlueNRGGattServer m_instance; + return m_instance; + } + + enum HandleEnum_t { + CHAR_HANDLE = 0, + CHAR_VALUE_HANDLE, + CHAR_DESC_HANDLE + }; + + /* Functions that must be implemented from GattServer */ + virtual ble_error_t addService(GattService &); + virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t initializeGATTDatabase(void); + + virtual bool isOnDataReadAvailable() const { + return true; + } + + virtual ble_error_t reset(void); + + /* BlueNRG Functions */ + void eventCallback(void); + //void hwCallback(void *pckt); + ble_error_t Read_Request_CB(uint16_t attributeHandle); + uint8_t Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, + uint8_t data_length, const uint8_t* data + ); + GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle); + void HCIDataWrittenEvent(const GattWriteCallbackParams *params); + void HCIDataReadEvent(const GattReadCallbackParams *params); + void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle); + void HCIDataSentEvent(unsigned count); + +private: + + // compute the number of attribute record needed by a service + static uint16_t computeAttributesRecord(GattService& service); + + + static const int MAX_SERVICE_COUNT = 10; + uint8_t serviceCount; + uint8_t characteristicCount; + uint16_t servHandle, charHandle; + + std::map<uint16_t, uint16_t> bleCharHandleMap; // 1st argument is characteristic, 2nd argument is service + GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS]; + uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS]; + + BlueNRGGattServer() { + serviceCount = 0; + characteristicCount = 0; + }; + + BlueNRGGattServer(BlueNRGGattServer const &); + void operator=(BlueNRGGattServer const &); + + static const int CHAR_DESC_TYPE_16_BIT=0x01; + static const int CHAR_DESC_TYPE_128_BIT=0x02; + static const int CHAR_DESC_SECURITY_PERMISSION=0x00; + static const int CHAR_DESC_ACCESS_PERMISSION=0x03; + static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_CLOCK_H__ +#define __BLE_CLOCK_H__ + +#include <ble_hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __BLE_CLOCK_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file ble_debug.h + * @author CL + * @version V1.0.0 + * @date 04-July-2014 + * @brief This file defines print functions for debug purposes. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLE_DEBUG_H +#define __BLE_DEBUG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> + +/* Exported macro ------------------------------------------------------------*/ +//#define DEBUG +#ifdef DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Print the data travelling over the SPI in the .csv format for the GUI*/ +//#define PRINT_CSV_FORMAT +#ifdef PRINT_CSV_FORMAT +#include <stdio.h> +#define PRINT_CSV(...) printf(__VA_ARGS__) +#else +#define PRINT_CSV(...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __BLE_DEBUG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_gp_timer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : General purpose timer library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_GP_TIMER_H__ +#define __BLE_GP_TIMER_H__ + +#include "ble_clock.h" +#include "ble_status.h" +#ifdef __DMA_LP__ +#include "stm32xx_timerserver.h" +#endif /* __DMA_LP__ */ + +/** + * timer + * + * A structure that represents a timer. Use Timer_Set() to set the timer. + * + */ +struct timer { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + tClockTime start; + tClockTime interval; + +#endif +}; + +typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); + +/** + * Timer_Set + * + * @param[in] t Pointer to a timer structure + * @param[in] interval timeout value + * + * This function sets the timeout value of a timer. + * + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * Timer_Reset + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the time it previously expired. + * + */ +void Timer_Reset(struct timer *t); + +/** + * Timer_Restart + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the current time. + * + */ +void Timer_Restart(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns TRUE if timer is expired, FALSE otherwise. + * + */ +int Timer_Expired(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns the time needed for expiration. + * + * @return Time before timer's expiration. + */ +tClockTime Timer_Remaining(struct timer *t); + +#ifdef __DMA_LP__ +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID); + +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); +#endif /* __DMA_LP__ */ + +#endif /* __BLE_GP_TIMER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,108 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_H__ +#define __BLE_HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void signalEventsToProcess(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __BLE_HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_TYPES_H__ +#define __BLE_HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __BLE_HAL_TYPES_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,126 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.0, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_H_ +#define __BLE_HCI_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ble_hal_types.h" +#include "ble_link_layer.h" +#include <ble_list.h> + +#define HCI_READ_PACKET_SIZE 128 //71 + +/** + * Maximum payload of HCI commands that can be sent. Change this value if needed. + * This value can be up to 255. + */ +#define HCI_MAX_PAYLOAD_SIZE 128 + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_READ_PACKET_SIZE]; + uint8_t data_len; +} tHciDataPacket; + +struct hci_request { + uint16_t ogf; + uint16_t ocf; + int event; + void *cparam; + int clen; + void *rparam; + int rlen; +}; + +typedef enum +{ + BUSY, + AVAILABLE +} HCI_CMD_STATUS_t; + + +/** + * This function must be used to pass the packet received from the HCI + * interface to the BLE Stack HCI state machine. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * + */ +void HCI_Input(tHciDataPacket *hciReadPacket); + +/** + * Initialization function. Must be done before any data can be received from + * BLE controller. + */ +void HCI_Init(void); + +/** + * Callback used to pass events to application. + * + * @param[in] pckt The event. + * + */ +extern void HCI_Event_CB(void *pckt); + +/** + * Processing function that must be called after an event is received from + * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if + * necessary. +*/ +void HCI_Process(void); + +/** + * @brief Check if queue of HCI event is empty or not. + * @note This funtion can be used to check if the event queue from BlueNRG is empty. This + * is useful when checking if it is safe to go to sleep. + * @return TRUE if event queue is empty. FALSE otherwhise. + */ +BOOL HCI_Queue_Empty(void); +/** + * Iterrupt service routine that must be called when the BlueNRG + * reports a packet received or an event to the host through the + * BlueNRG interrupt line. + */ +#ifdef __DMA_LP__ +void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); +void HCI_Process_Notification_Request(void); +void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); +void HCI_Wait_For_Response(void); +#else +void HCI_Isr(void); +void HCI_HandleSPI(void); + +int hci_send_req(struct hci_request *r, BOOL async); +#endif /* __DMA_LP__ */ + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#ifdef __cplusplus +} +#endif + + +#endif /* __BLE_HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,548 @@ +/****************************************************************************** +* +* File Description +* --------------------- +* This file defines constants and functions for HCI layer. +* See Bluetooth Core v 4.0, Vol. 2, Part E. +* +*******************************************************************************/ + +#ifndef __HCI_INTERNAL_H_ +#define __HCI_INTERNAL_H_ + +#include "ble_compiler.h" +#include "ble_hal_types.h" +#include "ble_clock.h" +#include "ble_link_layer.h" +#include "ble_hci.h" + +#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) + + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +typedef __packed struct _hci_uart_pckt{ + uint8_t type; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef __packed struct _hci_command_hdr{ + uint16_t opcode; /* OCF & OGF */ + uint8_t plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef __packed struct _hci_event_pckt{ + uint8_t evt; + uint8_t plen; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef __packed struct _hci_acl_hdr{ + uint16_t handle; /* Handle & Flags(PB, BC) */ + uint16_t dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef __packed struct _disconnect_cp{ + uint16_t handle; + uint8_t reason; +} PACKED disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 + +#define OCF_SET_EVENT_MASK 0x0001 +#define OCF_RESET 0x0003 + +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D +typedef __packed struct _read_transmit_power_level_cp{ + uint16_t handle; + uint8_t type; +} PACKED read_transmit_power_level_cp; +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 +typedef __packed struct _read_transmit_power_level_rp{ + uint8_t status; + uint16_t handle; + int8_t level; +} PACKED read_transmit_power_level_rp; +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 + +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 +#define OCF_HOST_BUFFER_SIZE 0x0033 +#define OCF_HOST_NUM_COMP_PKTS 0x0035 + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef __packed struct _read_local_version_rp{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t manufacturer_name; + uint16_t lmp_pal_subversion; +} PACKED read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_COMMANDS 0x0002 +#define OCF_READ_LOCAL_FEATURES 0x0003 + +#define OCF_READ_BD_ADDR 0x0009 +typedef __packed struct _read_bd_addr_rp{ + uint8_t status; + tBDAddr bdaddr; +} PACKED read_bd_addr_rp; +#define READ_BD_ADDR_RP_SIZE 7 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +#define OCF_READ_RSSI 0x0005 +typedef __packed struct _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef __packed struct _read_rssi_rp{ + uint8_t status; + uint16_t handle; + int8_t rssi; +} PACKED read_rssi_rp; +#define READ_RSSI_RP_SIZE 4 + + +/* LE commands */ +#define OGF_LE_CTL 0x08 + +#define OCF_LE_SET_EVENT_MASK 0x0001 +typedef __packed struct _le_set_event_mask_cp{ + uint8_t mask[8]; +} PACKED le_set_event_mask_cp; +#define LE_SET_EVENT_MASK_CP_SIZE 8 + +#define OCF_LE_READ_BUFFER_SIZE 0x0002 +typedef __packed struct _le_read_buffer_size_rp{ + uint8_t status; + uint16_t pkt_len; + uint8_t max_pkt; +} PACKED le_read_buffer_size_rp; +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 + +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 +typedef __packed struct _le_read_local_supported_features_rp{ + uint8_t status; + uint8_t features[8]; +} PACKED le_read_local_supported_features_rp; +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 + +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 +typedef __packed struct _le_set_random_address_cp{ + tBDAddr bdaddr; +} PACKED le_set_random_address_cp; +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 + +#define OCF_LE_SET_ADV_PARAMETERS 0x0006 +typedef __packed struct _le_set_adv_parameters_cp{ + uint16_t min_interval; + uint16_t max_interval; + uint8_t advtype; + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint8_t chan_map; + uint8_t filter; +} PACKED le_set_adv_parameters_cp; +#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 + +#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 +typedef __packed struct _le_read_adv_channel_tx_power_rp{ + uint8_t status; + int8_t level; +} PACKED le_read_adv_channel_tx_power_rp; +#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 + +#define OCF_LE_SET_ADV_DATA 0x0008 +typedef __packed struct _le_set_adv_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_adv_data_cp; +#define LE_SET_ADV_DATA_CP_SIZE 32 + +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 +typedef __packed struct _le_set_scan_response_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_scan_response_data_cp; +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 + +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A +typedef __packed struct _le_set_advertise_enable_cp{ + uint8_t enable; +} PACKED le_set_advertise_enable_cp; +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 + +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B +typedef __packed struct _le_set_scan_parameters_cp{ + uint8_t type; + uint16_t interval; + uint16_t window; + uint8_t own_bdaddr_type; + uint8_t filter; +} PACKED le_set_scan_parameters_cp; +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 + +#define OCF_LE_SET_SCAN_ENABLE 0x000C +typedef __packed struct _le_set_scan_enable_cp{ + uint8_t enable; + uint8_t filter_dup; +} PACKED le_set_scan_enable_cp; +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 + +#define OCF_LE_CREATE_CONN 0x000D +typedef __packed struct _le_create_connection_cp{ + uint16_t interval; + uint16_t window; + uint8_t initiator_filter; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_create_connection_cp; +#define LE_CREATE_CONN_CP_SIZE 25 + +#define OCF_LE_CREATE_CONN_CANCEL 0x000E + +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F +typedef __packed struct _le_read_white_list_size_rp{ + uint8_t status; + uint8_t size; +} PACKED le_read_white_list_size_rp; +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 + +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 +typedef __packed struct _le_add_device_to_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_add_device_to_white_list_cp; +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 +typedef __packed struct _le_remove_device_from_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_remove_device_from_white_list_cp; +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_CONN_UPDATE 0x0013 +typedef __packed struct _le_connection_update_cp{ + uint16_t handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_connection_update_cp; +#define LE_CONN_UPDATE_CP_SIZE 14 + +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 +typedef __packed struct _le_set_host_channel_classification_cp{ + uint8_t map[5]; +} PACKED le_set_host_channel_classification_cp; +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 + +#define OCF_LE_READ_CHANNEL_MAP 0x0015 +typedef __packed struct _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef __packed struct _le_read_channel_map_rp{ + uint8_t status; + uint16_t handle; + uint8_t map[5]; +} PACKED le_read_channel_map_rp; +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 + +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 +typedef __packed struct _le_read_remote_used_features_cp{ + uint16_t handle; +} PACKED le_read_remote_used_features_cp; +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 + +#define OCF_LE_ENCRYPT 0x0017 +typedef __packed struct _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef __packed struct _le_encrypt_rp{ + uint8_t status; + uint8_t encdata[16]; +} PACKED le_encrypt_rp; +#define LE_ENCRYPT_RP_SIZE 17 + +#define OCF_LE_RAND 0x0018 +typedef __packed struct _le_rand_rp{ + uint8_t status; + uint8_t random[8]; +} PACKED le_rand_rp; +#define LE_RAND_RP_SIZE 9 + +#define OCF_LE_START_ENCRYPTION 0x0019 +typedef __packed struct _le_start_encryption_cp{ + uint16_t handle; + uint8_t random[8]; + uint16_t diversifier; + uint8_t key[16]; +} PACKED le_start_encryption_cp; +#define LE_START_ENCRYPTION_CP_SIZE 28 + +#define OCF_LE_LTK_REPLY 0x001A +typedef __packed struct _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef __packed struct _le_ltk_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_reply_rp; +#define LE_LTK_REPLY_RP_SIZE 3 + +#define OCF_LE_LTK_NEG_REPLY 0x001B +typedef __packed struct _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef __packed struct _le_ltk_neg_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_neg_reply_rp; +#define LE_LTK_NEG_REPLY_RP_SIZE 3 + +#define OCF_LE_READ_SUPPORTED_STATES 0x001C +typedef __packed struct _le_read_supported_states_rp{ + uint8_t status; + uint8_t states[8]; +} PACKED le_read_supported_states_rp; +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 + +#define OCF_LE_RECEIVER_TEST 0x001D +typedef __packed struct _le_receiver_test_cp{ + uint8_t frequency; +} PACKED le_receiver_test_cp; +#define LE_RECEIVER_TEST_CP_SIZE 1 + +#define OCF_LE_TRANSMITTER_TEST 0x001E +typedef __packed struct _le_transmitter_test_cp{ + uint8_t frequency; + uint8_t length; + uint8_t payload; +} PACKED le_transmitter_test_cp; +#define LE_TRANSMITTER_TEST_CP_SIZE 3 + +#define OCF_LE_TEST_END 0x001F +typedef __packed struct _le_test_end_rp{ + uint8_t status; + uint16_t num_pkts; +} PACKED le_test_end_rp; +#define LE_TEST_END_RP_SIZE 3 + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3f + + +/*------------- Events -------------*/ +#define EVT_CONN_COMPLETE 0x03 +typedef __packed struct _evt_conn_complete{ + uint8_t status; + uint16_t handle; + tBDAddr bdaddr; + uint8_t link_type; + uint8_t encr_mode; +} PACKED evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef __packed struct _evt_disconn_complete{ + uint8_t status; + uint16_t handle; + uint8_t reason; +} PACKED evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef __packed struct _evt_encrypt_change{ + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} PACKED evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C + +#define EVT_CMD_COMPLETE 0x0E +typedef __packed struct _evt_cmd_complete{ + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef __packed struct _evt_cmd_status{ + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef __packed struct _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef __packed struct _evt_num_comp_pkts{ + uint8_t num_hndl; + /* variable length part */ +} PACKED evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +/* variable length part of evt_num_comp_pkts. */ +typedef __packed struct _evt_num_comp_pkts_param{ + uint16_t hndl; + uint16_t num_comp_pkts; +} PACKED evt_num_comp_pkts_param; +#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 + +#define EVT_DATA_BUFFER_OVERFLOW 0x1A +typedef __packed struct _evt_data_buffer_overflow{ + uint8_t link_type; +} PACKED evt_data_buffer_overflow; +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 + +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef __packed struct _evt_encryption_key_refresh_complete{ + uint8_t status; + uint16_t handle; +} PACKED evt_encryption_key_refresh_complete; +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 + +#define EVT_LE_META_EVENT 0x3E +typedef __packed struct _evt_le_meta_event{ + uint8_t subevent; + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef __packed struct _evt_le_connection_complete{ + uint8_t status; + uint16_t handle; + uint8_t role; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; +} PACKED evt_le_connection_complete; +#define EVT_LE_CONN_COMPLETE_SIZE 18 + +#define EVT_LE_ADVERTISING_REPORT 0x02 +typedef __packed struct _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t data_length; + uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef __packed struct _evt_le_connection_update_complete{ + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; +} PACKED evt_le_connection_update_complete; +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 + +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +typedef __packed struct _evt_le_read_remote_used_features_complete{ + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} PACKED evt_le_read_remote_used_features_complete; +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 + +#define EVT_LE_LTK_REQUEST 0x05 +typedef __packed struct _evt_le_long_term_key_request{ + uint16_t handle; + uint8_t random[8]; + uint16_t ediv; +} PACKED evt_le_long_term_key_request; +#define EVT_LE_LTK_REQUEST_SIZE 12 + +/** +* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, +* application can use @ref evt_blue_aci structure to parse the packet. +*/ +#define EVT_VENDOR 0xFF + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + + + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); + +typedef enum { + WAITING_TYPE, + WAITING_OPCODE1, + WAITING_OPCODE2, + WAITING_EVENT_CODE, + WAITING_HANDLE, + WAITING_HANDLE_FLAG, + WAITING_PARAM_LEN, + WAITING_DATA_LEN1, + WAITING_DATA_LEN2, + WAITING_PAYLOAD +}hci_state; + +typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); + +/* HCI library functions. */ + +int hci_send_req(struct hci_request *r, BOOL async); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,170 @@ +/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +* File Name : ble_hci_le.h +* Author : AMG RF FW team +* Version : V1.1.0 +* Date : 18-July-2016 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.1, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_LE_H_ +#define __BLE_HCI_LE_H_ + +#include "ble_hal_types.h" +#include "ble_link_layer.h" + +/** + * @defgroup HCI_Error_codes HCI Error codes + * @{ + */ +#define HCI_UNKNOWN_COMMAND 0x01 +#define HCI_NO_CONNECTION 0x02 +#define HCI_HARDWARE_FAILURE 0x03 +#define HCI_PAGE_TIMEOUT 0x04 +#define HCI_AUTHENTICATION_FAILURE 0x05 +#define HCI_PIN_OR_KEY_MISSING 0x06 +#define HCI_MEMORY_FULL 0x07 +#define HCI_CONNECTION_TIMEOUT 0x08 +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a +#define HCI_ACL_CONNECTION_EXISTS 0x0b +#define HCI_COMMAND_DISALLOWED 0x0c +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d +#define HCI_REJECTED_SECURITY 0x0e +#define HCI_REJECTED_PERSONAL 0x0f +#define HCI_HOST_TIMEOUT 0x10 +#define HCI_UNSUPPORTED_FEATURE 0x11 +#define HCI_INVALID_PARAMETERS 0x12 +#define HCI_OE_USER_ENDED_CONNECTION 0x13 +#define HCI_OE_LOW_RESOURCES 0x14 +#define HCI_OE_POWER_OFF 0x15 +#define HCI_CONNECTION_TERMINATED 0x16 +#define HCI_REPEATED_ATTEMPTS 0x17 +#define HCI_PAIRING_NOT_ALLOWED 0x18 +#define HCI_UNKNOWN_LMP_PDU 0x19 +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a +#define HCI_SCO_OFFSET_REJECTED 0x1b +#define HCI_SCO_INTERVAL_REJECTED 0x1c +#define HCI_AIR_MODE_REJECTED 0x1d +#define HCI_INVALID_LMP_PARAMETERS 0x1e +#define HCI_UNSPECIFIED_ERROR 0x1f +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 +#define HCI_UNIT_LINK_KEY_USED 0x26 +#define HCI_QOS_NOT_SUPPORTED 0x27 +#define HCI_INSTANT_PASSED 0x28 +#define HCI_PAIRING_NOT_SUPPORTED 0x29 +#define HCI_TRANSACTION_COLLISION 0x2a +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c +#define HCI_QOS_REJECTED 0x2d +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e +#define HCI_INSUFFICIENT_SECURITY 0x2f +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 +#define HCI_ROLE_SWITCH_PENDING 0x32 +#define HCI_SLOT_VIOLATION 0x34 +#define HCI_ROLE_SWITCH_FAILED 0x35 +#define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 +#define HCI_CONN_REJ_NO_CH_FOUND 0x39 +#define HCI_CONTROLLER_BUSY 0x3A +#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B +#define HCI_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_CONN_TERM_MIC_FAIL 0x3D +#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E +#define HCI_MAC_CONN_FAILED 0x3F +/** + * @} + */ + + +/* + * HCI library functions. + * Each function returns 0 in case of success, otherwise one of the error codes. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(uint8_t enable); + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter); + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter); + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); + +int hci_le_rand(uint8_t random_number[8]); + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); + +int hci_acl_data(const uint8_t * data, uint16_t len); + +int hci_le_set_random_address(tBDAddr bdaddr); + +int hci_read_bd_addr(tBDAddr bdaddr); + +int hci_le_read_white_list_size(uint8_t *size); + +int hci_le_clear_white_list(); + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); + +int hci_le_ltk_request_reply(uint8_t key[16]); + +int hci_le_ltk_request_neg_reply(); + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); + +int hci_le_create_connection_cancel(void); + +int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level); + +int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi); + +int hci_le_read_local_supported_features(uint8_t *features); + +int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); + +int hci_le_read_supported_states(uint8_t states[8]); + +int hci_le_receiver_test(uint8_t frequency); + +int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); + +int hci_le_test_end(uint16_t *num_pkts); + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion); + + + +#endif /* __BLE_HCI_LE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,161 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_link_layer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's link layer. It contains +* definition of functions for link layer, most of which are +* mapped to HCI commands. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef _BLE_LINK_LAYER_H +#define _BLE_LINK_LAYER_H + +#include <ble_status.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + *@name Advertising filter + *Advertising policy for filtering (white list related) + *@{ + */ +#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ +#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ +/** + * @} + */ + + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef uint8_t tBDAddr[6]; + + +/** + *@name Bluetooth address types + * Bluetooth address types + *@{ + */ +#define PUBLIC_ADDR (0) +#define RANDOM_ADDR (1) +#define STATIC_RANDOM_ADDR (1) +#define RESOLVABLE_PRIVATE_ADDR (2) +#define NON_RESOLVABLE_PRIVATE_ADDR (3) +/** + * @} + */ + +/** + *@name Directed advertising types + * Type of advertising during directed advertising + *@{ + */ +#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) +#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) +/** + * @} + */ + +/** + * @name Advertising type + * @{ + */ + +/** + * undirected scannable and connectable + */ +#define ADV_IND (0x00) + +/** + * directed non scannable + */ +#define ADV_DIRECT_IND (0x01) + +/** + * scannable non connectable + */ +#define ADV_SCAN_IND (0x02) + +/** + * non-connectable and no scan response + */ +#define ADV_NONCONN_IND (0x03) + +/** + * scan response + */ +#define SCAN_RSP (0x04) + +/** + * @} + */ + +/* 0X05-0XFF RESERVED */ + +/** + * @name Advertising ranges + * @{ + */ + +/** + * lowest allowed interval value for connectable types(20ms)..multiple of 625us + */ +#define ADV_INTERVAL_LOWEST_CONN (0X0020) + +/** + * highest allowed interval value (10.24s)..multiple of 625us. + */ +#define ADV_INTERVAL_HIGHEST (0X4000) + +/** + * lowest allowed interval value for non connectable types + * (100ms)..multiple of 625us. + */ +#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) + +/** + * @} + */ + +/** + * @name Advertising channels + * @{ + */ +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 +/** + * @} + */ + +/** + * @name Scan_types Scan types + * @{ + */ +#define PASSIVE_SCAN 0 +#define ACTIVE_SCAN 1 +/** + * @} + */ + +/** + * @} + */ + + +#endif /* _BLE_LINK_LAYER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,47 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for linked list library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef _BLE_LIST_H_ +#define _BLE_LIST_H_ + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +uint8_t list_is_empty (tListNode * listHead); + +void list_insert_head (tListNode * listHead, tListNode * node); + +void list_insert_tail (tListNode * listHead, tListNode * node); + +void list_remove_node (tListNode * node); + +void list_remove_head (tListNode * listHead, tListNode ** node ); + +void list_remove_tail (tListNode * listHead, tListNode ** node ); + +void list_insert_node_after (tListNode * node, tListNode * ref_node); + +void list_insert_node_before (tListNode * node, tListNode * ref_node); + +int list_get_size (tListNode * listHead); + +void list_get_next_node (tListNode * ref_node, tListNode ** node); + +void list_get_prev_node (tListNode * ref_node, tListNode ** node); + +#endif /* _BLE_LIST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_OSAL_H__ +#define __BLE_OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __BLE_OSAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,158 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_sm.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's security manager. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_SM_H__ +#define __BLE_SM_H__ + +/****************************************************************************** +* Macros +*****************************************************************************/ + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/* IO capabilities */ +/** + * @anchor IO_capabilities + * @name IO capabilities + * @{ + */ +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define IO_CAP_KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) +/** + * @} + */ + +/** + * @anchor Auth_req + * @name Authentication requirements + * @{ + */ +#define BONDING (0x01) +#define NO_BONDING (0x00) +/** + * @} + */ + +/** + * @anchor MITM_req + * @name MITM protection requirements + * @{ + */ +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor OOB_Data + * @name Out-Of-Band data + * @{ + */ +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) +/** + * @} + */ + +/** + * @anchor Author_req + * @name Authorization requirements + * @{ + */ +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor Conn_authorization + * @name Connection authorization + * @{ + */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) +/** + * @} + */ + +/** + * @anchor Use_fixed_pin + * @name Use fixed pin + * @{ + */ +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +/** + * @} + */ + +/** + * @anchor link_security_status + * @name Link security status + * @{ + */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) +/** + * @} + */ + +/** + * @anchor SMP_pairing_failed_codes + * @name SMP pairing failed reason codes + * @{ + */ +#define PASSKEY_ENTRY_FAILED (0x01) +#define OOB_NOT_AVAILABLE (0x02) +#define AUTH_REQ_CANNOT_BE_MET (0x03) +#define CONFIRM_VALUE_FAILED (0x04) +#define PAIRING_NOT_SUPPORTED (0x05) +#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) +#define CMD_NOT_SUPPORTED (0x07) +#define UNSPECIFIED_REASON (0x08) +#define VERY_EARLY_NEXT_ATTEMPT (0x09) +#define SM_INVALID_PARAMS (0x0A) +/** + * @} + */ + +/** + * @anchor pairing_failed_codes + * @name Pairing failed error codes + * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event + * @{ + */ +#define SM_PAIRING_SUCCESS (0x00) +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,188 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_status.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file with BLE Stack status codes. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_STATUS_H__ +#define __BLE_STATUS_H__ + +#include <ble_hal_types.h> + +/** @addtogroup Middlewares + * @{ + */ + +/** @defgroup ST + * @{ + */ + +/** @defgroup SimpleBlueNRG_HCI + * @{ + */ + +/** @defgroup ble_status Bluetooth Status/Error Codes + * @{ + */ + +typedef uint8_t tBleStatus; + +/* Error Codes as specified by the specification + * according to the spec the error codes range + * from 0x00 to 0x3F + */ +/** + * @name Standard error codes + * @brief Standard error codes. See Core v 4.1, Vol. 2, part D. + * @{ + */ +#define ERR_CMD_SUCCESS (0x00) +#define BLE_STATUS_SUCCESS (0x00) +#define ERR_UNKNOWN_HCI_COMMAND (0x01) +#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) + +#define ERR_AUTH_FAILURE (0x05) +#define ERR_PIN_OR_KEY_MISSING (0x06) +#define ERR_MEM_CAPACITY_EXCEEDED (0x07) +#define ERR_CONNECTION_TIMEOUT (0x08) + +#define ERR_COMMAND_DISALLOWED (0x0C) + +#define ERR_UNSUPPORTED_FEATURE (0x11) +#define ERR_INVALID_HCI_CMD_PARAMS (0x12) +#define ERR_RMT_USR_TERM_CONN (0x13) +#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) +#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) +#define ERR_LOCAL_HOST_TERM_CONN (0x16) + +#define ERR_UNSUPP_RMT_FEATURE (0x1A) + +#define ERR_INVALID_LMP_PARAM (0x1E) +#define ERR_UNSPECIFIED_ERROR (0x1F) + +#define ERR_LL_RESP_TIMEOUT (0x22) +#define ERR_LMP_PDU_NOT_ALLOWED (0x24) + +#define ERR_INSTANT_PASSED (0x28) + +#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) +#define ERR_CONTROLLER_BUSY (0x3A) + +#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) + +#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) + +#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) + + +/** + * @} + */ +/** + * @name Vendor-specific error codes + * @brief Error codes defined by ST related to BlueNRG stack + * @{ + */ +/** + * The command cannot be executed due to the current state of the device. + */ +#define BLE_STATUS_FAILED (0x41) +/** + * Some parameters are invalid. + */ +#define BLE_STATUS_INVALID_PARAMS (0x42) +/** + * It is not allowed to start the procedure (e.g. another the procedure is ongoing + * or cannot be started on the given handle). + */ +#define BLE_STATUS_NOT_ALLOWED (0x46) +/** + * Unexpected error. + */ +#define BLE_STATUS_ERROR (0x47) +#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) + +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +#define BLE_STATUS_INVALID_CID (0x50) + +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) +#define BLE_STATUS_IRK_NOT_FOUND (0x5B) +#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) +#define BLE_STATUS_SEC_DB_FULL (0x5D) +#define BLE_STATUS_DEV_NOT_BONDED (0x5E) +#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) + +#define BLE_STATUS_INVALID_HANDLE (0x60) +#define BLE_STATUS_INVALID_PARAMETER (0x61) +#define BLE_STATUS_OUT_OF_HANDLE (0x62) +#define BLE_STATUS_INVALID_OPERATION (0x63) +#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) +#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) +#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) + +/** + * Returned when no valid slots are available (e.g. when there are no available state machines). + */ +#define BLE_STATUS_NO_VALID_SLOT (0x82) + +/** + * Returned when a scan window shorter than minimum allowed value has been requested (i.e. 2ms) + */ + +#define BLE_STATUS_SCAN_WINDOW_SHORT (0x83) +/** + * Returned when the maximum requested interval to be allocated is shorter then the current + * anchor period and a there is no submultiple for the current anchor period that is between + * the minimum and the maximum requested intervals. + */ + +#define BLE_STATUS_NEW_INTERVAL_FAILED (0x84) +/** + * Returned when the maximum requested interval to be allocated is greater than the current anchor + * period and there is no multiple of the anchor period that is between the minimum and the maximum + * requested intervals. + */ + +#define BLE_STATUS_INTERVAL_TOO_LARGE (0x85) +/** + * Returned when the current anchor period or a new one can be found that is compatible to the + * interval range requested by the new slot but the maximum available length that can be allocated is + * less than the minimum requested slot length. + */ + +#define BLE_STATUS_LENGTH_FAILED (0x86) +/** + * @} + */ + +/** + * @name Library Error Codes + * @brief Error codes defined by ST related to MCU library. + * @{ + */ +#define BLE_STATUS_TIMEOUT (0xFF) +#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) +#define BLE_STATUS_NULL_PARAM (0xF1) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,813 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci_const.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with ACI definitions for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_CONST_H_ +#define __BLUENRG_ACI_CONST_H_ + +#include "ble_compiler.h" +#include "ble_link_layer.h" +#include "ble_hci_const.h" +#include "bluenrg_gatt_server.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define OCF_HAL_GET_FW_BUILD_NUMBER 0x0000 +typedef __packed struct _hal_get_fw_build_number_rp{ + uint8_t status; + uint16_t build_number; +} PACKED hal_get_fw_build_number_rp; +#define HAL_GET_FW_BUILD_NUMBER_RP_SIZE 3 +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +#define OCF_HAL_READ_CONFIG_DATA 0x000D +typedef __packed struct _hal_read_config_data_cp{ + uint8_t offset; +} PACKED hal_read_config_data_cp; +#define HAL_READ_CONFIG_DATA_RP_SIZE 1 +typedef __packed struct _hal_read_config_data_rp{ + uint8_t status; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE]; +} PACKED hal_read_config_data_rp; + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef __packed struct _hal_set_tx_power_level_cp{ + uint8_t en_high_power; + uint8_t pa_level; +} PACKED hal_set_tx_power_level_cp; +#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 + +#define OCF_HAL_DEVICE_STANDBY 0x0013 + +#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014 +typedef __packed struct _hal_le_tx_test_packet_number_rp{ + uint8_t status; + uint32_t number_of_packets; +} PACKED hal_le_tx_test_packet_number_rp; + +#define OCF_HAL_TONE_START 0x0015 +typedef __packed struct _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_HAL_TONE_STOP 0x0016 +#define OCF_HAL_GET_LINK_STATUS 0x0017 +typedef __packed struct _hal_get_link_status_rp{ + uint8_t status; + uint8_t link_status[8]; + uint16_t conn_handle[8]; +} PACKED hal_get_link_status_rp; + +#define OCF_HAL_GET_ANCHOR_PERIOD 0x0019 +typedef __packed struct _hal_get_anchor_period_rp{ + uint8_t status; + uint32_t anchor_period; + uint32_t max_free_slot; +} PACKED hal_get_anchor_period_rp; + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef __packed struct _get_updater_version_rp{ + uint8_t status; + uint8_t version; +} PACKED get_updater_version_rp; +#define GET_UPDATER_VERSION_RP_SIZE 2 + +#define OCF_GET_UPDATER_BUFSIZE 0x0023 +typedef __packed struct _get_updater_bufsize_rp{ + uint8_t status; + uint8_t buffer_size; +} PACKED get_updater_bufsize_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 + +#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 + +#define OCF_UPDATER_ERASE_SECTOR 0x0026 +typedef __packed struct _updater_erase_sector_cp{ + uint32_t address; +} PACKED updater_erase_sector_cp; +#define UPDATER_ERASE_SECTOR_CP_SIZE 4 + +#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 +#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_prog_data_block_cp{ + uint32_t address; + uint16_t data_len; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; +} PACKED updater_prog_data_block_cp; + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef __packed struct _updater_read_data_block_cp{ + uint32_t address; + uint16_t data_len; +} PACKED updater_read_data_block_cp; +#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[VARIABLE_SIZE]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef __packed struct _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef __packed struct _updater_calc_crc_rp{ + uint8_t status; + uint32_t crc; +} PACKED updater_calc_crc_rp; +#define UPDATER_CALC_CRC_RP_SIZE 5 + +#define OCF_UPDATER_HW_VERSION 0x002A +typedef __packed struct _updater_hw_version_rp{ + uint8_t status; + uint8_t version; +} PACKED updater_hw_version_rp; +#define UPDATER_HW_VERSION_RP_SIZE 2 + +#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 + +#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 + +#define OCF_GAP_SET_DISCOVERABLE 0x0083 + +#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 +typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ + uint8_t own_bdaddr_type; + uint8_t directed_adv_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint16_t adv_interv_min; + uint16_t adv_interv_max; +} PACKED gap_set_direct_conectable_cp_IDB05A1; + +typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB04A1; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef __packed struct _gap_set_io_capability_cp{ + uint8_t io_capability; +} PACKED gap_set_io_capability_cp; +#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 + +#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 +typedef __packed struct _gap_set_auth_requirement_cp{ + uint8_t mitm_mode; + uint8_t oob_enable; + uint8_t oob_data[16]; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t bonding_mode; +} PACKED gap_set_auth_requirement_cp; +#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 + +#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 +typedef __packed struct _gap_set_author_requirement_cp{ + uint16_t conn_handle; + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef __packed struct _gap_passkey_response_cp{ + uint16_t conn_handle; + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef __packed struct _gap_authorization_response_cp{ + uint16_t conn_handle; + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 + +#define OCF_GAP_INIT 0x008A +typedef __packed struct _gap_init_cp_IDB05A1{ + uint8_t role; + uint8_t privacy_enabled; + uint8_t device_name_char_len; +} PACKED gap_init_cp_IDB05A1; +#define GAP_INIT_CP_SIZE_IDB05A1 3 + +typedef __packed struct _gap_init_cp_IDB04A1{ + uint8_t role; +} PACKED gap_init_cp_IDB04A1; +#define GAP_INIT_CP_SIZE_IDB04A1 1 +typedef __packed struct _gap_init_rp{ + uint8_t status; + uint16_t service_handle; + uint16_t dev_name_char_handle; + uint16_t appearance_char_handle; +} PACKED gap_init_rp; +#define GAP_INIT_RP_SIZE 7 + +#define OCF_GAP_SET_NON_CONNECTABLE 0x008B +typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ + uint8_t advertising_event_type; + uint8_t own_address_type; +#endif +} PACKED gap_set_non_connectable_cp_IDB05A1; + +typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp_IDB04A1; + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef __packed struct _gap_set_undirected_connectable_cp{ + uint8_t adv_filter_policy; + uint8_t own_addr_type; +} PACKED gap_set_undirected_connectable_cp; +#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 + +#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D +typedef __packed struct _gap_slave_security_request_cp{ + uint16_t conn_handle; + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef __packed struct _gap_delete_ad_type_cp{ + uint8_t ad_type; +} PACKED gap_delete_ad_type_cp; +#define GAP_DELETE_AD_TYPE_CP_SIZE 1 + +#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 +typedef __packed struct _gap_get_security_level_rp{ + uint8_t status; + uint8_t mitm_protection; + uint8_t bonding; + uint8_t oob_data; + uint8_t passkey_required; +} PACKED gap_get_security_level_rp; +#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 + +#define OCF_GAP_SET_EVT_MASK 0x0091 +typedef __packed struct _gap_set_evt_mask_cp{ + uint16_t evt_mask; +} PACKED gap_set_evt_mask_cp; +#define GAP_SET_EVT_MASK_CP_SIZE 2 + +#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 + +#define OCF_GAP_TERMINATE 0x0093 +typedef __packed struct _gap_terminate_cp{ + uint16_t handle; + uint8_t reason; +} PACKED gap_terminate_cp; +#define GAP_TERMINATE_CP_SIZE 3 + +#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 + +#define OCF_GAP_ALLOW_REBOND_DB 0x0095 + +typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ + uint16_t conn_handle; +} PACKED gap_allow_rebond_cp_IDB05A1; + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef __packed struct _gap_start_limited_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_limited_discovery_proc_cp; +#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 +typedef __packed struct _gap_start_general_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_general_discovery_proc_cp; +#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 +typedef __packed struct _gap_start_name_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_name_discovery_proc_cp; +#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 + +#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 + +#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; + +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t use_reconn_addr; + tBDAddr reconn_addr; +} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; + +#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B +#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 +typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t num_whitelist_entries; + uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; +} PACKED gap_start_selective_conn_establish_proc_cp; + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef __packed struct _gap_create_connection_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_create_connection_cp; +#define GAP_CREATE_CONNECTION_CP_SIZE 24 + +#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D + +#define OCF_GAP_START_CONNECTION_UPDATE 0x009E +typedef __packed struct _gap_start_connection_update_cp{ + uint16_t conn_handle; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_connection_update_cp; +#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 + +#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F +typedef __packed struct _gap_send_pairing_request_cp{ + uint16_t conn_handle; + uint8_t force_rebond; +} PACKED gap_send_pairing_request_cp; +#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 + +#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 +typedef __packed struct _gap_resolve_private_address_cp{ + tBDAddr address; +} PACKED gap_resolve_private_address_cp; +#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 +typedef __packed struct _gap_resolve_private_address_rp{ + uint8_t status; + tBDAddr address; +} PACKED gap_resolve_private_address_rp; + +#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 +#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 +typedef __packed struct _gap_set_broadcast_mode_cp{ + uint16_t adv_interv_min; + uint16_t adv_interv_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; +} PACKED gap_set_broadcast_mode_cp; + +#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 +typedef __packed struct _gap_start_observation_proc_cp{ + uint16_t scan_interval; + uint16_t scan_window; + uint8_t scan_type; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_observation_proc_cp; + +#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 +typedef __packed struct _gap_get_bonded_devices_rp{ + uint8_t status; + uint8_t num_addr; + uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; +} PACKED gap_get_bonded_devices_rp; + +#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 +typedef __packed struct _gap_is_device_bonded_cp{ + uint8_t peer_address_type; + tBDAddr peer_address; +} PACKED gap_is_device_bonded_cp; + + +#define OCF_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef __packed struct _gatt_add_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_serv_rp; +#define GATT_ADD_SERV_RP_SIZE 3 + +#define OCF_GATT_INCLUDE_SERV 0x0103 +typedef __packed struct _gatt_include_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_include_serv_rp; +#define GATT_INCLUDE_SERV_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR 0x0104 +typedef __packed struct _gatt_add_char_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_rp; +#define GATT_ADD_CHAR_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR_DESC 0x0105 +typedef __packed struct _gatt_add_char_desc_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_desc_rp; +#define GATT_ADD_CHAR_DESC_RP_SIZE 3 + +#define OCF_GATT_UPD_CHAR_VAL 0x0106 + +#define OCF_GATT_DEL_CHAR 0x0107 +typedef __packed struct _gatt_del_char_cp{ + uint16_t service_handle; + uint16_t char_handle; +} PACKED gatt_del_char_cp; +#define GATT_DEL_CHAR_CP_SIZE 4 + +#define OCF_GATT_DEL_SERV 0x0108 +typedef __packed struct _gatt_del_serv_cp{ + uint16_t service_handle; +} PACKED gatt_del_serv_cp; +#define GATT_DEL_SERV_CP_SIZE 2 + +#define OCF_GATT_DEL_INC_SERV 0x0109 +typedef __packed struct _gatt_del_inc_serv_cp{ + uint16_t service_handle; + uint16_t inc_serv_handle; +} PACKED gatt_del_inc_serv_cp; +#define GATT_DEL_INC_SERV_CP_SIZE 4 + +#define OCF_GATT_SET_EVT_MASK 0x010A +typedef __packed struct _gatt_set_evt_mask_cp{ + uint32_t evt_mask; +} PACKED gatt_set_evt_mask_cp; +#define GATT_SET_EVT_MASK_CP_SIZE 4 + +#define OCF_GATT_EXCHANGE_CONFIG 0x010B +typedef __packed struct _gatt_exchange_config_cp{ + uint16_t conn_handle; +} PACKED gatt_exchange_config_cp; +#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 + +#define OCF_ATT_FIND_INFO_REQ 0x010C +typedef __packed struct _att_find_info_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED att_find_info_req_cp; +#define ATT_FIND_INFO_REQ_CP_SIZE 6 + +#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D +#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 +typedef __packed struct _att_find_by_type_value_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[2]; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU - 7]; +} PACKED att_find_by_type_value_req_cp; + +#define OCF_ATT_READ_BY_TYPE_REQ 0x010E +#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_type_req_cp; + +#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F +#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_group_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_group_type_req_cp; + +#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 +#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val +typedef __packed struct _att_prepare_write_req_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t value_offset; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU-5]; +} PACKED att_prepare_write_req_cp; + +#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 +typedef __packed struct _att_execute_write_req_cp{ + uint16_t conn_handle; + uint8_t execute; +} PACKED att_execute_write_req_cp; +#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 + +#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 +typedef __packed struct _gatt_disc_all_prim_serivces_cp{ + uint16_t conn_handle; +} PACKED gatt_disc_all_prim_services_cp; +#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 + +#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 +typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ + uint16_t conn_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_disc_prim_service_by_uuid_cp; +#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid + +#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 +typedef __packed struct _gatt_disc_find_included_services_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED gatt_find_included_services_cp; +#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 + +#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 +typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ + uint16_t conn_handle; + uint16_t start_attr_handle; + uint16_t end_attr_handle; +} PACKED gatt_disc_all_charac_of_serv_cp; +#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 + +#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 + +#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ + uint16_t conn_handle; + uint16_t char_val_handle; + uint16_t char_end_handle; +} PACKED gatt_disc_all_charac_descriptors_cp; +#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 + +#define OCF_GATT_READ_CHARAC_VAL 0x0118 +typedef __packed struct _gatt_read_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_val_cp; +#define GATT_READ_CHARAC_VAL_CP_SIZE 4 + +#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 +typedef __packed struct _gatt_read_using_charac_uuid_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_read_using_charac_uuid_cp; +#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID + +#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A +typedef __packed struct _gatt_read_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_val_cp; +#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 + +#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B +#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles +typedef __packed struct _gatt_read_multiple_charac_val_cp{ + uint16_t conn_handle; + uint8_t num_handles; + uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_read_multiple_charac_val_cp; + +#define OCF_GATT_WRITE_CHAR_VALUE 0x011C + +#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D +#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_write_long_charac_val_cp; + +#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E +#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_charac_reliable_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; +} PACKED gatt_write_charac_reliable_cp; + +#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F +#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; +} PACKED gatt_write_long_charac_desc_cp; + +#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 +typedef __packed struct _gatt_read_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_desc_cp; +#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 + +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 +typedef __packed struct _gatt_read_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_desc_cp; +#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 +#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 3]; +} PACKED gatt_write_without_resp_cp; + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 +#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_signed_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 13]; +} PACKED gatt_signed_write_without_resp_cp; + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 +typedef __packed struct _gatt_confirm_indication_cp{ + uint16_t conn_handle; +} PACKED gatt_confirm_indication_cp; +#define GATT_CONFIRM_INDICATION_CP_SIZE 2 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef __packed struct _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 +typedef __packed struct _gatt_set_security_permission_cp{ + uint16_t service_handle; + uint16_t attr_handle; + uint8_t security_permission; +} PACKED gatt_set_security_permission_cp; +#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_GATT_READ_HANDLE_VALUE 0x012A +typedef __packed struct _gatt_read_handle_val_cp{ + uint16_t attr_handle; +} PACKED gatt_read_handle_val_cp; +#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 +typedef __packed struct _gatt_read_handle_val_rp{ + uint8_t status; + uint16_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; +} PACKED gatt_read_handle_val_rp; + +#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B +typedef __packed struct _gatt_read_handle_val_offset_cp{ + uint16_t attr_handle; + uint8_t offset; +} PACKED gatt_read_handle_val_offset_cp; +#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 +typedef __packed struct _gatt_read_handle_val_offset_rp{ + uint8_t status; + uint8_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; +} PACKED gatt_read_handle_val_offset_rp; + +#define OCF_GATT_UPD_CHAR_VAL_EXT 0x012C +#define GATT_UPD_CHAR_VAL_EXT_CP_SIZE 10 // without value +typedef __packed struct _gatt_upd_char_val_ext_cp{ + uint16_t service_handle; + uint16_t char_handle; + uint8_t update_type; + uint16_t char_length; + uint16_t value_offset; + uint8_t value_length; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_UPD_CHAR_VAL_EXT_CP_SIZE]; +} PACKED gatt_upd_char_val_ext_cp; + +#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 +typedef __packed struct _l2cap_conn_param_update_req_cp{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_update_req_cp; +#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 + +#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint16_t min_ce_length; + uint16_t max_ce_length; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; + +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; + +/** + * @defgroup BlueNRG_Events BlueNRG events (vendor specific) + * @{ + */ + +/** + * Vendor specific event for BlueNRG. + */ +typedef __packed struct _evt_blue_aci{ + uint16_t ecode; /**< One of the BlueNRG event codes. */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_blue_aci; + + +/** + * @} + */ + +#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gap.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GAP layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BNRG_GAP_H__ +#define __BNRG_GAP_H__ + +#include <ble_link_layer.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + * @name GAP UUIDs + * @{ + */ +#define GAP_SERVICE_UUID (0x1800) +#define DEVICE_NAME_UUID (0x2A00) +#define APPEARANCE_UUID (0x2A01) +#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) +#define RECONNECTION_ADDR_UUID (0x2A03) +#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) +/** + * @} + */ + +/** + * @name Characteristic value lengths + * @{ + */ +#define DEVICE_NAME_CHARACTERISTIC_LEN (8) +#define APPEARANCE_CHARACTERISTIC_LEN (2) +#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) +#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) +#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) +/** + * @} + */ + +/*------------- AD types for adv data and scan response data ----------------*/ + +/** + * @defgroup AD_Types AD Types + * @brief AD Types + * @{ + */ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +/** + * @anchor Flags_AD_Type_bits + * @name Flags AD Type bits + * @brief Bits in Flags AD Type + * @{ + */ +#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) +#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) +#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) +#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) +#define FLAG_BIT_LE_BR_EDR_HOST (0x10) +/** + * @} + */ + +/** + * @name Service UUID AD types + * @{ + */ +#define AD_TYPE_16_BIT_SERV_UUID (0x02) +#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) +#define AD_TYPE_32_BIT_SERV_UUID (0x04) +#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) +#define AD_TYPE_128_BIT_SERV_UUID (0x06) +#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) +/** + * @} + */ + +/* LOCAL NAME AD types */ +/** + * @name Local name AD types + * @{ + */ +#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) +#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) +/** + * @} + */ + +/* TX power level AD type*/ +#define AD_TYPE_TX_POWER_LEVEL (0x0A) + +/* Class of device */ +#define AD_TYPE_CLASS_OF_DEVICE (0x0D) + +/* security manager TK value AD type */ +#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) + +/* security manager OOB flags */ +#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) + +/* slave connection interval AD type */ +#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) + +/* service solicitation UUID list Ad types*/ +/** + * @name Service solicitation UUID list AD types + * @{ + */ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) +#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) +/** + * @} + */ + +/* service data AD type */ +#define AD_TYPE_SERVICE_DATA (0x16) + +/* manufaturer specific data AD type */ +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/* appearance AD type */ +#define AD_TYPE_APPEARANCE (0x19) + +/* advertising interval AD type */ +#define AD_TYPE_ADVERTISING_INTERVAL (0x1A) + +/** + * @} + */ + +#define MAX_ADV_DATA_LEN (31) + +#define DEVICE_NAME_LEN (7) +#define BD_ADDR_SIZE (6) + +/** + * @name Privacy flag values + * @{ + */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) +/** + * @} + */ + +/** + * @name Intervals + * Intervals in terms of 625 micro sec + * @{ + */ +#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ +#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ +#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ +#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ +#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ +#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ +#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ +#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ +/** + * @} + */ + +/** + * @name Timeout values + * @{ + */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ +/** + * @} + */ + +/** + * @anchor gap_roles + * @name GAP Roles + * @{ +*/ +#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) +#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) + +#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) +#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) +/** + * @} + */ + +/** + * @anchor gap_procedure_codes + * @name GAP procedure codes + * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event + * and aci_gap_terminate_gap_procedure() command. + * @{ + */ +#define GAP_LIMITED_DISCOVERY_PROC (0x01) +#define GAP_GENERAL_DISCOVERY_PROC (0x02) +#define GAP_NAME_DISCOVERY_PROC (0x04) +#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) +#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) +#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) +#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) +#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1231 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gap_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GAP_ACI_H__ +#define __BLUENRG_GAP_ACI_H__ + +/** + *@addtogroup GAP GAP + *@brief GAP layer. + *@{ + */ + +/** + *@defgroup GAP_Functions GAP functions + *@brief API for GAP layer. + *@{ + */ + +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". + * @param privacy_enabled Enable (1) or disable (0) privacy. + * @param device_name_char_len Length of the device name characteristic + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, + uint8_t device_name_char_len, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Privacy Flag (peripheral role only) + * @li Reconnection Address (peripheral role only) + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB04A1(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); + +/** + * @brief Set the Device in non-discoverable mode. + * @note This command will disable the LL advertising. + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_discoverable(void); + +/** + * @brief Put the device in limited discoverable mode + * (as defined in GAP specification volume 3, section 9.2.3). + * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. + * The advertising can be disabled at any time by issuing + * aci_gap_set_non_discoverable() command. + * The AdvIntervMin and AdvIntervMax parameters are optional. If both + * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). + * Host can set the Local Name, a Service UUID list and the Slave Connection + * Minimum and Maximum. If provided, these data will be inserted into the + * advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() + * separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following + * standard AD types: + * @li AD Flags + * @li TX Power Level + * + * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates + * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. + * + * Example: + * @code + * + * #define ADV_INTERVAL_MIN_MS 100 + * #define ADV_INTERVAL_MAX_MS 200 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, + * (ADV_INTERVAL_MAX_MS*1000)/0.625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * sizeof(serviceUUIDList), serviceUUIDList, + * 0, 0); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 250 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 500 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg NO_WHITE_LIST_USE + * @arg WHITE_LIST_FOR_ONLY_SCAN + * @arg WHITE_LIST_FOR_ONLY_CONN + * @arg WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +/** + * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4). + * @note The device will be discoverable until the Host issue Aci_Gap_Set_Non_Discoverable command. + * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses + * the default values for advertising intervals (1.28 s and 2.56 s respectively for IDB04A1). + * When using connectable undirected advertising events:\n + * @li Adv_Interval_Min = 30 ms + * @li Adv_Interval_Max = 60 ms + * \nWhen using non-connectable advertising events or scannable undirected advertising events:\n + * @li Adv_Interval_Min = 100 ms + * @li Adv_Interval_Max = 150 ms + * Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided, + * these data will be inserted into the advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following standard AD types: + * @li AD Flags + * @li TX Power Level + * + * Usage example: + * + * @code + * + * #define ADV_INTERVAL_MIN_MS 800 + * #define ADV_INTERVAL_MAX_MS 900 + * #define CONN_INTERVAL_MIN_MS 100 + * #define CONN_INTERVAL_MAX_MS 300 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625, + * (ADV_INTERVAL_MAX_MS*1000)/625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * 0, NULL, + * (CONN_INTERVAL_MIN_MS*1000)/1250, + * (CONN_INTERVAL_MAX_MS*1000)/1250); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 1.28 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 2.56 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ONLY_SCAN + * @arg @ref WHITE_LIST_FOR_ONLY_CONN + * @arg @ref WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); + +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @param adv_interv_min Minimum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @param adv_interv_max Maximum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max); +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); + +/** + * @brief Set the IO capabilities of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param io_capability One of the allowed codes for IO Capability: + * @arg @ref IO_CAP_DISPLAY_ONLY + * @arg @ref IO_CAP_DISPLAY_YES_NO + * @arg @ref IO_CAP_KEYBOARD_ONLY + * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT + * @arg @ref IO_CAP_KEYBOARD_DISPLAY + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_io_capability(uint8_t io_capability); + +/** + * @brief Set the authentication requirements for the device. + * @note If the oob_enable is set to 0, oob_data will be ignored. + * This command has to be given only when the device is not in a connected state. + * @param mitm_mode MITM mode: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @param oob_enable If OOB data are present or not: + * @arg @ref OOB_AUTH_DATA_ABSENT + * @arg @ref OOB_AUTH_DATA_PRESENT + * @param oob_data Out-Of-Band data + * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process + * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process + * @param use_fixed_pin If application wants to use a fixed pin or not: + * @arg @ref USE_FIXED_PIN_FOR_PAIRING + * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING + * If a fixed pin is not used, it has to be provided by the application with + * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will + * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is + * accepted. + * @param bonding_mode One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode); + /** + * @brief Set the authorization requirements of the device. + * @note This command has to be given when connected to a device if authorization is required to access services + * which require authorization. + * @param conn_handle Handle of the connection. + * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required + * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables + * the authorization requirement in the device and when a remote device + * tries to read/write a characeristic with authorization requirements, the stack will + * send back an error response with "Insufficient authorization" error code. + * After pairing is complete a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event + * will be sent to the Host. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); + +/** + * @brief Provide the pass key that will be used during pairing. + * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param conn_handle Connection handle + * @param passkey Pass key that will be used during the pairing process. Must be a number between + * 0 and 999999. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); + +/** + * @brief Authorize a device to access attributes. + * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. + * + * @param conn_handle Connection handle + * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) + * @arg @ref CONNECTION_REJECTED : Reject (reject connection) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); + +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @param own_address_type If Privacy is disabled, then the peripheral address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the peripheral address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); + +/** + * @brief Put the device into undirected connectable mode. + * @note If privacy is enabled in the device, a resolvable private address is generated and used + * as the advertiser's address. If not, the address of the type specified in own_addr_type + * is used for advertising. + * @param own_addr_type Type of our address used during advertising: + * if BLUENRG (IDB04A1) + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * else if BLUENRG_MS (IDB05A1) + * If Privacy is disabled: + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled: + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_filter_policy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ALL + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); + +/** + * @brief Send a slave security request to the master. + * @note This command has to be issued to notify the master of the security requirements of the slave. + * The master may encrypt the link, initiate the pairing procedure, or reject the request. + * @param conn_handle Connection handle + * @param bonding One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @param mitm_protection If MITM protection is required or not: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); + +/** + * @brief Update advertising data. + * @note This command can be used to update the advertising data for a particular AD type. + * If the AD type specified does not exist, then it is added to the advertising data. + * If the overall advertising data length is more than 31 octets after the update, then + * the command is rejected and the old data is retained. + * @param AdvLen Length of AdvData array + * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification + * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. + * Example + * @code + * tBleStatus ret; + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; + * + * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * 8, local_name, 3, serviceUUIDList, 0, 0); + * ret = aci_gap_update_adv_data(5, manuf_data); + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); + +/** + * @brief Delete an AD Type + * @note This command can be used to delete the specified AD type from the advertisement data if + * present. + * @param ad_type One of the allowed AD types (see @ref AD_Types) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); + +/** + * @brief Get the current security settings + * @note This command can be used to get the current security settings of the device. + * @param mitm_protection @arg 0: Not required + * @arg 1: Required + * @param bonding @arg 0: No bonding mode + * @arg 1: Bonding mode + * @param oob_data @arg 0: Data absent + * @arg 1: Data present + * @param passkey_required @arg 0: Not required + * @arg 1: Fixed pin is present which is being used + * @arg 2: Passkey required for pairing. An event will be generated + * when required. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required); + +/** + * @brief Add addresses of bonded devices into the controller's whitelist. + * @note The command will return an error if there are no devices in the database or if it was unable + * to add the device into the whitelist. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_configure_whitelist(void); + +/** + * @brief Terminate a connection. + * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. + * @param conn_handle Connection handle + * @param reason Reason for requesting disconnection. The error code can be any of ones as specified + * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); + +/** + * @brief Clear the security database. + * @note All the devices in the security database will be removed. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_clear_security_database(void); + +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @param conn_handle + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB04A1(void); + +/** + * @brief Start the limited discovery procedure. + * @note The controller is commanded to start active scanning. When this procedure is started, + * only the devices in limited discoverable mode are returned to the upper layers. + * The procedure is terminated when either the upper layers issue a command to terminate the + * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code + * set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated + * due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC. + * The device found when the procedure is ongoing is returned to the upper layers through the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the general discovery procedure. + * @note The controller is commanded to start active scanning. The procedure is terminated when + * either the upper layers issue a command to terminate the procedure by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC + * or a timeout happens. When the procedure is terminated due to any of the above reasons, + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to + * @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to + * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the name discovery procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. Once a connection is established, GATT procedure is started to read the + * device name characteristic. When the read is completed (successfully or unsuccessfully), + * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also + * contains the name of the device if the device name was read successfully. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Start the auto connection establishment procedure. + * @note The devices specified are added to the white list of the controller and a LE_Create_Connection + * call will be made to the controller by GAP with the initiator filter policy set to + * use whitelist to determine which advertiser to connect to. When a command is issued to + * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the + * controller by GAP. + * The procedure is terminated when either a connection is successfully established with one of + * the specified devices in the white list or the procedure is explicitly terminated by issuing + * the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start a general connection establishment procedure. + * @note The host enables scanning in the controller with the scanner filter policy set + * to accept all advertising packets and from the scanning results all the devices + * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * The upper layer then has to select one of the devices to which it wants to connect + * by issuing the command aci_gap_create_connection(). The procedure is terminated + * when a connection is established or the upper layer terminates the procedure by + * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates); +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); + +/** + * @brief Start a selective connection establishment procedure. + * @note The GAP adds the specified device addresses into white list and enables scanning in + * the controller with the scanner filter policy set to accept packets only from + * devices in whitelist. All the devices found are sent to the upper layer by the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the + * devices to which it wants to connect by issuing the command aci_gap_create_connection(). + * On completion of the procedure a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated + * with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * The procedure is terminated when a connection is established or the upper layer terminates + * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure + * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start the direct connection establishment procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. The procedure can be terminated explicitly by the upper layer by issuing + * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the + * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller + * by GAP. + * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can + * be explicitly terminated by the upper layer by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is + * returned with the procedure code set to the corresponding procedure. + * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes"). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); + +/** + * @brief Start the connection parameter update procedure. + * @note Allowed by the Central to update the connection parameter of the specified connection. + * A Link Layer Connection Update procedure is started on the controller. + * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to + * the upper layer. + * @param conn_handle Handle of the connection for which the update procedure has to be started. + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Send a pairing request. + * @note Send the SM pairing request to start a pairing process from a Central. The authentication + * requirements and IO capabilities should be set before issuing this command using + * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). + * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. + * @param conn_handle Handle of the connection for which the pairing request has to be sent. + * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded + * @arg 0x01: Pairing request will be sent even if the device was previously bonded + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param[in] address Address to be resolved. + * @param[out] actual_address The public or static random address of the peer device, distributed during pairing phase. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); + +/** + * @brief This command gets the list of bonded devices. + * @note It returns the number of addresses and the corresponding address types and values. + * Example: + * @code + * tBleStatus ret; + * uint8_t num_devices = 0; + * uint8_t device_list[12*7]; + * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); + * for(int i = 0; i < num_devices; i+=7){ + * uint8_t addr_type = device_list[i]; + * uint8_t addr = device_list[i+1]; + * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); + * } + * @endcode + * + * @param[out] num_devices The number of bonded devices. + * @param[out] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address + * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. + * @param device_list_size Maximum size of the device_list buffer used to return the device list. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); + +/** + * @brief Puts the device into broadcast mode + * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address + * as specified in the own_addr_type parameter of the command. + * @param adv_interv_min Minimum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_interv_max Maximum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param own_addr_type If Privacy is disabled, the broadcaster address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the broadcaster address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_data_length Length of the advertising data in the advertising packet + * @param adv_data Advertising data used by the device while advertising + * @param num_whitelist_entries Number of devices to be added to whitelist + * @param addr_array It will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Starts an observation procedure, when the device is in Observer role. + * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer + * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth + * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. + * The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. + * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param own_address_type If Privacy is disabled, then the scanner address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the scanner address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates); + +/** + * @brief The command finds whether a device is bonded. + * @note If the device is using a resolvable private address and it has been bonded, then the command will return + * BLE_STATUS_SUCCESS. + * @param peer_address_type The address type of the peer device + * @arg @ref PUBLIC_ADDR. + * @arg @ref RANDOM_ADDR. + * @param peer_address Address used by the peer device while advertising. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address); + + +/** + * @} + */ + +/** + * @defgroup GAP_Events GAP events + * @{ + */ + +/** + * This event is generated by the controller when the limited discoverable + * mode ends due to timeout (180 seconds). No parameters in the event. + */ +#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) + + +/** + * This event is generated when the pairing process has completed successfully + * or a pairing procedure timeout has occurred or the pairing has failed. + * This is to notify the application that we have paired with a remote device + * so that it can take further actions or to notify that a timeout has occurred + * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. + */ +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +typedef __packed struct _evt_gap_pairing_cmplt{ + uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ + /** + * 0x00: Pairing Success. Pairing with a remote device was successful\n + * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n + * 0x02: Pairing Failed. The pairing failed with the remote device. + */ + uint8_t status; +} PACKED evt_gap_pairing_cmplt; + + +/** + * This event is generated by the Security manager to the application when a pass key is required for pairing. + * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. + * See @ref _evt_gap_pass_key_req. + */ +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +typedef __packed struct _evt_gap_pass_key_req{ + uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ +} PACKED evt_gap_pass_key_req; + + +/** + * This event is generated by the Security manager to the application when the application + * has set that authorization is required for reading/writing of attributes. This event will + * be generated as soon as the pairing is complete. When this event is received, + * aci_gap_authorization_response() command should be used by the application. + * See @ref _evt_gap_author_req. + */ +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +typedef __packed struct _evt_gap_author_req{ + uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ +} PACKED evt_gap_author_req; + +/** + * This event is generated when the slave security request is successfully sent to the master. + * No parameters for this event. + */ +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) + +/** + * This event is generated on the slave when a aci_gap_slave_security_request() is called to reestablish the bond + * with a master but the master has lost the bond. When this event is received, the upper layer has to issue the + * command aci_gap_allow_rebond() in order to allow the slave to continue the pairing process with the master. + * On the master this event is raised when aci_gap_send_pairing_request() is called to reestablish a bond with a slave + * but the slave has lost the bond. In order to create a new bond the master has to launch aci_gap_send_pairing_request() + * with force_rebond set to 1. + * No parameters for this event + */ +#define EVT_BLUE_GAP_BOND_LOST (0X0405) + +/** + * The event is given by the GAP layer to the upper layers when a device is discovered during scanning + * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. + */ +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef __packed struct _evt_gap_device_found{ + uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ + uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ + tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ + uint8_t data_length; /**< Length of advertising or scan response data. */ + uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ +} PACKED evt_gap_device_found; + +/** + * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated + * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. + */ +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef __packed struct _evt_gap_procedure_complete{ + uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ + /** + * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed + * due to authentication requirements). + */ + uint8_t status; + /** + * Procedure specific data.\n + * @li For Name Discovery Procedure:\n + * the name of the peer device if the procedure completed successfully. + * @li For General Connection Establishment Procedure:\n + * The reconnection address written to the peripheral device if the peripheral is privacy enabled + */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_gap_procedure_complete; + +/** + * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral + * is not able to resolve the private address of the peer device after connecting to it. + */ +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) +typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ + uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ +} PACKED evt_gap_addr_not_resolved_IDB05A1; +/** + * This event is raised when the reconnection address is generated during the general connection + * establishment procedure. The same address is set into the peer device also as a part of the general + * connection establishment procedure. In order to make use of the reconnection address the next time + * while connecting to the bonded peripheral, the application needs to use this reconnection address + * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() + * and aci_gap_start_auto_conn_establish_proc(). + */ +#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) +typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ + uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ +} PACKED evt_gap_reconnection_addr_IDB04A1; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1128 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GATT_ACI_H__ +#define __BLUENRG_GATT_ACI_H__ + +#include "bluenrg_gatt_server.h" + +/** + *@addtogroup GATT GATT + *@brief GATT layer. + *@{ + */ + +/** + *@defgroup GATT_Functions GATT functions + *@brief API for GATT layer. + *@{ + */ + +/** + * @brief Initialize the GATT layer for server and client roles. + * @note It adds also the GATT service with Service Changed Characteristic. + * Until this command is issued the GATT channel will not process any commands + * even if the connection is opened. This command has to be given + * before using any of the GAP features. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_init(void); + +/** + * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs + * to reserve the handle ranges for this service using max_attr_records parameter. This + * parameter specifies the maximum number of attribute records that can be added to this + * service (including the service attribute, include attribute, characteristic attribute, + * characteristic value attribute and characteristic descriptor attribute). Handle of the + * created service is returned. + * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors + * are allocated from the attribute pool. + * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field + * @param service_type Primary or secondary service. See @ref Service_type "Service Type". + * @param max_attr_records Maximum number of attribute records that can be added to this service + * (including the service declaration itself) + * @param[out] serviceHandle Handle of the Service. When this service is added to the service, + * a handle is allocated by the server to this service. Server also + * allocates a range of handles for this service from serviceHandle to + * <serviceHandle + max_attr_records>. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, + const uint8_t* service_uuid, + uint8_t service_type, + uint8_t max_attr_records, + uint16_t *serviceHandle); + +/** + * @brief Include a service given by included_start_handle and included_end_handle to another service + * given by service_handle. Attribute server creates an INCLUDE definition attribute and return + * the handle of this attribute in included_handle. + * @param service_handle Handle of the service to which another service has to be included + * @param included_start_handle Start Handle of the service which has to be included in service + * @param included_end_handle End Handle of the service which has to be included in service + * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". + * @param[in] included_uuid 16-bit or 128-bit UUID. + * @param[out] included_handle Handle of the include declaration. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle); + +/** + * @brief Add a characteristic to a service. + * @param serviceHandle Handle of the service to which the characteristic has to be added. + * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param charUuid 16-bit or 128-bit UUID. + * @param charValueLen Maximum length of the characteristic value. + * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, + * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". + * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @arg GATT_DONT_NOTIFY_EVENTS + * @arg GATT_NOTIFY_ATTRIBUTE_WRITE + * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP + * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. + * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client + * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE + * properties. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle); + +/** + * Add a characteristic descriptor to a service. + * @param serviceHandle Handle of the service to which the characteristic belongs + * @param charHandle Handle of the characteristic to which description has to be added. + * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG + * (Well_known_UUIDs) or a user-defined one. + * @param descValueMaxLen The maximum length of the descriptor value + * @param descValueLen Current Length of the characteristic descriptor value + * @param[in] descValue Value of the characteristic description + * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". + * @arg ATTR_NO_ACCESS + * @arg ATTR_ACCESS_READ_ONLY + * @arg ATTR_ACCESS_WRITE_REQ_ONLY + * @arg ATTR_ACCESS_READ_WRITE + * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE + * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param[out] descHandle Handle of the Characteristic Descriptor. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle); + +/** + * @brief Update a characteristic value in a service. + * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. The command is queued into the + * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, + * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or + * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate + * than what is allowed by the link. Throughput on BLE link depends on connection interval and + * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() + * for more info on how to suggest new connection parameters from a slave). If the application does not + * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function + * returns @ref BLE_STATUS_SUCCESS or any other error code.\n + * Example:\n + * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some + * notifications will be lost. + * @code + * tBleStatus Free_Fall_Notify(void) + * { + * uint8_t val; + * tBleStatus ret; + * + * val = 0x01; + * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); + * + * if (ret != BLE_STATUS_SUCCESS){ + * PRINTF("Error while updating FFall characteristic.\n") ; + * return BLE_STATUS_ERROR ; + * } + * return BLE_STATUS_SUCCESS; + * } + * @endcode + * Here if BlueNRG buffer become full, the application try again to send the notification. + * @code + * struct timer t; + * Timer_Set(&t, CLOCK_SECOND*10); + * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ + * // Radio is busy (buffer full). + * if(Timer_Expired(&t)) + * break; + * } + * @endcode + * + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic + * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, + * and the attribute value is of variable length, then the length of the attribute will + * be set to the charValueLen. If the charValOffset is set to a value greater than 0, + * then the length of the attribute will be set to the maximum length as specified for + * the attribute while adding the characteristic. + * @param charValueLen Length of the characteristic value in octets + * @param[in] charValue Characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue); +/** + * @brief Delete the specified characteristic from the service. + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); + +/** + * @brief Delete the specified service from the GATT server database. + * @param servHandle Handle of the service to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_service(uint16_t servHandle); + +/** + * @brief Delete the Include definition from the service. + * @param servHandle Handle of the service to which Include definition belongs + * @param includeServHandle Handle of the Included definition to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); + +/** + * @brief Perform an ATT MTU exchange procedure. + * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP + * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated + * to indicate the end of the procedure. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); + +/** + * @brief Send a @a Find @a Information @a Request. + * @note This command is used to obtain the mapping of attribute handles with their associated + * types. The responses of the procedure are given through the + * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by + * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range of attributes to be discovered on the server + * @param end_handle Ending handle of the range of attributes to be discovered on the server + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send a @a Find @a By @a Type @a Value @a Request + * @note The Find By Type Value Request is used to obtain the handles of attributes that + * have a given 16-bit UUID attribute type and a given attribute value. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid 2 octet UUID to find (little-endian) + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). + * @param attr_val Attribute value to find + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send a @a Read @a By @a Type @a Request + * @note The Read By Type Request is used to obtain the values of attributes where the attribute type + * is known but the handle is not known. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Read @a By @a Group @a Type @a Request + * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute + * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping + * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Prepare @a Write @a Request + * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param attr_handle The handle of the attribute to be written + * @param value_offset The offset of the first octet to be written + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). + * @param attr_val The value of the attribute to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send an @a Execute @a Write @a Request + * @note The Execute Write Request is used to request the server to write or cancel the write of all the + * prepared values currently held in the prepare queue from this client. + * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param execute @arg 0x00 Cancel all prepared writes + * @arg 0x01 Immediately write all pending prepared values. + * @return Value indicating success or error code. + */ +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); + +/** + * @brief This command will start the GATT client procedure to discover all primary services on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +/** + * @brief Start the procedure to discover the primary services of the specified UUID on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to find all included services. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle Start handle of the service + * @param end_handle End handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Start the procedure to discover all the characteristics of a given service. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_attr_handle Start attribute handle of the service + * @param end_attr_handle End attribute handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +/** + * @brief Start the procedure to discover all the characteristics specified by a UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Start attribute handle of the service + * @param end_handle End attribute handle of the service + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); + +/** + * @brief Start the procedure to discover all characteristic descriptors on the server. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. + * @param conn_handle Connection handle for which the command is given. + * @param char_val_handle Starting handle of the characteristic + * @param char_end_handle End handle of the characteristic + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +/** + * @brief Start the procedure to read the attribute value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to read all the characteristics specified by the UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range to be searched + * @param end_handle End handle of the range to be searched + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start a procedure to read multiple characteristic values from a server. + * @note This sub-procedure is used to read multiple Characteristic Values from a server when the + * client knows the Characteristic Value Handles. + * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param num_handles The number of handles for which the value has to be read + * @param set_of_handles The handles for which the attribute value has to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles); + +/** + * @brief Start the procedure to write a characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to write a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start the procedure to write a characteristic reliably. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to write a long characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP + * event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic descriptor + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start the procedure to write a characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to read the descriptor specified. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the descriptor to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to write a characteristic value without waiting for any response from the server. + * @note No events are generated after this command is executed. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 3) + * @param[in] attr_val Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start a signed write without response from the server. + * @note The procedure i used to write a characteristic value with an authentication signature without waiting + * for any response from the server. It cannot be used when the link is encrypted. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 13). + * @param attr_val Value to be written + * @return Value indicating success or error code + */ +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Confirm an indication + * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); + +/** + * @brief Allow or reject a write request from a client. + * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, + * then the status has to be set to 1 and the error code has to be set to the error code that has to be + * passed to the client. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n + * 0x01: The value cannot be written to the attribute specified by the attr_handle. + * @param err_code The error code that has to be passed to the client in case the write has to be rejected. + * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val); + +/** + * @brief Allow the GATT server to send a response to a read request from a client. + * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ + * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response + * can be sent to the client. So if the application wishes to update any of the attributes before + * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value + * and then give this command. The application should perform the required operations within 30 seconds, + * otherwise the GATT procedure will go to timeout. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_allow_read(uint16_t conn_handle); + +/** + * @brief Set the security permission for the attribute handle specified. + * @note Currently the setting of security permission is allowed only for client configuration descriptor. + * @param service_handle Handle of the service which contains the attribute whose security + * permission has to be modified. + * @param attr_handle Handle of the attribute whose security permission has to be modified. + * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission); + +/** + * @brief This command sets the value of the descriptor specified by charDescHandle. + * @param servHandle Handle of the service which contains the descriptor. + * @param charHandle Handle of the characteristic which contains the descriptor. + * @param charDescHandle Handle of the descriptor whose value has to be set. + * @param charDescValOffset Offset from which the descriptor value has to be updated. + * @param charDescValueLen Length of the descriptor value + * @param[in] charDescValue descriptor value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue); + +/** + * @brief Reads the value of the attribute handle specified from the local GATT database. + * @param attr_handle Handle of the attribute to read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + + /** + * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. + * @param attr_handle Handle of the attribute to read + * @param offset Offset from which the value needs to be read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); +/** + * @brief Update the value of a characteristic and sends notifications or indications. + * @note This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute + * up to 512 bytes and indicate selectively the generation of indications and notifications. + * @param service_handle Handle of the service to which the characteristic belongs. + * @param char_handle Handle of the characteristic + * @param update_type Bitmask that controls generation of notifications and indications. It can be a combination + * @arg @ref NOTIFICATION (0x01): send notification, if enabled. + * @arg @ref INDICATION (0x02): send indication, if enabled. + * If set to 0 no notifications or indications are sent. + * @param char_length Total length of the characteristic value. In case of a variable size characteristic, + * this field specifies the new length of the characteristic value after the update; + * in case of fixed length characteristic this field is ignored. + * @param value_offset The offset from which the attribute value has to be updated + * @param value_length Length of the value to be updated + * @param[out] value Updated characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value); + +/** + * @} + */ + + +/** + * @defgroup GATT_Events GATT events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** + * This event (if enabled, see @ref Gatt_Event_Mask "Gatt Event Mask") is raised to the application + * by the GATT server when a client modifies any attribute on the server, as consequence of one of + * the following GATT procedures: + * @li write without response + * @li signed write without response + * @li write characteristic value + * @li write long characteristic value + * @li reliable write. + * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. + */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint16_t offset; /**< Offset from which the write has been performed by the peer device */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB05A1; + +typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB04A1; + +/** + * This event is generated by the client/server to the application on a GATT timeout (30 seconds). + * See @ref _evt_gatt_procedure_timeout. + */ +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +typedef __packed struct _evt_gatt_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ +} PACKED evt_gatt_procedure_timeout; + +/** + * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). + * See @ref _evt_att_exchange_mtu_resp. + */ +#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) +typedef __packed struct _evt_att_exchange_mtu_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data (always 1). */ + uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ +} PACKED evt_att_exchange_mtu_resp; + +/** + * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and + * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. + */ +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef __packed struct _evt_att_find_information_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ + /** + * A sequence of handle-uuid pairs.\n + * @li if format=1, each pair is:\n + * [2 octets for handle, 2 octets for UUIDs] \n + * @li if format=2, each pair is:\n + * [2 octets for handle, 16 octets for UUIDs] + */ + uint8_t handle_uuid_pair[VARIABLE_SIZE]; +} PACKED evt_att_find_information_resp; + +/** + * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See + * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. + */ +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +typedef __packed struct _evt_att_find_by_type_val_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + /** + * Handles Information List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] + */ + uint8_t handles_info_list[VARIABLE_SIZE]; +} PACKED evt_att_find_by_type_val_resp; + +/** + * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and + * aci_gatt_disc_all_charac_of_serv(). + * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. + */ +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef __packed struct _evt_att_read_by_type_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ + /** + * Attribute Data List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] + */ + uint8_t handle_value_pair[VARIABLE_SIZE]; +} PACKED evt_att_read_by_type_resp; + +/** + * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). + * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. + */ +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +typedef __packed struct _evt_att_read_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ +} PACKED evt_att_read_resp; + +/** + * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). + * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. + */ +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +typedef __packed struct _evt_att_read_blob_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ +} PACKED evt_att_read_blob_resp; + +/** + * This event is generated in response to a @a Read @a Multiple @a Request. + * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. + */ +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +typedef __packed struct _evt_att_read_mult_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ +} PACKED evt_att_read_mult_resp; + +/** + * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). + * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. + */ +#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) +typedef __packed struct _evt_att_read_by_group_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_data_length; /**< The size of each Attribute Data. */ + /** + * A list of Attribute Data where the attribute data is composed by: + * @li 2 octets for Attribute Handle + * @li 2 octets for End Group Handle + * @li (attribute_data_length - 4) octets for Attribute Value + */ + uint8_t attribute_data_list[VARIABLE_SIZE]; +} PACKED evt_att_read_by_group_resp; + +/** + * This event is generated in response to a @a Prepare @a Write @a Request. + * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. + */ +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +typedef __packed struct _evt_att_prepare_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attribute_handle; /**< The handle of the attribute to be written. */ + uint16_t offset; /**< The offset of the first octet to be written. */ + uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ +} PACKED evt_att_prepare_write_resp; + +/** + * This event is generated in response to an @a Execute @a Write @a Request. + * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. + */ +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +typedef __packed struct _evt_att_exec_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Always 0. */ +} PACKED evt_att_exec_write_resp; + +/** + * This event is generated when an indication is received from the server. + * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. + */ +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +typedef __packed struct _evt_gatt_indication{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_indication; + +/** + * This event is generated when a notification is received from the server. + * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. + */ +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef __packed struct _evt_gatt_notification{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_attr_notification; + +/** + * This event is generated when a GATT client procedure completes either with error or successfully. + * See @ref _evt_gatt_procedure_complete. + */ +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef __packed struct _evt_gatt_procedure_complete{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ + uint8_t data_length; /**< Length of error_code field (always 1). */ + /** + * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). + */ + uint8_t error_code; +} PACKED evt_gatt_procedure_complete; + +/** + * This event is generated when an Error Response is received from the server. The error response can be given + * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended + * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. + */ +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +typedef __packed struct _evt_gatt_error_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t req_opcode; /**< The request that generated this error response. */ + uint16_t attr_handle; /**< The attribute handle that generated this error response. */ + uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ +} PACKED evt_gatt_error_resp; + +/** + * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using + * Characteristic UUID" procedure. + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. + */ +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + /** + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. + */ + uint8_t attr_value[VARIABLE_SIZE]; +} PACKED evt_gatt_disc_read_char_by_uuid_resp; + +/** + * This event is given to the application when a write request, write command or signed write command + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * If the write is rejected by the application, then the value of the attribute will not be modified. + * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. + * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef __packed struct _evt_gatt_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_write_permit_req; + +/** + * This event is given to the application when a read request or read blob request is received by the server + * from the client. This event will be given to the application only if the event bit for this event generation + * is set when the characteristic was added. + * On receiving this event, the application can update the value of the handle if it desires and when done + * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef __packed struct _evt_gatt_read_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ + uint8_t data_length; /**< Length of offset field. */ + uint16_t offset; /**< Contains the offset from which the read has been requested */ +} PACKED evt_gatt_read_permit_req; + +/** + * This event is given to the application when a read multiple request or read by type request is received + * by the server from the client. This event will be given to the application only if the event bit for this + * event generation is set when the characteristic was added. + * On receiving this event, the application can update the values of the handles if it desires and when done + * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_multi_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) +typedef __packed struct _evt_gatt_read_multi_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ +} PACKED evt_gatt_read_multi_permit_req; + +/** + * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2). + * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES. + * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value(). + * See @ref evt_gatt_tx_pool_vailable. + * + */ +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE (0x0C16) +typedef __packed struct _evt_gatt_tx_pool_available{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t available_buffers; /**< Length of data field. */ +} PACKED evt_gatt_tx_pool_available; + +/** + * This event is raised on the server when the client confirms the reception of an indication. + */ +#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT (0x0C17) +typedef __packed struct _evt_gatt_server_confirmation{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ +} PACKED evt_gatt_server_confirmation; +/** + * This event is given to the application when a prepare write request + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * Based on the response from the application, the attribute value will be modified by the stack. + * If the write is rejected by the application, then the value of the attribute will not be modified + * and an error response will be sent to the client, with the error code as specified by the application. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ (0x0C18) +typedef __packed struct _evt_gatt_prepare_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint16_t offset; /**< The offset from which the prepare write has been requested */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_prepare_write_permit_req; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,229 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gatt_server.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GATT server layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BNRG_GATT_SERVER_H__ +#define __BNRG_GATT_SERVER_H__ + +#include "ble_compiler.h" +#include "ble_status.h" + +/** + *@addtogroup GATT GATT + *@{ + */ + +/** + * @anchor Well-Known_UUIDs + * @name Well-Known UUIDs + * @{ + */ +#define PRIMARY_SERVICE_UUID (0x2800) +#define SECONDARY_SERVICE_UUID (0x2801) +#define INCLUDE_SERVICE_UUID (0x2802) +#define CHARACTERISTIC_UUID (0x2803) +#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) +#define CHAR_USER_DESC_UUID (0x2901) +#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) +#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) +#define CHAR_FORMAT_DESC_UUID (0x2904) +#define CHAR_AGGR_FMT_DESC_UUID (0x2905) +#define GATT_SERVICE_UUID (0x1801) +#define GAP_SERVICE_UUID (0x1800) +#define SERVICE_CHANGED_UUID (0x2A05) +/** + * @} + */ + +/** + * @anchor Access_permissions + * @name Access permissions + * Access permissions for an attribute + * @{ + */ +#define ATTR_NO_ACCESS (0x00) +#define ATTR_ACCESS_READ_ONLY (0x01) +#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) +#define ATTR_ACCESS_READ_WRITE (0x03) +#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) +#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) +/** + * Allows all write procedures + */ +#define ATTR_ACCESS_WRITE_ANY (0x0E) +/** + * @} + */ + +/** + * @anchor Char_properties + * @name Characteristic properties. + * @{ + */ +#define CHAR_PROP_BROADCAST (0x01) +#define CHAR_PROP_READ (0x02) +#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) +#define CHAR_PROP_WRITE (0x08) +#define CHAR_PROP_NOTIFY (0x10) +#define CHAR_PROP_INDICATE (0x20) +#define CHAR_PROP_SIGNED_WRITE (0x40) +#define CHAR_PROP_EXT (0x80) +/** + * @} + */ + + +/** + * @anchor Security_permissions + * @name Security permissions for an attribute. + * @{ + */ +#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ +#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ +#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ +#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ +/** + * @} + */ + +/** + * @anchor UUID_Types + * @name Type of UUID (16 bit or 128 bit). + * @{ + */ +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) +/** + * @} + */ + +/** + * @anchor Service_type + * @name Type of service (primary or secondary) + * @{ + */ +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) +/** + * @} + */ + +/** + * @anchor Gatt_Event_Mask + * @name Gatt Event Mask + * Type of event generated by GATT server + * @{ + */ +#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ +#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. + An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ +#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd + or a signed write cmd are received by the server for this attribute. + An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ +#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is + received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ +/** + * @} + */ + +/** + * @name Type of characteristic length + * See aci_gatt_add_char() + * @{ + */ +#define CHAR_VALUE_LEN_CONSTANT (0x00) +#define CHAR_VALUE_LEN_VARIABLE (0x01) +/** + * @} + */ + + +/** + * @name Encryption key size + * @{ + */ +/** + * Minimum encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Maximum encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) +/** + * @} + */ + +/** + * @name Characteristic Presentation Format + * @{ + */ +typedef __packed struct _charactFormat { + uint8_t format; + int8_t exp; + uint16_t unit; + uint8_t name_space; + uint16_t desc; +} PACKED charactFormat; + +/** + * @} + */ + +/** + * @name Format + * @{ + */ +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F +/** + * @} + */ + +/** + * @name Unit + * @{ + */ +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 +/** + * @} + */ + + +/** + * ATT MTU size + */ +#define ATT_MTU (23) + +/** + * @} + */ + + /** + * @name Update type of aci_gatt_upd_char_val_ext(). + * @{ + */ + +#define NOTIFICATION 1 +#define INDICATION 2 + +#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,385 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hal_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with HCI commands for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_HAL_ACI_H__ +#define __BLUENRG_HAL_ACI_H__ + +/** + *@addtogroup HAL HAL + *@brief Hardware Abstraction Layer. + *@{ + */ + +/** + * @defgroup HAL_Functions HAL functions + * @brief API for BlueNRG HAL layer. + * @{ + */ + +/** + * @brief This command retrieves the buid number of the firmware. + * @param[out] build_number Build number identifying the firmware release. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number); + +/** + * @brief This command writes a value to a low level configure data structure. + * @note It is useful to setup directly some low level parameters for the system at runtime. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * + * @param len Length of data to be written + * @param[out] val Data to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val); + +/** + * @brief This command requests the value in the low level configure data structure. + * The number of read bytes changes for different Offset. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * @param data_len Length of the data buffer + * @param[out] data_len_out_p length of the data returned by the read. + * @param[out] data Read data + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data); + +/** + * @brief This command sets the TX power level of the BlueNRG. + * @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines + * the output power level (dBm). + * When the system starts up or reboots, the default TX power level will be used, which is + * the maximum value of 8dBm. Once this command is given, the output power will be changed + * instantly, regardless if there is Bluetooth communication going on or not. For example, + * for debugging purpose, the BlueNRG can be set to advertise all the time and use this + * command to observe the signal strength changing. The system will keep the last received + * TX power level from the command, i.e. the 2nd command overwrites the previous TX power + * level. The new TX power level remains until another Set TX Power command, or the system + * reboots.\n + * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the + * right value, depending on the selected hardware configuration for the RF network: + * normal mode or high power mode. + * @param pa_level Can be from 0 to 7. Set the PA level value. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +/** + * @brief This command returns the number of packets sent in Direct Test Mode. + * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets + * have been transmitted. This command can be used to check how many packets have been sent + * during the Direct TX test.\n + * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again. + * The counter is not cleared until the next Direct TX test starts. + * @param[out] number_of_packets Number of packets sent during the last Direct TX test. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets); + +/** + * @brief Put the device in standby mode. + * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the + * device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode, + * the device can still wake up itself with the internal timer. But in standby mode, this timer is + * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command + * sent via SPI bus. + * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code + * ERR_COMMAND_DISALLOWED will be returned. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_device_standby(void); + +/** + * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. + * @note The frequency sine wave at the specific channel may be used for test purpose only. + * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. + * This command shouldn't be used when normal Bluetooth activities are ongoing. + * The tone should be stopped by aci_hal_tone_stop() command. + * + * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the + * channel central frequency minus 250 kHz. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +/** + * This command is used to stop the previously started aci_hal_tone_start() command. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_stop(void); + +/** + * @brief This command returns the status of all the connections. + * @note This command returns the status of the 8 Bluetooth low energy links managed by the device. + * @param[out] link_status Array of link status (8 links). See @ref Link_Status. + * @param[out] conn_handle Array of connection handles for each link. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]); + +/** + * @brief This command returns the anchor period and the largest available slot. + * @note This command returns information about the anchor period to help application in selecting + * slot timings when operating in multi-link scenarios. + * @param anchor_period Current anchor period (multiple of 0.625 ms). + * @param max_free_slot Maximum available time (multiple of 0.625 ms) that can be allocated for a new slot. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot); + +/** + * @} + */ + +/** + * @defgroup HAL_Events HAL events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_HAL_INITIALIZED (0x0001) +typedef __packed struct _evt_hal_initialized{ + uint8_t reason_code; /**< Reset reason. See @ref Reset_Reasons */ +} PACKED evt_hal_initialized; + +/** + * This event is generated when an overflow occurs in the event queue read by the external microcontroller. + * This is normally caused when the external microcontroller does not read pending events. + * The returned bitmap indicates which event has been lost. Please note that one bit set to 1 indicates one or + * more occurrences of the particular events. The event EVT_BLUE_HAL_EVENTS_LOST cannot be lost and it will + * be inserted in the event queue as soon as a position is freed in the event queue. This event should not + * happen under normal operating condition where external microcontroller promptly reads events signaled by + * IRQ pin. It is provided to detected unexpected behavior of the external microcontroller or to allow + * application to recover situations where critical events are lost. + */ +#define EVT_BLUE_HAL_EVENTS_LOST_IDB05A1 (0x0002) +typedef __packed struct _evt_hal_events_lost{ + uint8_t lost_events[8]; /**< Bitmap of lost events. Each bit indicates one or more occurrences of the specific event. See @ref Lost_Events */ +} PACKED evt_hal_events_lost_IDB05A1; + + +/** + * This event is given to the application after the @ref ACI_BLUE_INITIALIZED_EVENT + * when a system crash is detected. This events returns system crash information for debugging purposes. + * Information reported are useful to understand the root cause of the crash. + */ +#define EVT_BLUE_HAL_CRASH_INFO_IDB05A1 (0x0003) +typedef __packed struct _evt_hal_crash_info{ + uint8_t crash_type; /**< Type of crash: Assert failed (0), NMI Fault (1), Hard Fault (2) */ + uint32_t sp; /**< SP register */ + uint32_t r0; /**< R0 register */ + uint32_t r1; /**< R1 register */ + uint32_t r2; /**< R2 register */ + uint32_t r3; /**< R3 register */ + uint32_t r12; /**< R12 register */ + uint32_t lr; /**< LR register */ + uint32_t pc; /**< PC register */ + uint32_t xpsr; /**< xPSR register */ + uint8_t debug_data_len; /**< length of debug_data field */ + uint8_t debug_data[VARIABLE_SIZE]; /**< Debug data */ +} PACKED evt_hal_crash_info_IDB05A1; + + +/** + * @} + */ + + +/** + * @anchor Reset_Reasons + * @name Reset Reasons + * See @ref EVT_BLUE_HAL_INITIALIZED. + * @{ + */ +#define RESET_NORMAL 1 /**< Normal startup. */ +#define RESET_UPDATER_ACI 2 /**< Updater mode entered with ACI command */ +#define RESET_UPDATER_BAD_FLAG 3 /**< Updater mode entered due to a bad BLUE flag */ +#define RESET_UPDATER_PIN 4 /**< Updater mode entered with IRQ pin */ +#define RESET_WATCHDOG 5 /**< Reset caused by watchdog */ +#define RESET_LOCKUP 6 /**< Reset due to lockup */ +#define RESET_BROWNOUT 7 /**< Brownout reset */ +#define RESET_CRASH 8 /**< Reset caused by a crash (NMI or Hard Fault) */ +#define RESET_ECC_ERR 9 /**< Reset caused by an ECC error */ +/** + * @} + */ + + +/** + * @defgroup Config_vals Offsets and lengths for configuration values. + * @brief Offsets and lengths for configuration values. + * See aci_hal_write_config_data(). + * @{ + */ + +/** + * @name Configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ +#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ +#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ +#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ +#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. + It can be written only if aci_hal_write_config_data() is the first command after reset. */ +#define CONFIG_DATA_RANDOM_ADDRESS (0x80) /**< Stored static random address. Read-only. */ + +/** + * Select the BlueNRG mode configurations.\n + * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) + * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) + * @li Mode 3: master/slave, 8 connections, RAM1 and RAM2. + * @li Mode 4: master/slave, 4 connections, RAM1 and RAM2 simultaneous scanning and advertising. + */ +#define CONFIG_DATA_MODE_OFFSET (0x2D) + +#define CONFIG_DATA_WATCHDOG_DISABLE (0x2F) /**< Set to 1 to disable watchdog. It is enabled by default. */ +/** + * @} + */ + +/** + * @name Length for configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_LEN (6) +#define CONFIG_DATA_DIV_LEN (2) +#define CONFIG_DATA_ER_LEN (16) +#define CONFIG_DATA_IR_LEN (16) +#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) +#define CONFIG_DATA_MODE_LEN (1) +#define CONFIG_DATA_WATCHDOG_DISABLE_LEN (1) +/** + * @} + */ + +/** + * @anchor Link_Status + * @name Status of the link + * See @ref aci_hal_get_link_status(). + * @{ + */ +#define STATUS_IDLE 0 +#define STATUS_ADVERTISING 1 +#define STATUS_CONNECTED_AS_SLAVE 2 +#define STATUS_SCANNING 3 +#define STATUS_CONNECTED_AS_MASTER 5 +#define STATUS_TX_TEST 6 +#define STATUS_RX_TEST 7 +/** + * @} + */ + +/** + * @} + */ + + /** + * @anchor Lost_Events + * @name Lost events bitmap + * See @ref EVT_BLUE_HAL_EVENTS_LOST. + * @{ + */ +#define EVT_DISCONN_COMPLETE_BIT 0 +#define EVT_ENCRYPT_CHANGE_BIT 1 +#define EVT_READ_REMOTE_VERSION_COMPLETE_BIT 2 +#define EVT_CMD_COMPLETE_BIT 3 +#define EVT_CMD_STATUS_BIT 4 +#define EVT_HARDWARE_ERROR_BIT 5 +#define EVT_NUM_COMP_PKTS_BIT 6 +#define EVT_ENCRYPTION_KEY_REFRESH_BIT 7 +#define EVT_BLUE_HAL_INITIALIZED_BIT 8 +#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE_BIT 9 +#define EVT_BLUE_GAP_PAIRING_CMPLT_BIT 10 +#define EVT_BLUE_GAP_PASS_KEY_REQUEST_BIT 11 +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST_BIT 12 +#define EVT_BLUE_GAP_SECURITY_REQ_INITIATED_BIT 13 +#define EVT_BLUE_GAP_BOND_LOST_BIT 14 +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE_BIT 15 +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_BIT 16 +#define EVT_BLUE_L2CAP_CONN_UPDATE_RESP_BIT 17 +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT_BIT 18 +#define EVT_BLUE_L2CAP_CONN_UPDATE_REQ_BIT 19 +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_BIT 20 +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT_BIT 21 +#define EVT_BLUE_EXCHANGE_MTU_RESP_BIT 22 +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP_BIT 23 +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP_BIT 24 +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP_BIT 25 +#define EVT_BLUE_ATT_READ_RESP_BIT 26 +#define EVT_BLUE_ATT_READ_BLOB_RESP_BIT 27 +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP_BIT 28 +#define EVT_BLUE_ATT_READ_BY_GROUP_RESP_BIT 29 +#define EVT_BLUE_ATT_WRITE_RESP_BIT 30 +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP_BIT 31 +#define EVT_BLUE_ATT_EXEC_WRITE_RESP_BIT 32 +#define EVT_BLUE_GATT_INDICATION_BIT 33 +#define EVT_BLUE_GATT_NOTIFICATION_BIT 34 +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE_BIT 35 +#define EVT_BLUE_GATT_ERROR_RESP_BIT 36 +#define EVT_BLUE_GATT_DISC_READ_CHARAC_BY_UUID_RESP_BIT 37 +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ_BIT 38 +#define EVT_BLUE_GATT_READ_PERMIT_REQ_BIT 39 +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ_BIT 40 +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_BIT 41 +#define EVT_BLUE_GATT_SERVER_RX_CONFIRMATION_BIT 42 +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ_BIT 43 +#define EVT_LL_CONNECTION_COMPLETE_BIT 44 +#define EVT_LL_ADVERTISING_REPORT_BIT 45 +#define EVT_LL_CONNECTION_UPDATE_COMPLETE_BIT 46 +#define EVT_LL_READ_REMOTE_USED_FEATURES_BIT 47 +#define EVT_LL_LTK_REQUEST_BIT 48 +/** + * @} + */ + +/** + * @name Hardware error event codes + * See @ref EVT_HARDWARE_ERROR. + * @{ + */ +/** + * Error on the SPI bus has been detected, most likely caused by incorrect SPI configuration on the external micro-controller. + */ +#define SPI_FRAMING_ERROR 0 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define RADIO_STATE_ERROR 1 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define TIMER_OVERRUN_ERROR 2 + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,166 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_l2cap_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with L2CAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_L2CAP_ACI_H__ +#define __BLUENRG_L2CAP_ACI_H__ + +/** + *@addtogroup L2CAP L2CAP + *@brief L2CAP layer. + *@{ + */ + +/** + *@defgroup L2CAP_Functions L2CAP functions + *@brief API for L2CAP layer. + *@{ + */ + +/** + * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. + * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request + * (accepts or rejects). + * @param conn_handle Connection handle on which the connection parameter update request has to be sent. + * @param interval_min Defines minimum value for the connection event interval in the following manner: + * connIntervalMin = interval_min x 1.25ms + * @param interval_max Defines maximum value for the connection event interval in the following manner: + * connIntervalMax = interval_max x 1.25ms + * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). + * @param timeout_multiplier Defines connection timeout parameter in the following manner: + * timeout_multiplier x 10ms. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier); +/** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param min_ce_length Minimum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_ce_length Maximum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept); + /** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept); + +/** + * @} + */ + +/** + * @defgroup L2CAP_Events L2CAP events + * @{ + */ + +/** + * This event is generated when the master responds to the L2CAP connection update request packet. + * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. + */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef __packed struct _evt_l2cap_conn_upd_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ +/** + * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. + * @li 0x01 in case of Command Reject. + */ + uint8_t code; + uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ + uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ +/** + * Result code (parameters accepted or rejected) in case of Connection Parameter Update + * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). + */ + uint16_t result; +} PACKED evt_l2cap_conn_upd_resp; + +/** + * This event is generated when the master does not respond to the connection update request + * within 30 seconds. + */ +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) +typedef __packed struct _evt_l2cap_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */ +} PACKED evt_l2cap_procedure_timeout; + +/** + * The event is given by the L2CAP layer when a connection update request is received from the slave. + * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). + */ +#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) +typedef __packed struct _evt_l2cap_conn_upd_req{ +/** + * Handle of the connection for which the connection update request has been received. + * The same handle has to be returned while responding to the event with the command + * aci_l2cap_connection_parameter_update_response(). + */ + uint16_t conn_handle; + uint8_t event_data_length; /**< Length of following data. */ +/** + * This is the identifier which associates the request to the + * response. The same identifier has to be returned by the upper + * layer in the command aci_l2cap_connection_parameter_update_response(). + */ + uint8_t identifier; + uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ + uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ +} PACKED evt_l2cap_conn_upd_req; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_updater_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with updater commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_UPDATER_ACI_H__ +#define __BLUENRG_UPDATER_ACI_H__ + +#include <ble_compiler.h> + +/** + * @defgroup Updater Updater + * @brief Updater. + * @{ + */ + +/** + * @defgroup Updater_Functions Updater functions + * @brief API for BlueNRG Updater. + * @{ + */ + +tBleStatus aci_updater_start(void); + +tBleStatus aci_updater_reboot(void); + +tBleStatus aci_get_updater_version(uint8_t *version); + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); + +tBleStatus aci_erase_blue_flag(void); + +tBleStatus aci_reset_blue_flag(void); + +tBleStatus aci_updater_erase_sector(uint32_t address); + +tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); + +tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); + +tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); + +tBleStatus aci_updater_hw_version(uint8_t *version); + +/** + * @} + */ + +/** + * @defgroup Updater_Events Updater events + * @{ + */ +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_INITIALIZED (0x0001) +typedef __packed struct _evt_blue_initialized{ + uint8_t reason_code; +} PACKED evt_blue_initialized; +/** + * @} + */ + +/** + * @} + */ + + + +#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,204 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_utils.h +* Author : AMS - VMA, RF Application Team +* Version : V1.0.1 +* Date : 03-October-2014 +* Description : Header file for BlueNRG utility functions +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + * @file bluenrg_utils.h + * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description + * + * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> +**/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLUENRG_UTILS_H +#define __BLUENRG_UTILS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ble_hal_types.h" +#include "ble_compiler.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct{ + uint8_t stack_mode; + uint8_t day; + uint8_t month; + uint8_t year; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint16_t hs_startup_time; /* In system time units*/ +} IFR_config2_TypeDef; + +/** + * Structure inside IFR for configuration options. + */ +typedef __packed struct{ + uint8_t cold_ana_act_config_table[64]; + uint8_t hot_ana_config_table[64]; + uint8_t stack_mode; + uint8_t gpio_config; + uint8_t rsrvd1[2]; + uint32_t rsrvd2[3]; + uint32_t max_conn_event_time; + uint32_t ls_crystal_period; + uint32_t ls_crystal_freq; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint8_t rsrvd3; + uint16_t hs_startup_time; /* In system time units*/ + uint8_t rsrvd4[2]; + uint32_t uid; + uint8_t rsrvd5; + uint8_t year; + uint8_t month; + uint8_t day; + uint32_t unused[5]; +} PACKED IFR_config_TypeDef; + +/* Exported constants --------------------------------------------------------*/ +extern const IFR_config_TypeDef IFR_config; + +/* Exported macros -----------------------------------------------------------*/ +#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)+1) +#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) + +/* Convert 2 digit BCD number to an integer */ +#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) + +/* Convert 2 digit number to a BCD number */ +#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) + +/** + * Return values + */ +#define BLE_UTIL_SUCCESS 0 +#define BLE_UTIL_UNSUPPORTED_VERSION 1 +#define BLE_UTIL_WRONG_IMAGE_SIZE 2 +#define BLE_UTIL_ACI_ERROR 3 +#define BLE_UTIL_CRC_ERROR 4 +#define BLE_UTIL_PARSE_ERROR 5 +#define BLE_UTIL_WRONG_VERIFY 6 + +/* Exported functions ------------------------------------------------------- */ +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int program_device(const uint8_t *fw_image, uint32_t fw_size); + +/** + * @brief Read raw data from IFR (3 64-bytes blocks). + * @param data Pointer to the buffer that will contain the read data. + * Its size must be 192 bytes. This data can be parsed by + * parse_IFR_data_config(). + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION) + */ +int read_IFR(uint8_t data[192]); + +/** + * @brief Verify raw data from IFR (3 64-bytes blocks). + * @param ifr_data Pointer to the buffer that will contain the data to verify. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) + */ +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); + +/** + * @brief Program raw data to IFR (3 64-bytes blocks). + * @param ifr_image Pointer to the buffer that will contain the data to program. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful + */ +int program_IFR(const IFR_config_TypeDef *ifr_image); + +/** + * @brief Parse IFR raw data. + * @param data Pointer to the raw data: last 64 bytes read from IFR sector. + * @param IFR_config Data structure that will be filled with parsed data. + * @retval None + */ +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); + +/** + * @brief Check for the correctness of parsed data. + * @param IFR_config Data structure filled with parsed data. + * @retval int It returns 0 if successful, or PARSE_ERROR in case data is + * not correct. + */ +int IFR_validate(IFR_config2_TypeDef *IFR_config); + +/** + * @brief Modify IFR data. (Last 64-bytes block). + * @param IFR_config Structure that contains the new parameters inside the + * IFR configuration data. + * @note It is highly recommended to parse the IFR configuration from + * a working IFR block (this should be done with parse_IFR_data_config()). + * Then it is possible to write the new parameters inside the IFR_config + * structure. + * @param data Pointer to the buffer that contains the original data. It + * will be modified according to the new data in the IFR_config + * structure. Then this data must be written in the last + * 64-byte block in the IFR. + * Its size must be 64 bytes. + * @retval None + */ +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); + +/** + * @brief Get BlueNRG hardware and firmware version + * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). + * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN + * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. + * @retval Status of the call + */ +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); + +/** + * @brief Get BlueNRG updater version + * @param version This parameter returns the updater version. If the updadter version is 0x03 + * the chip has the updater old, needs to update the bootloader. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterVersion(uint8_t *version); + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version); + +/** + * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on + * the HW bootloader related to the 32 MHz external crystal oscillator. + * @retval TRUE if the HW bootloader is already patched, FALSE otherwise + */ +uint8_t isHWBootloader_Patched(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__BLUENRG_UTILS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file bluenrg_targets.h + * @author AST / EST + * @version V0.0.1 + * @date 24-July-2015 + * @brief This header file is intended to manage the differences between + * the different supported base-boards which might mount the + * X_NUCLEO_IDB0XA1 BlueNRG BLE Expansion Board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent from recursive inclusion --------------------------------*/ +#ifndef _BLUENRG_TARGETS_H_ +#define _BLUENRG_TARGETS_H_ + +#if !defined(BLUENRG_PIN_SPI_MOSI) +#define BLUENRG_PIN_SPI_MOSI (D11) +#endif +#if !defined(BLUENRG_PIN_SPI_MISO) +#define BLUENRG_PIN_SPI_MISO (D12) +#endif +#if !defined(BLUENRG_PIN_SPI_nCS) +#define BLUENRG_PIN_SPI_nCS (A1) +#endif +#if !defined(BLUENRG_PIN_SPI_RESET) +#define BLUENRG_PIN_SPI_RESET (D7) +#endif +#if !defined(BLUENRG_PIN_SPI_IRQ) +#define BLUENRG_PIN_SPI_IRQ (A0) +#endif + +/* NOTE: Refer to README for further details regarding BLUENRG_PIN_SPI_SCK */ +#if !defined(BLUENRG_PIN_SPI_SCK) +#define BLUENRG_PIN_SPI_SCK (D3) +#endif + +/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv) + * Mode 0x01: slave or master, 1 connection + * Mode 0x02: slave or master, 1 connection + * Mode 0x03: master/slave, 8 connections + * Mode 0x04: master/slave, 4 connections (simultaneous scanning and advertising) + * Check Table 285 of + * BlueNRG-MS Bluetooth LE stack application command interface (ACI) User Manual (UM1865) at st.com + */ +#if !defined(BLUENRG_STACK_MODE) +#define BLUENRG_STACK_MODE (0x04) +#endif + +#endif // _BLUENRG_TARGTES_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef _BTLE_H_ +#define _BTLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "bluenrg_aci.h" +#include "ble_hci_const.h" +#include "bluenrg_hal_aci.h" +#include "stm32_bluenrg_ble.h" +#include "bluenrg_gap.h" +#include "bluenrg_gatt_server.h" + +extern uint16_t g_gap_service_handle; +extern uint16_t g_appearance_char_handle; +extern uint16_t g_device_name_char_handle; +extern uint16_t g_preferred_connection_parameters_char_handle; + +void btleInit(void); +void SPI_Poll(void); +void User_Process(void); +void setConnectable(void); +void setVersionString(uint8_t hwVersion, uint16_t fwVersion); +const char* getVersionString(void); +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type); + + +extern int btle_handler_pending; +extern void btle_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.h + * @author CL + * @version V1.0.1 + * @date 15-June-2014 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_BLUENRG_BLE_H +#define __STM32_BLUENRG_BLE_H + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdint.h> +#include "ble_gp_timer.h" +#include "ble_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup X-NUCLEO-IDB04A1 + * @{ + */ + +/** @addtogroup STM32_BLUENRG_BLE + * @{ + */ + +/** @defgroup STM32_BLUENRG_BLE_Exported_Functions + * @{ + */ + +// FIXME: add prototypes for BlueNRG here +void BlueNRG_RST(void); +uint8_t BlueNRG_DataPresent(void); +void BlueNRG_HW_Bootloader(void); +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size); +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, + uint8_t Nb_bytes1, + uint8_t Nb_bytes2); +void Clear_SPI_EXTI_Flag(void); + +void print_csv_time(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_BLUENRG_BLE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_debug.h" + +#ifndef __PAYLOAD_H__ +#define __PAYLOAD_H__ + +class UnitPayload +{ +public: + uint8_t length; + uint8_t id; + uint8_t *data; + uint8_t *idptr; + + + + void set_length(uint8_t l) { + length=l; + } + + void set_id(uint8_t i) { + id=i; + } + + void set_data(uint8_t* data1) { + for(int j=0;j<length;j++) + { + data[j]=data1[j]; + } + } + + uint8_t get_length() { + return length; + } + + uint8_t get_id() { + return id; + } + + uint8_t* get_data() { + return data; + } + +}; + +class Payload { + UnitPayload *payload; + int stringLength; + int payloadUnitCount; + +public: + Payload(const uint8_t *tokenString, uint8_t string_ength); + Payload(); + ~Payload(); + uint8_t getPayloadUnitCount(); + + uint8_t getIDAtIndex(int index); + uint8_t getLengthAtIndex(int index); + uint8_t* getDataAtIndex(int index); + int8_t getInt8AtIndex(int index); + uint16_t getUint16AtIndex(int index); + uint8_t* getSerializedAdDataAtIndex(int index); +}; + + +class PayloadUnit { +private: + uint8_t* lenPtr; + uint8_t* adTypePtr; + uint8_t* dataPtr; + +public: + PayloadUnit() { + lenPtr = NULL; + adTypePtr = NULL; + dataPtr = NULL; + } + + PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { + lenPtr = len; + adTypePtr = adType; + dataPtr = data; + } + + void setLenPtr(uint8_t *len) { + lenPtr = len; + } + + void setAdTypePtr(uint8_t *adType) { + adTypePtr = adType; + } + + void setDataPtr(uint8_t *data) { + dataPtr = data; + } + + uint8_t* getLenPtr() { + return lenPtr; + } + + uint8_t* getAdTypePtr() { + return adTypePtr; + } + + uint8_t* getDataPtr() { + return dataPtr; + } + + void printDataAsHex() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("0x%x ", dataPtr[i]); + } + PRINTF("\n"); + } + + void printDataAsString() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("%c", dataPtr[i]); + } + PRINTF("\n"); + } + +}; + +class PayloadPtr { +private: + PayloadUnit *unit; + int payloadUnitCount; +public: + PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + int stringLength = string_ength; + payloadUnitCount = 0; + + int index = 0; + while(index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + // allocate memory to unit + unit = new PayloadUnit[payloadUnitCount]; + int i = 0; + int nextUnitOffset = 0; + + while(i<payloadUnitCount) { + unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); + unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); + unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); + + nextUnitOffset += *unit[i].getLenPtr()+1; + i++; + + } + } + + PayloadUnit getUnitAtIndex(int index) { + return unit[index]; + } + + int getPayloadUnitCount() { return payloadUnitCount; } + + ~PayloadPtr() { + if(unit) delete[] unit; + + unit = NULL; + } +}; + +#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include "ble_status.h" +#include "ble_hal_types.h" + +#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do {\ + uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ + }while(0) + + +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); + +#endif // __UTIL_H__ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/mbed_lib.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "bluenrg", + "target_overrides": { + "K64F": { + "target.macros_add": ["BLUENRG_PIN_SPI_SCK=D13"] + }, + "DISCO_L475VG_IOT01A": { + "target.macros_add": ["BLUENRG_PIN_SPI_MOSI=PC_12", + "BLUENRG_PIN_SPI_MISO=PC_11", + "BLUENRG_PIN_SPI_nCS=PD_13", + "BLUENRG_PIN_SPI_RESET=PA_8", + "BLUENRG_PIN_SPI_IRQ=PE_6", + "BLUENRG_PIN_SPI_SCK=PC_10"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,37 @@ +{ + "name": "x-nucleo-idb0xa1", + "version": "2.2.0", + "description": "ST driver for the mbed BLE API.", + "keywords": [ + "expansion", + "board", + "x-nucleo", + "nucleo", + "ST", + "STM", + "Bluetooth", + "BLE" + ], + "author": "Andrea Palmieri", + "repository": { + "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git", + "type": "git" + }, + "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "extraIncludes": [ + "x-nucleo-idb0xa1", + "x-nucleo-idb0xa1/utils", + "x-nucleo-idb0xa1/platform", + "x-nucleo-idb0xa1/bluenrg-hci" + ], + "dependencies": { + "mbed-drivers": ">=0.11.3", + "ble": "^2.7.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,474 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.cpp + * @author STMicroelectronics + * @brief Implementation of BLEDeviceInstanceBase + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGDevice + * @brief BlueNRG BLE_API Device Adaptation + * @{ + */ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGDevice.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" + +#include "btle.h" +#include "ble_utils.h" +#include "ble_osal.h" + +#include "ble_debug.h" +#include "stm32_bluenrg_ble.h" + +extern "C" { + #include "ble_hci.h" + #include "bluenrg_utils.h" +} + +#define HEADER_SIZE 5 +#define MAX_BUFFER_SIZE 255 + +/** + * The singleton which represents the BlueNRG transport for the BLEDevice. + * + * See file 'bluenrg_targets.h' for details regarding the peripheral pins used! + */ +#include "bluenrg_targets.h" + +BlueNRGDevice bluenrgDeviceInstance(BLUENRG_PIN_SPI_MOSI, + BLUENRG_PIN_SPI_MISO, + BLUENRG_PIN_SPI_SCK, + BLUENRG_PIN_SPI_nCS, + BLUENRG_PIN_SPI_RESET, + BLUENRG_PIN_SPI_IRQ); + +/** +* BLE-API requires an implementation of the following function in order to +* obtain its transport handle. +*/ +BLEInstanceBase * +createBLEInstance(void) +{ + return (&bluenrgDeviceInstance); +} + +/**************************************************************************/ +/** + @brief Constructor + * @param mosi mbed pin to use for MOSI line of SPI interface + * @param miso mbed pin to use for MISO line of SPI interface + * @param sck mbed pin to use for SCK line of SPI interface + * @param cs mbed pin to use for not chip select line of SPI interface + * @param rst mbed pin to use for BlueNRG reset + * @param irq mbed pin for BlueNRG IRQ +*/ +/**************************************************************************/ +BlueNRGDevice::BlueNRGDevice(PinName mosi, + PinName miso, + PinName sck, + PinName cs, + PinName rst, + PinName irq) : + isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq) +{ + // Setup the spi for 8 bit data, low clock polarity, + // 1-edge phase, with an 8MHz clock rate + spi_.format(8, 0); + spi_.frequency(8000000); + + // Deselect the BlueNRG chip by keeping its nCS signal high + nCS_ = 1; + + wait_us(500); + + // Prepare communication between the host and the BlueNRG SPI interface + HCI_Init(); + + // Set the interrupt handler for the device + irq_.mode(PullDown); // set irq mode + irq_.rise(&HCI_Isr); +} + +/**************************************************************************/ +/** + @brief Destructor +*/ +/**************************************************************************/ +BlueNRGDevice::~BlueNRGDevice(void) +{ +} + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param hw_version The HW version is written to this parameter + * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise + */ +uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version) +{ + uint8_t status; + + status = getBlueNRGUpdaterHWVersion(hw_version); + + return (status); +} + +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns BLE_STATUS_SUCCESS on success, or a number + * not equal to 0 in case of error + * (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size) +{ + int status = program_device(fw_image, fw_size); + + return (status); +} + + +/** + * @brief Initialises anything required to start using BLE + * @param[in] instanceID + * The ID of the instance to initialize. + * @param[in] callback + * A callback for when initialization completes for a BLE + * instance. This is an optional parameter set to NULL when not + * supplied. + * + * @return BLE_ERROR_NONE if the initialization procedure was started + * successfully. + */ +ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback) +{ + if (isInitialized) { + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_ALREADY_INITIALIZED + }; + callback.call(&context); + return BLE_ERROR_ALREADY_INITIALIZED; + } + + // Init the BlueNRG/BlueNRG-MS stack + btleInit(); + + isInitialized = true; + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_NONE + }; + callback.call(&context); + + return BLE_ERROR_NONE; +} + + +/** + @brief Resets the BLE HW, removing any existing services and + characteristics + @param[in] void + @returns void +*/ +void BlueNRGDevice::reset(void) +{ + /* Reset BlueNRG SPI interface. Hold reset line to 0 for 1500us */ + rst_ = 0; + wait_us(1500); + rst_ = 1; + + /* Wait for the radio to come back up */ + wait_us(5000); +} + +/*! + @brief Wait for any BLE Event like BLE Connection, Read Request etc. + @param[in] void + @returns char * +*/ +void BlueNRGDevice::waitForEvent(void) +{ + bool must_return = false; + + do { + bluenrgDeviceInstance.processEvents(); + + if(must_return) return; + + __WFE(); /* it is recommended that SEVONPEND in the + System Control Register is NOT set */ + must_return = true; /* after returning from WFE we must guarantee + that conrol is given back to main loop before next WFE */ + } while(true); + +} + +/*! + @brief get GAP version + @brief Get the BLE stack version information + @param[in] void + @returns char * + @returns char * +*/ +const char *BlueNRGDevice::getVersion(void) +{ + return getVersionString(); +} + +/**************************************************************************/ +/*! + @brief get reference to GAP object + @param[in] void + @returns Gap& +*/ +/**************************************************************************/ +Gap &BlueNRGDevice::getGap() +{ + return BlueNRGGap::getInstance(); +} + +const Gap &BlueNRGDevice::getGap() const +{ + return BlueNRGGap::getInstance(); +} + +/**************************************************************************/ +/*! + @brief get reference to GATT server object + @param[in] void + @returns GattServer& +*/ +/**************************************************************************/ +GattServer &BlueNRGDevice::getGattServer() +{ + return BlueNRGGattServer::getInstance(); +} + +const GattServer &BlueNRGDevice::getGattServer() const +{ + return BlueNRGGattServer::getInstance(); +} + +/**************************************************************************/ +/*! + @brief shut down the BLE device + @param[out] error if any +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::shutdown(void) { + PRINTF("BlueNRGDevice::reset\n"); + + if (!isInitialized) { + return BLE_ERROR_INITIALIZATION_INCOMPLETE; + } + + /* Reset the BlueNRG device first */ + reset(); + + /* Shutdown the BLE API and BlueNRG glue code */ + ble_error_t error; + + /* GattServer instance */ + error = BlueNRGGattServer::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* GattClient instance */ + error = BlueNRGGattClient::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* Gap instance */ + error = BlueNRGGap::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + isInitialized = false; + + PRINTF("BlueNRGDevice::reset complete\n"); + return BLE_ERROR_NONE; + +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size) +{ + uint16_t byte_count; + uint8_t len = 0; + uint8_t char_ff = 0xff; + volatile uint8_t read_char; + + uint8_t i = 0; + volatile uint8_t tmpreg; + + uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00}; + uint8_t header_slave[HEADER_SIZE]; + + /* Select the chip */ + nCS_ = 0; + + /* Read the header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = (uint8_t)(tmpreg); + } + + if (header_slave[0] == 0x02) { + /* device is ready */ + byte_count = (header_slave[4]<<8)|header_slave[3]; + + if (byte_count > 0) { + + /* avoid to read more data that size of the buffer */ + if (byte_count > buff_size){ + byte_count = buff_size; + } + + for (len = 0; len < byte_count; len++){ + read_char = spi_.write(char_ff); + buffer[len] = read_char; + } + } + } + /* Release CS line to deselect the chip */ + nCS_ = 1; + + // Add a small delay to give time to the BlueNRG to set the IRQ pin low + // to avoid a useless SPI read at the end of the transaction + for(volatile int i = 0; i < 2; i++)__NOP(); + +#ifdef PRINT_CSV_FORMAT + if (len > 0) { + print_csv_time(); + for (int i=0; i<len; i++) { + PRINT_CSV(" %02x", buffer[i]); + } + PRINT_CSV("\n"); + } +#endif + + return len; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRGDevice::spiWrite(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t result = 0; + uint32_t i; + volatile uint8_t tmpreg; + + unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00}; + + disable_irq(); + + /* CS reset */ + nCS_ = 0; + + /* Exchange header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = tmpreg; + } + + if (header_slave[0] == 0x02) { + /* SPI is ready */ + if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { + + /* Buffer is big enough */ + for (i = 0; i < Nb_bytes1; i++) { + spi_.write(*(data1 + i)); + } + for (i = 0; i < Nb_bytes2; i++) { + spi_.write(*(data2 + i)); + } + } else { + /* Buffer is too small */ + result = -2; + } + } else { + /* SPI is not ready */ + result = -1; + } + + /* Release CS line */ + //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); + nCS_ = 1; + + enable_irq(); + + return result; +} + +bool BlueNRGDevice::dataPresent() +{ + return (irq_ == 1); +} + +void BlueNRGDevice::disable_irq() +{ + irq_.disable_irq(); +} + +void BlueNRGDevice::enable_irq() +{ + irq_.enable_irq(); +} + +void BlueNRGDevice::processEvents() { + btle_handler(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,68 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattClient.h" + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + uuid = uuidIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + + void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) { + lastHandle = lastHandleIn; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1477 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file BlueNRGGap.cpp + * @author STMicroelectronics + * @brief Implementation of BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGap + * @brief BlueNRG BLE_API GAP Adaptation + * @{ + */ + +#include "BlueNRGDevice.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_payload.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/* + * Utility to process GAP specific events (e.g., Advertising timeout) + */ +void BlueNRGGap::Process(void) +{ + if(AdvToFlag) { + AdvToFlag = false; + stopAdvertising(); + } + + if(ScanToFlag) { + ScanToFlag = false; + stopScan(); + } +} + +/**************************************************************************/ +/*! + @brief Sets the advertising parameters and payload for the device. + Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API + + @params[in] advData + The primary advertising data payload + @params[in] scanResponse + The optional Scan Response payload if the advertising + type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED + in \ref GapAdveritinngParams + + @returns \ref ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @retval BLE_ERROR_BUFFER_OVERFLOW + The proposed action would cause a buffer overflow. All + advertising payloads must be <= 31 bytes, for example. + + @retval BLE_ERROR_NOT_IMPLEMENTED + A feature was requested that is not yet supported in the + nRF51 firmware or hardware. + + @retval BLE_ERROR_PARAM_OUT_OF_RANGE + One of the proposed values is outside the valid range. + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) +{ + PRINTF("BlueNRGGap::setAdvertisingData\n\r"); + /* Make sure we don't exceed the advertising payload length */ + if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + PRINTF("Exceeded the advertising payload length\n\r"); + return BLE_ERROR_BUFFER_OVERFLOW; + } + + /* Make sure we have a payload! */ + if (advData.getPayloadLen() != 0) { + PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); + + /* Align the GAP Service Appearance Char value coherently + This setting is duplicate (see below GapAdvertisingData::APPEARANCE) + since BLE API has an overloaded function for appearance + */ + STORE_LE_16(deviceAppearance, advData.getAppearance()); + setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0])); + + + for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { + loadPtr.getUnitAtIndex(index); + + PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); + PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); + + switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { + /**< TX Power Level (in dBm) */ + case GapAdvertisingData::TX_POWER_LEVEL: + { + PRINTF("Advertising type: TX_POWER_LEVEL\n\r"); + int8_t enHighPower = 0; + int8_t paLevel = 0; + + int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); + tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); +#ifdef DEBUG + PRINTF("dbm=%d, ret=%d\n\r", dbm, ret); + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); +#endif + if(ret == BLE_STATUS_SUCCESS) { + aci_hal_set_tx_power_level(enHighPower, paLevel); + } + break; + } + /**< Appearance */ + case GapAdvertisingData::APPEARANCE: + { + PRINTF("Advertising type: APPEARANCE\n\r"); + + GapAdvertisingData::Appearance appearanceP; + memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2); + + PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]); + /* Align the GAP Service Appearance Char value coherently */ + setAppearance(appearanceP); + break; + } + + } // end switch + + } //end for + + } + + // update the advertising data in the shield if advertising is running + if (state.advertising == 1) { + tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS != ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload()); + if (ret) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + } + + _advData = advData; + _scanResponse = scanResponse; + + return BLE_ERROR_NONE; +} + +/* + * Utility to set ADV timeout flag + */ +void BlueNRGGap::setAdvToFlag(void) { + AdvToFlag = true; + signalEventsToProcess(); +} + +/* + * ADV timeout callback + */ +#ifdef AST_FOR_MBED_OS +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().stopAdvertising(); +} +#else +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().setAdvToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getAdvTimeout(); + t.detach(); /* disable the callback from the timeout */ +} +#endif /* AST_FOR_MBED_OS */ + +/* + * Utility to set SCAN timeout flag + */ +void BlueNRGGap::setScanToFlag(void) { + ScanToFlag = true; + signalEventsToProcess(); +} + +static void scanTimeoutCB(void) +{ + BlueNRGGap::getInstance().setScanToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getScanTimeout(); + t.detach(); /* disable the callback from the timeout */ +} + +/**************************************************************************/ +/*! + @brief Starts the BLE HW, initialising any services that were + added before this function was called. + + @param[in] params + Basic advertising details, including the advertising + delay, timeout and how the device should be advertised + + @note All services must be added before calling this function! + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ + +ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) +{ + tBleStatus ret; + int err; + + /* Make sure we support the advertising type */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { + /* ToDo: This requires a proper security implementation, etc. */ + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /* Check interval range */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { + /* Min delay is slightly longer for unconnectable devices */ + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } else { + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } + + /* Check timeout is zero for Connectable Directed */ + if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { + /* Timeout must be 0 with this type, although we'll never get here */ + /* since this isn't implemented yet anyway */ + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* Check timeout for other advertising types */ + if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && + (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* + * Advertising filter policy setting + * FIXME: the Security Manager should be implemented + */ + AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode(); + if(mode != ADV_POLICY_IGNORE_WHITELIST) { + ret = aci_gap_configure_whitelist(); + if(ret != BLE_STATUS_SUCCESS) { + PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret); + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } + + uint8_t advFilterPolicy = NO_WHITE_LIST_USE; + switch(mode) { + case ADV_POLICY_FILTER_SCAN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN; + break; + case ADV_POLICY_FILTER_CONN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN; + break; + case ADV_POLICY_FILTER_ALL_REQS: + advFilterPolicy = WHITE_LIST_FOR_ALL; + break; + default: + advFilterPolicy = NO_WHITE_LIST_USE; + break; + } + + /* Check the ADV type before setting scan response data */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED || + params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) { + + /* set scan response data */ + PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen()); + ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS!=ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + } else { + hci_le_set_scan_resp_data(0, NULL); + } + + setAdvParameters(); + PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType()); + + err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload()); + + if (err) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + + tBDAddr dummy_addr = { 0 }; + uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval; + uint16_t advIntervalMax = advIntervalMin + 1; + + err = hci_le_set_advertising_parameters( + advIntervalMin, + advIntervalMax, + params.getAdvertisingType(), + addr_type, + 0x00, + dummy_addr, + /* all channels */ 7, + advFilterPolicy + ); + + if (err) { + PRINTF("impossible to set advertising parameters\n\r"); + PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1); + PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy); + return BLE_ERROR_INVALID_PARAM; + } + + err = hci_le_set_advertise_enable(0x01); + if (err) { + PRINTF("impossible to start advertising\n\r"); + return BLE_ERROR_UNSPECIFIED; + } + + if(params.getTimeout() != 0) { + PRINTF("!!! attaching adv to!!!\n"); +#ifdef AST_FOR_MBED_OS + minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000)); +#else + advTimeout.attach(advTimeoutCB, params.getTimeout()); +#endif + } + + return BLE_ERROR_NONE; + +} + + +/**************************************************************************/ +/*! + @brief Stops the BLE HW and disconnects from any devices + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::stopAdvertising(void) +{ + if(state.advertising == 1) { + + int err = hci_le_set_advertise_enable(0); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + PRINTF("Advertisement stopped!!\n\r") ; + //Set GapState_t::advertising state + state.advertising = 0; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason) +{ + tBleStatus ret; + + ret = aci_gap_terminate(connectionHandle, reason); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_COMMAND_DISALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason) +{ + return disconnect(m_connectionHandle, reason); +} + +/**************************************************************************/ +/*! + @brief Sets the 16-bit connection handle + + @param[in] conn_handle + Connection Handle which is set in the Gap Instance + + @returns void +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionHandle(uint16_t conn_handle) +{ + m_connectionHandle = conn_handle; +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit connection handle + + @param[in] void + + @returns uint16_t + Connection Handle of the Gap Instance +*/ +/**************************************************************************/ +uint16_t BlueNRGGap::getConnectionHandle(void) +{ + return m_connectionHandle; +} + +/**************************************************************************/ +/*! + @brief Sets the BLE device address. SetAddress will reset the BLE + device and re-initialize BTLE. Will not start advertising. + + @param[in] type + Type of Address + + @param[in] address[6] + Value of the Address to be set + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address) +{ + if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if(type == BLEProtocol::AddressType::PUBLIC){ + tBleStatus ret = aci_hal_write_config_data( + CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + address + ); + if(ret != BLE_STATUS_SUCCESS) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } else if (type == BLEProtocol::AddressType::RANDOM_STATIC) { + // ensure that the random static address is well formed + if ((address[5] & 0xC0) != 0xC0) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // thanks to const correctness of the API ... + tBDAddr random_address = { 0 }; + memcpy(random_address, address, sizeof(random_address)); + int err = hci_le_set_random_address(random_address); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // It is not possible to get the bluetooth address when it is set + // store it locally in class data member + memcpy(bdaddr, address, sizeof(bdaddr)); + } else { + // FIXME random addresses are not supported yet + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + // if we're here then the address was correctly set + // commit it inside the addr_type + addr_type = type; + isSetAddress = true; + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Returns boolean if the address of the device has been set + or not + + @returns bool + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +bool BlueNRGGap::getIsSetAddress() +{ + return isSetAddress; +} + +/**************************************************************************/ +/*! + @brief Returns the address of the device if set + + @returns Pointer to the address if Address is set else NULL + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) +{ + uint8_t bdaddr[BDADDR_SIZE]; + uint8_t data_len_out; + + // precondition, check that pointers in input are valid + if (typeP == NULL || address == NULL) { + return BLE_ERROR_INVALID_PARAM; + } + + if (addr_type == BLEProtocol::AddressType::PUBLIC) { + tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr); + if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) { + return BLE_ERROR_UNSPECIFIED; + } + } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) { + // FIXME hci_read_bd_addr and + // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1 + // does not work, use the address stored in class data member + memcpy(bdaddr, this->bdaddr, sizeof(bdaddr)); + } else { + // FIXME: should be implemented with privacy features + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + *typeP = addr_type; + memcpy(address, bdaddr, BDADDR_SIZE); + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief obtains preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + + if (!g_preferred_connection_parameters_char_handle) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // Peripheral preferred connection parameters are an array of 4 uint16_t + uint8_t parameters_packed[parameter_size * 4]; + uint16_t bytes_read = 0; + + tBleStatus err = aci_gatt_read_handle_value( + g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE, + sizeof(parameters_packed), + &bytes_read, + parameters_packed + ); + + PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read); + + // check that the read succeed and the result have the expected length + if (err || bytes_read != sizeof(parameters_packed)) { + return BLE_ERROR_UNSPECIFIED; + } + + // memcpy field by field + memcpy(¶ms->minConnectionInterval, parameters_packed, parameter_size); + memcpy(¶ms->maxConnectionInterval, ¶meters_packed[parameter_size], parameter_size); + memcpy(¶ms->slaveLatency, ¶meters_packed[2 * parameter_size], parameter_size); + memcpy(¶ms->connectionSupervisionTimeout, ¶meters_packed[3 * parameter_size], parameter_size); + + return BLE_ERROR_NONE; +} + + +/**************************************************************************/ +/*! + @brief sets preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + uint8_t parameters_packed[parameter_size * 4]; + + // ensure that parameters are correct + // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC + if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) && + params->minConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) && + params->maxConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (params->slaveLatency > 0x01F3) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) && + params->connectionSupervisionTimeout != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // copy the parameters inside the byte array + memcpy(parameters_packed, ¶ms->minConnectionInterval, parameter_size); + memcpy(¶meters_packed[parameter_size], ¶ms->maxConnectionInterval, parameter_size); + memcpy(¶meters_packed[2 * parameter_size], ¶ms->slaveLatency, parameter_size); + memcpy(¶meters_packed[3 * parameter_size], ¶ms->connectionSupervisionTimeout, parameter_size); + + tBleStatus err = aci_gatt_update_char_value( + g_gap_service_handle, + g_preferred_connection_parameters_char_handle, + /* offset */ 0, + sizeof(parameters_packed), + parameters_packed + ); + + if (err) { + PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ; + switch (err) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief updates preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) +{ + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(gapRole == Gap::CENTRAL) { + ret = aci_gap_start_connection_update(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout, + CONN_L1, CONN_L2); + } else { + ret = aci_l2cap_connection_parameter_update_request(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout); + } + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case ERR_COMMAND_DISALLOWED: + case BLE_STATUS_NOT_ALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sets the Device Name Characteristic + + @param[in] deviceName + pointer to device name to be set + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) +{ + tBleStatus ret; + uint8_t nameLen = 0; + + nameLen = strlen((const char*)deviceName); + PRINTF("DeviceName Size=%d\n\r", nameLen); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_device_name_char_handle, + 0, + nameLen, + deviceName); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Gets the Device Name Characteristic + + @param[in] deviceName + pointer to device name + + @param[in] lengthP + pointer to device name length + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) +{ + tBleStatus ret; + + ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + *lengthP, + (uint16_t *)lengthP, + deviceName); + PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } +} + +/**************************************************************************/ +/*! + @brief Sets the Device Appearance Characteristic + + @param[in] appearance + device appearance + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance) +{ + tBleStatus ret; + uint8_t deviceAppearance[2]; + + STORE_LE_16(deviceAppearance, appearance); + PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_appearance_char_handle, + 0, 2, (uint8_t *)deviceAppearance); + if (BLE_STATUS_SUCCESS == ret){ + return BLE_ERROR_NONE; + } + + PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Gets the Device Appearance Characteristic + + @param[in] appearance + pointer to device appearance value + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) +{ + tBleStatus ret; + uint16_t lengthP = 2; + + ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + lengthP, + &lengthP, + (uint8_t*)appearanceP); + PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + +} + +GapScanningParams* BlueNRGGap::getScanningParams(void) +{ + return &_scanningParams; +} + +static void makeConnection(void) +{ + BlueNRGGap::getInstance().createConnection(); +} + +void BlueNRGGap::Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI) +{ + switch (reason) { + case DEVICE_FOUND: + { + GapAdvertisingParams::AdvertisingType_t type; + bool isScanResponse = false; + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * Private Random Address + * => scan_results = FALSE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type); + if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV || + (addr_type == RESOLVABLE_PRIVATE_ADDR || + addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) { + return; + } + + switch(adv_type) { + case ADV_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + break; + case ADV_DIRECT_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED; + break; + case ADV_SCAN_IND: + case SCAN_RSP: + type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED; + isScanResponse = true; + break; + case ADV_NONCONN_IND: + type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED; + break; + default: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + } + + PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n", + *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + if(!_connecting) { + processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data); + } + PRINTF("!!!After processAdvertisementReport\n\r"); + } + break; + + case DISCOVERY_COMPLETE: + // The discovery is complete. If this is due to a stop scanning (i.e., the device + // we are interested in has been found) and a connection has been requested + // then we start the device connection. + PRINTF("DISCOVERY_COMPLETE\n\r"); + _scanning = false; + + // Since the DISCOVERY_COMPLETE event can be received during the scanning interval, + // we need to delay the starting of connection + uint16_t delay = (_scanningParams.getInterval()*0.625); + +#ifdef AST_FOR_MBED_OS + if(_connecting) { + minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay)); + } +#else + Clock_Wait(delay); + if(_connecting) { + makeConnection(); + } +#endif /* AST_FOR_MBED_OS */ + + break; + } +} + +ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) +{ + + tBleStatus ret = BLE_STATUS_SUCCESS; + + // Stop ADV before scanning + /* + if (state.advertising == 1) { + stopAdvertising(); + } + */ + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * White List is empty + * => scan operation = FAILURE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + uint8_t whiteListSize = whitelistAddresses.size; + if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + ret = btleStartRadioScan(scanningParams.getActiveScanning(), + scanningParams.getInterval(), + scanningParams.getWindow(), + addr_type); + + PRINTF("Scanning...\n\r"); + PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000); + PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000); + //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval()); + //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1); + //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2); + if (BLE_STATUS_SUCCESS == ret){ + PRINTF("Observation Procedure Started\n"); + _scanning = true; + + if(scanningParams.getTimeout() != 0) { + PRINTF("!!! attaching scan to!!!\n"); + scanTimeout.attach(scanTimeoutCB, scanningParams.getTimeout()); + } + + return BLE_ERROR_NONE; + } + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + switch (ret) { + case BLE_STATUS_INVALID_CID: + PRINTF("Observation Procedure not implemented!!!\n\r"); + return BLE_ERROR_NOT_IMPLEMENTED; + default: + PRINTF("Observation Procedure failed (0x%02X)\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } + +} + +ble_error_t BlueNRGGap::stopScan() { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(_scanning) { + ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC); + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Discovery Procedure Terminated\n"); + return BLE_ERROR_NONE; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief set Tx power level + @param[in] txPower Transmission Power level + @returns ble_error_t +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setTxPower(int8_t txPower) +{ + tBleStatus ret; + + int8_t enHighPower = 0; + int8_t paLevel = 0; + + ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + ret = aci_hal_set_tx_power_level(enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief get permitted Tx power values + @param[in] values pointer to pointer to permitted power values + @param[in] num number of values +*/ +/**************************************************************************/ +void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { + static const int8_t permittedTxValues[] = { + -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8 + }; + + *valueArrayPP = permittedTxValues; + *countP = sizeof(permittedTxValues) / sizeof(int8_t); +} + +/**************************************************************************/ +/*! + @brief Set advertising parameters according to the current state + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setAdvParameters(void) +{ + uint32_t advIntMS; + + if(state.connected == 1) { + advIntMS = (conn_min_interval*1.25)-GUARD_INT; + advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS); + + PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval); + } else { + advInterval = _advParams.getIntervalInADVUnits(); + } +} + +/**************************************************************************/ +/*! + @brief Set connection parameters according to the current state (ADV and/or SCAN) + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionParameters(void) +{ + if (state.connected == 1) { + + PRINTF("state.connected=1\r\n"); + scanInterval = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(conn_min_interval*1.25); + scanWindow = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(((conn_min_interval*1.25)/100)*60); // scanWin ~= 60%(scanInt) + + } else if (state.advertising == 1) { + + if (_scanningParams.getInterval() < advInterval) { + PRINTF("state.adv=1 scanInterval<advInterval\r\n"); + scanInterval = advInterval; + scanWindow = advInterval; + } else { + PRINTF("state.adv=1 scanInterval>=advInterval\r\n"); + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + } + + if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms + conn_min_interval = MAX_INT_CONN; + conn_max_interval = MAX_INT_CONN; + } else { + conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + } + + } else { + + PRINTF("state.adv = 0\r\n"); + + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) || + SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms + conn_min_interval = DEF_INT_CONN; + conn_max_interval = DEF_INT_CONN; + } else { + conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + } + } + PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval)); + PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow)); + PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25)); + PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25)); + +} + +ble_error_t BlueNRGGap::createConnection () +{ + tBleStatus ret; + + /* + Before creating connection, set parameters according + to previous or current procedure (ADV and/or SCAN) + */ + setConnectionParameters(); + + /* + Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, + Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max + */ + ret = aci_gap_create_connection(scanInterval, + scanWindow, + _peerAddrType, + (unsigned char*)_peerAddr, + addr_type, + conn_min_interval, conn_max_interval, 0, + SUPERV_TIMEOUT, CONN_L1, CONN_L1); + + //_connecting = false; + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Connection started.\n"); + _connecting = false; + return BLE_ERROR_NONE; + } +} + +ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) +{ + /* avoid compiler warnings about unused variables */ + (void)connectionParams; + + setScanParams(scanParams->getInterval(), + scanParams->getWindow(), + scanParams->getTimeout(), + scanParams->getActiveScanning() + ); + + // Save the peer address + for(int i=0; i<BDADDR_SIZE; i++) { + _peerAddr[i] = peerAddr[i]; + } + _peerAddrType = peerAddrType; + + _connecting = true; + + if(_scanning) { + stopScan(); + } else { + PRINTF("Calling createConnection from connect()\n\r"); + return createConnection(); + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the advertising policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode) +{ + advertisingPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the scanning policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode) +{ + scanningPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Get the current advertising policy filter mode. + + @returns The advertising policy filter mode. +*/ +/**************************************************************************/ +Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const +{ + return advertisingPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Get the current scanning policy filter mode. + + @returns The scanning policy filter mode. + +*/ +/**************************************************************************/ +Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const +{ + return scanningPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGap's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::reset(void) +{ + PRINTF("BlueNRGGap::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (Gap::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + AdvToFlag = false; + ScanToFlag = false; + + /* Clear derived class members */ + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + return BLE_ERROR_NONE; +} + +void BlueNRGGap::setConnectionInterval(uint16_t interval) { + conn_min_interval = interval; + conn_max_interval = interval; +} + +Gap::Role_t BlueNRGGap::getGapRole(void) +{ + return (gapRole); +} + +void BlueNRGGap::setGapRole(Gap::Role_t role) +{ + gapRole = role; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,403 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTClient + * @brief BlueNRG BLE_API GattClient Adaptation + * @{ + */ + +#include "BlueNRGGattClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +#include <new> +#include <assert.h> + +ble_error_t BlueNRGGattClient::createGattConnectionClient(Gap::Handle_t connectionHandle) +{ + if(MAX_ACTIVE_CONNECTIONS <= _numConnections) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + for(uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + + if(_connectionPool[i] == NULL) { + BlueNRGGattConnectionClient *gattConnectionClient = new(std::nothrow) BlueNRGGattConnectionClient(this, connectionHandle); + + if (gattConnectionClient == NULL) { + return BLE_ERROR_NO_MEM; + } + + _connectionPool[i] = gattConnectionClient; + _connectionPool[i]->onServiceDiscoveryTermination(terminationCallback); + _numConnections++; + + PRINTF("createGattConnectionClient: _connectionPool index=%d\r\n", i); + PRINTF("createGattConnectionClient: succesfully added new gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + break; + } + } + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattClient::removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason) +{ + + PRINTF("removeGattConnectionClient: connectionHandle=%d reason=0x%x\r\n", connectionHandle, reason); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("removeGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("removeGattConnectionClient: Found gattConnectionClient\r\n"); + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + PRINTF("removeGattConnectionClient: succesfully removed gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + + break; + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + + return BLE_ERROR_NONE; +} + +BlueNRGGattConnectionClient * BlueNRGGattClient::getGattConnectionClient(Gap::Handle_t connectionHandle) { + PRINTF("getGattConnectionClient\r\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("getGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("getGattConnectionClient: Found gattConnectionClient\r\n"); + return _connectionPool[i]; + } + } + + return NULL; +} + +void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code) { + + if(error_code != BLE_STATUS_SUCCESS) { + return; + } + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->gattProcedureCompleteCB(error_code); +} + +void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServicesCB(event_data_length, + attribute_data_length, + attribute_data_list); +} + +void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServiceCB(event_data_length, + handles_info_list); +} + +ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->findServiceChars(); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharsCB(event_data_length, + handle_value_pair_length, + handle_value_pair); +} + +void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharByUUIDCB(event_data_length, + attr_handle, + attr_value); +} + +void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->discAllCharacDescCB(event_data_length, + format, + handle_uuid_pair); +} + +void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charReadCB(event_data_length, + attribute_value); +} + +void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWritePrepareCB(event_data_length, + attribute_handle, + offset, + part_attr_value); +} + +void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWriteExecCB(event_data_length); +} + +ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattClient launchServiceDiscovery\n\r"); + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->launchServiceDiscovery(sc, cc, matchingServiceUUID, matchingCharacteristicUUIDIn); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, matchingServiceUUID); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, startHandle, endHandle); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +bool BlueNRGGattClient::isServiceDiscoveryActive(void) const +{ + bool isSDActive = false; + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + isSDActive |= _connectionPool[i]->isServiceDiscoveryActive(); + } + } + + return isSDActive; +} + +void BlueNRGGattClient::terminateServiceDiscovery(void) +{ + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + _connectionPool[i]->terminateServiceDiscovery(); + } + } +} + +void BlueNRGGattClient::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; ++i) { + if (_connectionPool[i]) { + _connectionPool[i]->onServiceDiscoveryTermination(callback); + } + } +} + +ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->read(attributeHandle, offset); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->write(cmd, attributeHandle, length, value); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(characteristic.getConnectionHandle()); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverCharacteristicDescriptors(characteristic, discoveryCallback, terminationCallback); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattClient's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattClient::reset(void) +{ + PRINTF("BlueNRGGattClient::reset\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if(_connectionPool[i] != NULL) { + _connectionPool[i]->reset(); + + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + } + } + + return BLE_ERROR_NONE; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,816 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGattConnectionClient + * @brief BlueNRG GattConnectionClient Adaptation + * @{ + */ + +#include "BlueNRGGattConnectionClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" +#include "ble_debug.h" + +// #define PRINTF printf + +static uint8_t props_mask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 + }; + +void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code) +{ + if(error_code != BLE_STATUS_SUCCESS) { + _currentState = GATT_IDLE; + return; + } + + // Service Discovery complete +/* + if(_currentState != GATT_IDLE && + _currentState != GATT_DISCOVERY_TERMINATED && + _currentState != GATT_WRITE_CHAR && + _currentState != GATT_READ_CHAR) { +*/ + if(_currentState == GATT_SERVICE_DISCOVERY) { + findServiceChars(); + return; + } + + if(_currentState == GATT_CHAR_DESC_DISCOVERY) { + _currentState = GATT_IDLE; + if(charDescTerminationCallback != NULL) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { + _characteristic, + BLE_ERROR_NONE + }; + charDescTerminationCallback(¶ms); + } + return; + } + + // Read complete + if(_currentState == GATT_READ_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processReadResponse(&readCBParams); + free((void*)(readCBParams.data)); + readCBParams.data = NULL; + return; + } + + // Write complete + if(_currentState == GATT_WRITE_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); + return; + } +} + +void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numAttr; + + numAttr = (event_data_length - 1) / attribute_data_length; + + offset = 0; + for (i=0; i<numAttr; i++) { + startHandle = attribute_data_list[offset]; + endHandle = attribute_data_list[offset+2]; + + // UUID Type + if (attribute_data_length == 6) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4]; + PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(attribute_data_list+offset+4, UUID::LSB); + +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + + } + + PRINTF("Setup serviceIndex = %d\n\r", _numServices); + discoveredService[_numServices].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += attribute_data_length; + } + + PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr); + +} + +void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numHandlePairs; + + numHandlePairs = (event_data_length - 1) / 2; + + offset = 0; + for (i=0; i<numHandlePairs; i++) { + startHandle = handles_info_list[offset]; + endHandle = handles_info_list[offset+2]; + + PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle); + + + if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle); + uuid = _matchingServiceUUID.getShortUUID(); + } else { +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02x", longUUIDBytes[i]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB); + } + + discoveredService[i].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += 4; + } +} + +void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) +{ + // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + uint8_t i, numChar, offset; + + numChar = (event_data_length - 1) / handle_value_pair_length; + + PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar); + + offset = 0; + for (i=0; i<numChar; i++) { + // UUID Type + if (handle_value_pair_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(handle_value_pair+offset+5, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & handle_value_pair[offset+2]); + p._read = (props_mask[1] & handle_value_pair[offset+2])>>1; + p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2; + p._write = (props_mask[3] & handle_value_pair[offset+2])>>3; + p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4; + p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5; + p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = handle_value_pair[offset+2]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = handle_value_pair[offset]; + valueHandle = handle_value_pair[offset+3]; + lastHandle = valueHandle+1; + PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle); + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; + + offset += handle_value_pair_length; + } +} + +void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) +{ + // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + + PRINTF("serviceCharByUUIDCB\n\r"); + + // UUID Type + if (event_data_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = attr_value[4]<<8|attr_value[3]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(attr_value+3, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & attr_value[0]); + p._read = (props_mask[1] & attr_value[0])>>1; + p._writeWoResp = (props_mask[2] & attr_value[0])>>2; + p._write = (props_mask[3] & attr_value[0])>>3; + p._notify = (props_mask[4] & attr_value[0])>>4; + p._indicate = (props_mask[5] & attr_value[0])>>5; + p._authSignedWrite = (props_mask[6] & attr_value[0])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = attr_value[0]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = attr_handle; + valueHandle = attr_value[1]; + lastHandle = valueHandle+1; + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + // update the last handle and call the characteristic discovery callback for previous char + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; +} + +ble_error_t BlueNRGGattConnectionClient::findServiceChars(void) +{ + PRINTF("findServiceChars\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + + DiscoveredService *service; + + // complete the discovery of the last characteristic of the previous service. + // Its last handle wasn't known before this point + // update the handle and call the characteristic discovery callback. + if (_servIndex != 0 && _numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle()); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars = 0; + + // We finished chars discovery for all services + if(_servIndex >= _numServices) { + PRINTF("!!!We finished chars discovery for all services!!!\n\r"); + //_currentState = GATT_CHARS_DISCOVERY_COMPLETE; + + terminateServiceDiscovery(); + + return BLE_ERROR_NONE; + } + + service = &discoveredService[_servIndex]; + /* + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID()); + } else { + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); + } + */ + + if(serviceDiscoveryCallback) { + serviceDiscoveryCallback(service); + } + + PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex); + //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle()); + + if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) { + PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r"); + ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle()); + } else { + + uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID()); + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; +#ifdef DEBUG + PRINTF("findServiceChars C UUID-"); + for(unsigned i = 0; i < 2; i++) { + PRINTF("%02X", short_uuid[i]); + } + PRINTF("\n\r"); +#endif + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID(); +#ifdef DEBUG + PRINTF("(findServiceChars) C UUID-"); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", uuid[i]); + } + PRINTF("\r\n"); +#endif + } + + ret = aci_gatt_disc_charac_by_uuid(_connectionHandle, + service->getStartHandle(), + service->getEndHandle(), + uuid_type, + uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _servIndex++; + } + + PRINTF("findServiceChars ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + unsigned j; + + if(isServiceDiscoveryActive()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if(!sc && !cc) { + // nothing to do + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r"); + return BLE_ERROR_NONE; + } + + serviceDiscoveryCallback = sc; + characteristicDiscoveryCallback = cc; + _matchingServiceUUID = matchingServiceUUID; + _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn; + + //reset services + _numServices = 0; + _numChars = 0; + _servIndex = 0; + for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) { + discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE); + } + + if(matchingServiceUUID == BLE_UUID_UNKNOWN) { + + // Wildcard: search for all services + PRINTF("Wildcard: search for all services\r\n"); + ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle); + + } else { + PRINTF("search for specific services\r\n"); + + uint8_t type = matchingServiceUUID.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID()); +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x"); + for(j = 0; j < 2; j++) { + PRINTF("%02X", short_uuid[j]); + } + PRINTF("\n\r"); +#endif + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; + + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)matchingServiceUUID.getBaseUUID(); + +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x"); + for(j = 0; j < 16; j++) { + PRINTF("%02X", uuid[j]); + } + PRINTF("\n\r"); +#endif + } + + // search for specific service by UUID + ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_SERVICE_DISCOVERY; + } + + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)matchingServiceUUID; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)startHandle; + (void)endHandle; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const +{ + if(_currentState == GATT_SERVICE_DISCOVERY) { + return true; + } + + return false; +} + +void BlueNRGGattConnectionClient::terminateServiceDiscovery(void) +{ + _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED; + + if (terminationCallback) { + terminationCallback(_connectionHandle); + } +} + +void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value) +{ + // copy the data read, they will be forwarded to the user once the procedure + // has completed + readCBParams.connHandle = _connectionHandle; + readCBParams.offset = 0; + readCBParams.len = event_data_length; + readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length)); + memcpy((void*)(readCBParams.data), attribute_value, event_data_length); +} + +ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + /* avoid compiler warnings about unused variables */ + (void)offset; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // Save the attribute_handle not provided by evt_att_read_resp + gattc->readCBParams.handle = attributeHandle; + + ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle); + + if(ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_READ_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } +} + +void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) +{ + // Update the write response params + writeCBParams.handle = attribute_handle; + writeCBParams.offset = offset; + writeCBParams.len = event_data_length-4; //(?) + writeCBParams.data = part_attr_value; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length) +{ + /* avoid compiler warnings about unused variables */ + (void)event_data_length; + + writeCBParams.connHandle = _connectionHandle; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + /* avoid compiler warnings about unused variables */ + (void)cmd; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // We save the write response params (used by the callback) because + // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE + gattc->writeCBParams.connHandle = _connectionHandle; + gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD; + gattc->writeCBParams.handle = attributeHandle; + gattc->writeCBParams.offset = 0; + gattc->writeCBParams.len = length; + gattc->writeCBParams.data = value; + + ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); + + if (ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_WRITE_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } + +} + +void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + GattAttribute::Handle_t attHandle; + UUID uuid; + uint8_t i, numCharacDesc, offset, handle_uuid_length; + + handle_uuid_length = 4; //Handle + UUID_16 + if (format == 2) + handle_uuid_length = 18; //Handle + UUID_128 + + numCharacDesc = (event_data_length - 1) / handle_uuid_length; + + offset = 0; + + PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n", + event_data_length, format); + + + for (i=0; i<numCharacDesc; i++) { + memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle)); + + // UUID Type + if (handle_uuid_length == 4) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2]; + PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB); +#ifdef DEBUG + PRINTF("D UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + } + + if(charDescDiscoveryCallback != NULL) { + CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { + _characteristic, + DiscoveredCharacteristicDescriptor( + _characteristic.getGattClient(), + _connectionHandle, + attHandle, + uuid + ) + }; + charDescDiscoveryCallback(¶ms); + } + + _numCharDesc++; + + offset += handle_uuid_length; + } +} + +ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { + + tBleStatus ret; + + if(_currentState != GATT_IDLE) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + charDescDiscoveryCallback = discoveryCallback; + charDescTerminationCallback = terminationCallback; + + GattAttribute::Handle_t valueHandle = characteristic.getValueHandle(); + GattAttribute::Handle_t lastHandle = characteristic.getLastHandle(); + + PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle); + ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle); + + if (ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_CHAR_DESC_DISCOVERY; + _characteristic = characteristic; + return BLE_ERROR_NONE; + } + switch (ret) { + case BLE_STATUS_INVALID_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattConnectionClient::reset(void) { + PRINTF("BlueNRGGattConnectionClient::reset\n"); + + /* Clear all state, including private members */ + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + _numServices = 0; + _servIndex = 0; + _numChars = 0; + _numCharDesc = 0; + + /* Clear class members */ + memset(discoveredService, 0, sizeof(discoveredService)); + memset(discoveredChar, 0, sizeof(discoveredChar)); + + // free response if allocated + if(readCBParams.data) { + free((void*)(readCBParams.data)); + } + + return BLE_ERROR_NONE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,755 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTSERVER + * @brief BlueNRG BLE_API GattServer Adaptation + * @{ + */ + +#include "BlueNRGGattServer.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/**************************************************************************/ +/*! + @brief Adds a new service to the GATT table on the peripheral + + @params[in] service + Pointer to instance of the Gatt Server to add + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::addService(GattService &service) +{ + /* ToDo: Make sure we don't overflow the array, etc. */ + /* ToDo: Make sure this service UUID doesn't already exist (?) */ + /* ToDo: Basic validation */ + + tBleStatus ret; + uint8_t type; + uint16_t short_uuid; + uint8_t primary_short_uuid[2]; + uint8_t primary_base_uuid[16]; + uint8_t char_base_uuid[16]; + const uint8_t *base_uuid; + const uint8_t *base_char_uuid; + + uint8_t charsCount = service.getCharacteristicCount(); + const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount; + + // check that there is enough characteristics left in the + // characteristic array. + if (charsCount > available_characteristics) { + PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics); + return BLE_ERROR_NO_MEM; + } + + const uint16_t maxAttrRecords = computeAttributesRecord(service); + + type = (service.getUUID()).shortOrLong(); + PRINTF("AddService(): Type:%d\n\r", type); + + /* Add the service to the BlueNRG */ + short_uuid = (service.getUUID()).getShortUUID(); + STORE_LE_16(primary_short_uuid, short_uuid); + + if(type==UUID::UUID_TYPE_LONG) { + base_uuid = (service.getUUID()).getBaseUUID(); + + COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]); + } + + ret = BLE_STATUS_SUCCESS; + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_serv(UUID_TYPE_16, + primary_short_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_serv(UUID_TYPE_128, + primary_base_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_OUT_OF_HANDLE: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case ERR_UNSPECIFIED_ERROR: + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_ERROR: + default: + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + + + service.setHandle(servHandle); + //serviceHandleVector.push_back(servHandle); + PRINTF("added servHandle handle =%u\n\r", servHandle); + uint16_t bleCharacteristic; + + //iterate to include all characteristics + for (uint8_t i = 0; i < charsCount; i++) { + GattCharacteristic *p_char = service.getCharacteristic(i); + uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); + + uint8_t int_8_uuid[2]; + STORE_LE_16(int_8_uuid, char_uuid); + + type = (p_char->getValueAttribute().getUUID()).shortOrLong(); + + if(type==UUID::UUID_TYPE_LONG) { + base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); +#ifdef DEBUG + for(uint8_t j=0; j<16; j++) { + PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]); + } + PRINTF("\n\r"); +#endif + COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]); + } + + PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); + /* + * Gatt_Evt_Mask -> HardCoded (0) + * Encryption_Key_Size -> Hardcoded (16) + * isVariable (variable length value field) -> Hardcoded (1) + */ + uint8_t Gatt_Evt_Mask = 0x0; + + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP; + } + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; + } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_16, + int_8_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_128, + char_base_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + case BLE_STATUS_CHARAC_ALREADY_EXISTS: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); + + p_characteristics[characteristicCount++] = p_char; + /* Set the characteristic value handle */ + p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE); + PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle()); + + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + ble_error_t err = write(p_char->getValueAttribute().getHandle(), + p_char->getValueAttribute().getValuePtr(), + p_char->getValueAttribute().getLength(), false /* localOnly */); + if (err) { + PRINTF("ERROR HERE !!!!\r\n"); + return err; + } + } + + // add descriptors now + uint16_t descHandle = 0; + PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); + + for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { + GattAttribute *descriptor = p_char->getDescriptor(descIndex); + uint8_t desc_uuid[16] = { 0 }; + + + uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT; + STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID()); + + if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) { + desc_uuid_type = CHAR_DESC_TYPE_128_BIT; + const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID(); + + COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]); + } + + ret = aci_gatt_add_char_desc(service.getHandle(), + bleCharacteristic, + desc_uuid_type, + desc_uuid, + descriptor->getMaxLength(), + descriptor->getLength(), + descriptor->getValuePtr(), + CHAR_DESC_SECURITY_PERMISSION, + CHAR_DESC_ACCESS_PERMISSION, + GATT_NOTIFY_ATTRIBUTE_WRITE, + MIN_ENCRY_KEY_SIZE, + CHAR_ATTRIBUTE_LEN_IS_FIXED, + &descHandle); + PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); + + switch (ret) { + case BLE_STATUS_SUCCESS: + PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); + descriptor->setHandle(descHandle); + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_INVALID_OPERATION: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + } + + serviceCount++; + + //FIXME: There is no GattService pointer array in GattServer. + // There should be one? (Only the user is aware of GattServices!) Report to forum. + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on char handle + + @param[in] attributeHandle + The handle of the GattCharacteristic to read from + @param[in] buffer + Buffer to hold the the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes read into the buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) +{ + tBleStatus ret; + uint16_t charHandle = attributeHandle; + + ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer); + + if(ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on the connection + and char handle + + @param[in] connectionHandle + The handle of the connection + @param[in] attributeHandle + The handle of the GattCharacteristic to write to + @param[in] buffer + Data to use when updating the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes in buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + uint8_t buffer[], + uint16_t *lengthP) { + + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)attributeHandle; + (void)buffer; + (void)lengthP; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t, + const uint8_t[], + uint16_t, bool localOnly) { + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)localOnly; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly) +{ + /* avoid compiler warnings about unused variables */ + (void)localOnly; + + // check that the len of the data to write are compatible with the characteristic + GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle); + if (!characteristic) { + PRINTF("characteristic not found\r\n"); + return BLE_ERROR_INVALID_PARAM; + } + + // if the attribute handle is the attribute handle of the characteristic value then + // write the value + if (attributeHandle == characteristic->getValueHandle()) { + // assert the len in input is correct for this characteristic + const GattAttribute& value_attribute = characteristic->getValueAttribute(); + + // reject write if the lenght exceed the maximum lenght of this attribute + if (value_attribute.getMaxLength() < len) { + PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + // reject write if the attribute size is fixed and the lenght in input is different than the + // length of the attribute. + if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) { + PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + tBleStatus ret; + + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + + PRINTF("updating bleCharacteristic valueHandle=%u,\ + corresponding serviceHandle=%u len=%d\n\r", + attributeHandle, bleCharHandleMap.find(charHandle)->second, len); + + /* + * If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. + */ + ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } else { + // write this handle has a descriptor handle + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + uint16_t service_handle = bleCharHandleMap.find(charHandle)->second; + + tBleStatus ret = aci_gatt_set_desc_value( + service_handle, + charHandle, + attributeHandle, + 0, + len, + buffer + ); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } +} + +/**************************************************************************/ +/*! + @brief Reads a value according to the handle provided + + @param[in] attributeHandle + The handle of the attribute to read from + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle) +{ + uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); + + GattReadCallbackParams readParams; + readParams.handle = attributeHandle; + + //PRINTF("readParams.handle = %d\n\r", readParams.handle); + HCIDataReadEvent(&readParams); + + //EXIT: + if(gapConnectionHandle != 0){ + //PRINTF("Calling aci_gatt_allow_read\n\r"); + aci_gatt_allow_read(gapConnectionHandle); + } + + return BLE_ERROR_NONE; +} + +// ask if the write request should be accepted of rejected +// return 0 in case of success or an ATT error response in +// case of faillure +uint8_t BlueNRGGattServer::Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length, + const uint8_t* data) { + + GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle); + if(!characteristic) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF; + } + + // check if the data length is in range + if (characteristic->getValueAttribute().getMaxLength() < data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + // if the length of the characteristic value is fixed + // then the data in input should be of that length + if (characteristic->getValueAttribute().hasVariableLength() == false && + characteristic->getValueAttribute().getMaxLength() != data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + GattWriteAuthCallbackParams params = { + connection_handle, + attr_handle, + /* offset */ 0, + data_length, + data, + /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED + }; + + return characteristic->authorizeWrite(¶ms) & 0xFF; +} + +/**************************************************************************/ +/*! + @brief Returns the GattCharacteristic according to the handle provided + + @param[in] attrHandle + The handle of the attribute + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) +{ + GattCharacteristic *p_char = NULL; + int i; + uint16_t handle, handle_1; + + PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle); + for(i=0; i<characteristicCount; i++) + { + handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + PRINTF("handle(%d)=%d\n\r", i, handle); + if(i==characteristicCount-1)//Last Characteristic check + { + if(attrHandle>=handle) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); + break; + } + } + else { + handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + //Testing if attribute handle is between two Characteristic Handles + if(attrHandle>=handle && attrHandle<handle_1) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); + break; + } else continue; + } + } + + return p_char; +} + +void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { + this->handleDataWrittenEvent(params); +} + +void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { + PRINTF("Called HCIDataReadEvent\n\r"); + this->handleDataReadEvent(params); +} + +void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { + this->handleEvent(type, charHandle); +} + +void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { + this->handleDataSentEvent(count); +} + + +ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { + // <TODO> + return (ble_error_t)0; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::reset(void) +{ + PRINTF("BlueNRGGattServer::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (GattServer::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + /* Clear class members */ + memset(p_characteristics, 0, sizeof(p_characteristics)); + memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles)); + serviceCount = 0; + characteristicCount = 0; + + return BLE_ERROR_NONE; +} + + +/// compute the number of attributes needed by this service. +uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) { + uint16_t attribute_records = 1; + + for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) { + // add two attributes, one for the characteristic declaration + // and the other for the characteristic value. + attribute_records += 2; + + const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index); + const uint8_t properties = characteristic->getProperties(); + // if notify or indicate are present, two attributes are + // needed + if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) || + (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { + attribute_records += 2; + } + + // if broadcast is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) { + attribute_records += 2; + } + + // if extended properties flag is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) { + attribute_records += 2; + } + + attribute_records += characteristic->getDescriptorCount(); + } + + // for some reason, if there is just a service, this value should + // be equal to 5 + if (attribute_records == 1) { + attribute_records = 5; + } + + return attribute_records; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,421 @@ +/** + ****************************************************************************** + * @file ble_hci.c + * @author AMS/HESA Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "ble_gp_timer.h" +#include "ble_debug.h" + +#include "stm32_bluenrg_ble.h" + +#if BLE_CONFIG_DBG_ENABLE +#undef PRINTF +#endif + +#define HCI_LOG_ON 0 + +#define HCI_READ_PACKET_NUM_MAX (0x40) + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tListNode hciReadPktPool; +tListNode hciReadPktRxQueue; + +// betzw - DEBUG: +//#define POOL_CNT +#ifdef POOL_CNT +#include <stdio.h> +static unsigned int nr_hciReadPktPool; +static unsigned int lowest_nr_hciReadPktPool; +#endif // POOL_CNT + +/* pool of hci read packets */ +static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; + +static volatile uint8_t hci_timer_id; +static volatile uint8_t hci_timeout; + +void hci_timeout_callback(void) +{ + hci_timeout = 1; + return; +} + +void HCI_Init(void) +{ + uint8_t index; + +#ifdef POOL_CNT + nr_hciReadPktPool = 0; +#endif // POOL_CNT + + /* Initialize list heads of ready and free hci data packet queues */ + list_init_head (&hciReadPktPool); + list_init_head (&hciReadPktRxQueue); + + /* Initialize the queue of free hci data packets */ + for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) + { + list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif // POOL_CNT + } + +#ifdef POOL_CNT + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif // POOL_CNT +} + +#define HCI_PCK_TYPE_OFFSET 0 +#define EVENT_PARAMETER_TOT_LEN_OFFSET 2 + +/** + * Verify if HCI packet is correctly formatted. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * @return 0 if HCI packet is as expected + */ +int HCI_verify(const tHciDataPacket * hciReadPacket) +{ + const uint8_t *hci_pckt = hciReadPacket->dataBuff; + + if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) + return 1; /* Incorrect type. */ + + if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) + return 2; /* Wrong length (packet truncated or too long). */ + + return 0; +} + +void HCI_Process(void) +{ + tHciDataPacket * hciReadPacket = NULL; + +#ifdef POOL_CNT + printf("betzw(%s, %d): nr_hciReadPktPool = %u (lowest = %u)\r\n", __func__, __LINE__, + nr_hciReadPktPool, lowest_nr_hciReadPktPool); +#endif // POOL_CNT + + Disable_SPI_IRQ(); + uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); + /* process any pending events read */ + while(list_empty == FALSE) + { + list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + Enable_SPI_IRQ(); + HCI_Event_CB(hciReadPacket->dataBuff); + Disable_SPI_IRQ(); + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + list_empty = list_is_empty(&hciReadPktRxQueue); + } + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG. */ + HCI_HandleSPI(); + Enable_SPI_IRQ(); +} + +BOOL HCI_Queue_Empty(void) +{ + return list_is_empty(&hciReadPktRxQueue); +} + +/** + * When an interrupt is raised by BlueNRG, + * just signal that a new event (availability of SPI data to be read) + * needs to be processed. + */ +void HCI_Isr(void) +{ + signalEventsToProcess(); +} + +/** + * Now, SPI Data are handled in user space. + * In case it has to be called in ISR, take care to + * call Disable_SPI_IRQ/Enable_SPI_IRQ in a proper way. + * The calls Disable_SPI_IRQ/Enable_SPI_IRQ have not been removed + * from this code for backward compatibility. + */ +void HCI_HandleSPI(void) +{ + tHciDataPacket * hciReadPacket = NULL; + uint8_t data_len; + + Clear_SPI_EXTI_Flag(); + while(BlueNRG_DataPresent()){ + if (list_is_empty (&hciReadPktPool) == FALSE){ + + /* enqueueing a packet for read */ + list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool--; + if(nr_hciReadPktPool < lowest_nr_hciReadPktPool) + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif + + data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); + if(data_len > 0){ + hciReadPacket->data_len = data_len; + if(HCI_verify(hciReadPacket) == 0) { + list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); + } else { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else { + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else{ + // HCI Read Packet Pool is empty, wait for a free packet. + Clear_SPI_EXTI_Flag(); + return; + } + + Clear_SPI_EXTI_Flag(); + } +} + +void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){ +#if HCI_LOG_ON + PRINTF("HCI <- "); + for(int i=0; i < n_bytes1; i++) + PRINTF("%02X ", *((uint8_t*)data1 + i)); + for(int i=0; i < n_bytes2; i++) + PRINTF("%02X ", *((uint8_t*)data2 + i)); + PRINTF("\n"); +#endif + + Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); +} + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) +{ + hci_command_hdr hc; + + hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); + hc.plen= plen; + + uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; + header[0] = HCI_COMMAND_PKT; + Osal_MemCpy(header+1, &hc, sizeof(hc)); + + hci_write(header, param, sizeof(header), plen); +} + +static void move_list(tListNode * dest_list, tListNode * src_list) +{ + pListNode tmp_node; + + while(!list_is_empty(src_list)){ + list_remove_tail(src_list, &tmp_node); + list_insert_head(dest_list, tmp_node); + } +} + + /* It ensures that we have at least half of the free buffers in the pool. */ +static void free_event_list(void) +{ + tHciDataPacket * pckt; + + Disable_SPI_IRQ(); + + while(list_get_size(&hciReadPktPool) < HCI_READ_PACKET_NUM_MAX/2){ + list_remove_head(&hciReadPktRxQueue, (tListNode **)&pckt); + list_insert_tail(&hciReadPktPool, (tListNode *)pckt); + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG */ + HCI_HandleSPI(); + } + + Enable_SPI_IRQ(); +} + +int hci_send_req(struct hci_request *r, BOOL async) +{ + uint8_t *ptr; + uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + hci_event_pckt *event_pckt; + hci_uart_pckt *hci_hdr; + int to = DEFAULT_TIMEOUT; + struct timer t; + tHciDataPacket * hciReadPacket = NULL; + tListNode hciTempQueue; + + list_init_head(&hciTempQueue); + + free_event_list(); + + hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); + + if(async){ + return 0; + } + + /* Minimum timeout is 1. */ + if(to == 0) + to = 1; + + Timer_Set(&t, to); + + while(1) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + evt_le_meta_event *me; + int len; + + while(1){ + + Disable_SPI_IRQ(); + HCI_HandleSPI(); + Enable_SPI_IRQ(); + + if(Timer_Expired(&t)){ + goto failed; + } + if(!HCI_Queue_Empty()){ + break; + } + } + + /* Extract packet from HCI event queue. */ + Disable_SPI_IRQ(); + list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + + hci_hdr = (void *)hciReadPacket->dataBuff; + + if(hci_hdr->type == HCI_EVENT_PKT){ + + event_pckt = (void *) (hci_hdr->data); + + ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); + len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); + + switch (event_pckt->evt) { + + case EVT_CMD_STATUS: + cs = (void *) ptr; + + if (cs->opcode != opcode) + goto failed; + + if (r->event != EVT_CMD_STATUS) { + if (cs->status) { + goto failed; + } + break; + } + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_CMD_COMPLETE: + cc = (void *) ptr; + + if (cc->opcode != opcode) + goto failed; + + ptr += EVT_CMD_COMPLETE_SIZE; + len -= EVT_CMD_COMPLETE_SIZE; + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_LE_META_EVENT: + me = (void *) ptr; + + if (me->subevent != r->event) + break; + + len -= 1; + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, me->data, r->rlen); + goto done; + + case EVT_HARDWARE_ERROR: + goto failed; + + default: + break; + } + } + + /* If there are no more packets to be processed, be sure there is at list one + packet in the pool to process the expected event. + If no free packets are available, discard the processed event and insert it + into the pool. */ + if(list_is_empty(&hciReadPktPool) && list_is_empty(&hciReadPktRxQueue)){ + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); + hciReadPacket=NULL; + } + else { + /* Insert the packet in a different queue. These packets will be + inserted back in the main queue just before exiting from send_req(), so that + these events can be processed by the application. + */ + list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); + hciReadPacket = NULL; + } + + HCI_HandleSPI(); + + Enable_SPI_IRQ(); + + } + +failed: + if(hciReadPacket != NULL) { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + move_list(&hciReadPktRxQueue, &hciTempQueue); + Enable_SPI_IRQ(); + return -1; + +done: + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + move_list(&hciReadPktRxQueue, &hciTempQueue); + + Enable_SPI_IRQ(); + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,837 @@ +/** + ****************************************************************************** + * @file ble_hci_le.c + * @author AMG RF Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +int hci_reset(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_RESET; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_disconnect(uint16_t handle, uint8_t reason) +{ + struct hci_request rq; + disconnect_cp cp; + uint8_t status; + + cp.handle = handle; + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) +{ + struct hci_request rq; + read_local_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + + *hci_version = resp.hci_version; + *hci_revision = btohs(resp.hci_revision); + *lmp_pal_version = resp.lmp_pal_version; + *manufacturer_name = btohs(resp.manufacturer_name); + *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); + + return 0; +} + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) +{ + struct hci_request rq; + le_read_buffer_size_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_BUFFER_SIZE; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *pkt_len = resp.pkt_len; + *max_pkt = resp.max_pkt; + + return 0; +} + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter) +{ + struct hci_request rq; + le_set_adv_parameters_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.min_interval = min_interval; + adv_cp.max_interval = max_interval; + adv_cp.advtype = advtype; + adv_cp.own_bdaddr_type = own_bdaddr_type; + adv_cp.direct_bdaddr_type = direct_bdaddr_type; + if(direct_bdaddr != NULL) + Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); + adv_cp.chan_map = chan_map; + adv_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_PARAMETERS; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_adv_data_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.length = length; + Osal_MemCpy(adv_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_DATA; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertise_enable(uint8_t enable) +{ + struct hci_request rq; + le_set_advertise_enable_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.enable = enable?1:0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter) +{ + struct hci_request rq; + le_set_scan_parameters_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.type = type; + scan_cp.interval = interval; + scan_cp.window = window; + scan_cp.own_bdaddr_type = own_bdaddr_type; + scan_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) +{ + struct hci_request rq; + le_set_scan_enable_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.enable = enable?1:0; + scan_cp.filter_dup = filter_dup; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_ENABLE; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_rand(uint8_t random_number[8]) +{ + struct hci_request rq; + le_rand_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_RAND; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + Osal_MemCpy(random_number, resp.random, 8); + + return 0; +} + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_scan_response_data_cp scan_resp_cp; + uint8_t status; + + Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); + scan_resp_cp.length = length; + Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; + rq.cparam = &scan_resp_cp; + rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) +{ + struct hci_request rq; + le_read_adv_channel_tx_power_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *tx_power_level = resp.level; + + return 0; +} + +int hci_le_set_random_address(tBDAddr bdaddr) +{ + struct hci_request rq; + le_set_random_address_cp set_rand_addr_cp; + uint8_t status; + + Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); + Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; + rq.cparam = &set_rand_addr_cp; + rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_read_bd_addr(tBDAddr bdaddr) +{ + struct hci_request rq; + read_bd_addr_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_BD_ADDR; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_BD_ADDR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); + + return 0; +} + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) +{ + struct hci_request rq; + le_create_connection_cp create_cp; + uint8_t status; + + Osal_MemSet(&create_cp, 0, sizeof(create_cp)); + create_cp.interval = interval; + create_cp.window = window; + create_cp.initiator_filter = initiator_filter; + create_cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); + create_cp.own_bdaddr_type = own_bdaddr_type; + create_cp.min_interval=min_interval; + create_cp.max_interval=max_interval; + create_cp.latency = latency; + create_cp.supervision_timeout=supervision_timeout; + create_cp.min_ce_length=min_ce_length; + create_cp.max_ce_length=max_ce_length; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN; + rq.cparam = &create_cp; + rq.clen = LE_CREATE_CONN_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_create_connection_cancel(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN_CANCEL; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) +{ + struct hci_request rq; + le_encrypt_cp params; + le_encrypt_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemCpy(params.key, key, 16); + Osal_MemCpy(params.plaintext, plaintextData, 16); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ENCRYPT; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + le_ltk_neg_reply_cp params; + le_ltk_neg_reply_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + params.handle = 1; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_LTK_NEG_REPLY; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CLEAR_WHITE_LIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0){ + return BLE_STATUS_TIMEOUT; + } + + return status; +} + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) +{ + struct hci_request rq; + le_add_device_to_white_list_cp params; + uint8_t status; + + params.bdaddr_type = bdaddr_type; + Osal_MemCpy(params.bdaddr, bdaddr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; + rq.cparam = ¶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/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1309 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB05A1 cp; + gap_init_rp resp; + + cp.role = role; + cp.privacy_enabled = privacy_enabled; + cp.device_name_char_len = device_name_char_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} +tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB04A1 cp; + gap_init_rp resp; + + cp.role = role; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + SlaveConnIntervMin = htobs(SlaveConnIntervMin); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + SlaveConnIntervMax = htobs(SlaveConnIntervMax); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB05A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.directed_adv_type = directed_adv_type; + cp.adv_interv_min = adv_interv_min; + cp.adv_interv_max = adv_interv_max; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB04A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_io_capability(uint8_t io_capability) +{ + struct hci_request rq; + uint8_t status; + gap_set_io_capability_cp cp; + + cp.io_capability = io_capability; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_IO_CAPABILITY; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode) +{ + struct hci_request rq; + gap_set_auth_requirement_cp cp; + uint8_t status; + + cp.mitm_mode = mitm_mode; + cp.oob_enable = oob_enable; + Osal_MemCpy(cp.oob_data, oob_data, 16); + cp.min_encryption_key_size = min_encryption_key_size; + cp.max_encryption_key_size = max_encryption_key_size; + cp.use_fixed_pin = use_fixed_pin; + cp.fixed_pin = htobl(fixed_pin); + cp.bonding_mode = bonding_mode; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) +{ + struct hci_request rq; + gap_set_author_requirement_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorization_enable = authorization_enable; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) +{ + struct hci_request rq; + gap_passkey_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.passkey = htobl(passkey); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_PASSKEY_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) +{ + struct hci_request rq; + gap_authorization_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorize = authorize; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB05A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + cp.own_address_type = own_address_type; + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB04A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) +{ + struct hci_request rq; + gap_set_undirected_connectable_cp cp; + uint8_t status; + + cp.own_addr_type = own_addr_type; + cp.adv_filter_policy = adv_filter_policy; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) +{ + struct hci_request rq; + gap_slave_security_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.bonding = bonding; + cp.mitm_protection = mitm_protection; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[32]; + uint8_t indx = 0; + + if (AdvLen > (sizeof(buffer)-1)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvLen; + indx++; + + Osal_MemCpy(buffer + indx, AdvData, AdvLen); + indx += AdvLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_UPDATE_ADV_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) +{ + struct hci_request rq; + gap_delete_ad_type_cp cp; + uint8_t status; + + cp.ad_type = ad_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_DELETE_AD_TYPE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required) +{ + struct hci_request rq; + gap_get_security_level_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; + rq.rparam = &resp; + rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *mitm_protection = resp.mitm_protection; + *bonding = resp.bonding; + *oob_data = resp.oob_data; + *passkey_required = resp.passkey_required; + + return resp.status; +} + +tBleStatus aci_gap_configure_whitelist(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) +{ + struct hci_request rq; + gap_terminate_cp cp; + uint8_t status; + + cp.handle = htobs(conn_handle); + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_clear_security_database(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) +{ + struct hci_request rq; + gap_allow_rebond_cp_IDB05A1 cp; + uint8_t status; + + cp.conn_handle = conn_handle; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_allow_rebond_IDB04A1(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_limited_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_general_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_name_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = use_reconn_addr; + indx++; + + Osal_MemCpy(buffer + indx, reconn_addr, 6); + indx += 6; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB05A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB04A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.use_reconn_addr = use_reconn_addr; + Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_start_selective_conn_establish_proc_cp cp; + uint8_t status; + + if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.num_whitelist_entries = num_whitelist_entries; + + Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_create_connection_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CREATE_CONNECTION; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; + rq.cparam = &procedure_code; + rq.clen = 1; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_connection_update_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) +{ + struct hci_request rq; + gap_send_pairing_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.force_rebond = force_rebond; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + gap_resolve_private_address_rp rp; + + Osal_MemCpy(cp.address, private_address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); + + return 0; +} +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + uint8_t status; + + Osal_MemCpy(cp.address, address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_set_broadcast_mode_cp cp; + uint8_t status; + uint8_t indx = 0; + uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; + + if (variable_size > sizeof(cp.var_len_data) ) + return BLE_STATUS_INVALID_PARAMS; + + cp.adv_interv_min = htobs(adv_interv_min); + cp.adv_interv_max = htobs(adv_interv_max); + cp.adv_type = adv_type; + cp.own_addr_type = own_addr_type; + + cp.var_len_data[indx] = adv_data_length; + indx++; + Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); + indx += adv_data_length; + cp.var_len_data[indx] = num_whitelist_entries; + indx ++; + Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_BROADCAST_MODE; + rq.cparam = &cp; + rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_observation_proc_cp cp; + uint8_t status; + + cp.scan_interval = scan_interval; + cp.scan_window = scan_window; + cp.scan_type = scan_type; + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_OBSERVATION_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) +{ + struct hci_request rq; + gap_is_device_bonded_cp cp; + uint8_t status; + + cp.peer_address_type = peer_address_type; + Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_IS_DEVICE_BONDED; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) +{ + struct hci_request rq; + gap_get_bonded_devices_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_BONDED_DEVICES; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (rp.status) { + return rp.status; + } + + *num_devices = rp.num_addr; + if(device_list != NULL) + Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1505 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.c +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : File with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_gatt_init(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INIT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[19]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, service_uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = service_type; + indx++; + + buffer[indx] = max_attr_records; + indx++; + + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle) +{ + struct hci_request rq; + gatt_include_serv_rp resp; + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + service_handle = htobs(service_handle); + Osal_MemCpy(buffer, &service_handle, 2); + indx += 2; + + included_start_handle = htobs(included_start_handle); + Osal_MemCpy(buffer+indx, &included_start_handle, 2); + indx += 2; + + included_end_handle = htobs(included_end_handle); + Osal_MemCpy(buffer+indx, &included_end_handle, 2); + indx += 2; + + if(included_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } else { + uuid_len = 16; + } + + buffer[indx] = included_uuid_type; + indx++; + + Osal_MemCpy(buffer + indx, included_uuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INCLUDE_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *included_handle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[25]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + buffer[indx] = charValueLen; + indx++; + + buffer[indx] = charProperties; + indx++; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *charHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle) +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = descValueMaxLen; + indx++; + + buffer[indx] = descValueLen; + indx++; + + if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + Osal_MemCpy(buffer + indx, descValue, descValueLen); + indx += descValueLen; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = accPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR_DESC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *descHandle = btohs(resp.handle); + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = charValOffset; + indx++; + + buffer[indx] = charValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charValue, charValueLen); + indx += charValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_char_cp cp; + + cp.service_handle = htobs(servHandle); + cp.char_handle = htobs(charHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_CHAR; + rq.cparam = &cp; + rq.clen = GATT_DEL_CHAR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_service(uint16_t servHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_serv_cp cp; + + cp.service_handle = htobs(servHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_inc_serv_cp cp; + + cp.service_handle = htobs(servHandle); + cp.inc_serv_handle = htobs(includeServHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_INC_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_INC_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) +{ + struct hci_request rq; + uint8_t status; + gatt_set_evt_mask_cp cp; + + cp.evt_mask = htobs(event_mask); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_EVT_MASK; + rq.cparam = &cp; + rq.clen = GATT_SET_EVT_MASK_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_exchange_config_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_EXCHANGE_CONFIG; + rq.cparam = &cp; + rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) +{ + struct hci_request rq; + uint8_t status; + att_find_info_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_INFO_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_find_by_type_value_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + Osal_MemCpy(cp.uuid, uuid, 2); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_group_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_prepare_write_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.value_offset = htobs(value_offset); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) +{ + struct hci_request rq; + uint8_t status; + att_execute_write_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.execute = execute; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_prim_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_prim_service_by_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; + rq.cparam = &cp; + rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, + uint16_t end_service_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_find_included_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_service_handle); + cp.end_handle = htobs(end_service_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_of_serv_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_attr_handle = htobs(start_attr_handle); + cp.end_attr_handle = htobs(end_attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t charUuidType, + const uint8_t* charUuid) +{ + struct hci_request rq; + uint8_t status; + + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + start_handle = htobs(start_handle); + Osal_MemCpy(buffer + indx, &start_handle, 2); + indx += 2; + + end_handle = htobs(end_handle); + Osal_MemCpy(buffer + indx, &end_handle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == 0x01){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_descriptors_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.char_val_handle = htobs(char_val_handle); + cp.char_end_handle = htobs(char_end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_read_using_charac_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; + rq.cparam = &cp; + rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles) +{ + struct hci_request rq; + uint8_t status; + gatt_read_multiple_charac_val_cp cp; + + if(num_handles*2 > sizeof(cp.set_of_handles)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.num_handles = htobs(num_handles); + Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_long_charac_val_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; + rq.cparam = &cp; + rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_signed_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_confirm_indication_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_CONFIRM_INDICATION; + rq.cparam = &cp; + rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = write_status; + indx += 1; + + buffer[indx] = err_code; + indx += 1; + + buffer[indx] = att_val_len; + indx += 1; + + Osal_MemCpy(buffer + indx, att_val, att_val_len); + indx += att_val_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(uint16_t conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ALLOW_READ; + rq.cparam = &cp; + rq.clen = GATT_ALLOW_READ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission) +{ + struct hci_request rq; + gatt_set_security_permission_cp cp; + uint8_t status; + + cp.service_handle = htobs(service_handle); + cp.attr_handle = htobs(attr_handle); + cp.security_permission = security_permission; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; + rq.cparam = &cp; + rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + charDescHandle = htobs(charDescHandle); + Osal_MemCpy(buffer + indx, &charDescHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charDescValOffset, 2); + indx += 2; + + buffer[indx] = charDescValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); + indx += charDescValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_DESC_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_cp cp; + gatt_read_handle_val_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = btohs(rp.value_len); + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_offset_cp cp; + gatt_read_handle_val_offset_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rp.value_len; + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value) +{ + struct hci_request rq; + uint8_t status; + gatt_upd_char_val_ext_cp cp; + + if(value_length > sizeof(cp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.service_handle = htobs(service_handle); + cp.char_handle = htobs(char_handle); + cp.update_type = update_type; + cp.char_length = htobs(char_length); + cp.value_offset = htobs(value_offset); + cp.value_length = value_length; + Osal_MemCpy(cp.value, value, value_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL_EXT; + rq.cparam = &cp; + rq.clen = GATT_UPD_CHAR_VAL_EXT_CP_SIZE + value_length; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,266 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number) +{ + struct hci_request rq; + hal_get_fw_build_number_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_FW_BUILD_NUMBER; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *build_number = rp.build_number; + + return 0; +} + +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((len+2) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = offset; + indx++; + + buffer[indx] = len; + indx++; + + Osal_MemCpy(buffer + indx, val, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + hal_read_config_data_cp cp; + hal_read_config_data_rp rp; + + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_READ_CONFIG_DATA; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rq.rlen-1; + + Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) +{ + struct hci_request rq; + hal_set_tx_power_level_cp cp; + uint8_t status; + + cp.en_high_power = en_high_power; + cp.pa_level = pa_level; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets) +{ + struct hci_request rq; + hal_le_tx_test_packet_number_rp resp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_LE_TX_TEST_PACKET_NUMBER; + rq.rparam = &resp; + rq.rlen = sizeof(resp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *number_of_packets = btohl(resp.number_of_packets); + + return 0; +} + +tBleStatus aci_hal_device_standby(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_DEVICE_STANDBY; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_start(uint8_t rf_channel) +{ + struct hci_request rq; + hal_tone_start_cp cp; + uint8_t status; + + cp.rf_channel = rf_channel; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_START; + rq.cparam = &cp; + rq.clen = HAL_TONE_START_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_stop(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_STOP; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]) +{ + struct hci_request rq; + hal_get_link_status_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_LINK_STATUS; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(link_status,rp.link_status,sizeof(link_status)); + for(int i = 0; i < 8; i++) + conn_handle[i] = btohs(rp.conn_handle[i]); + + return 0; +} + +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot) +{ + struct hci_request rq; + hal_get_anchor_period_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_ANCHOR_PERIOD; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *anchor_period = btohl(rp.anchor_period); + *max_free_slot = btohl(rp.max_free_slot); + + return 0; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,117 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB05A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.min_ce_length = htobs(min_ce_length); + cp.max_ce_length = htobs(max_ce_length); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB04A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,269 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_updater_aci.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_updater_reboot(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_get_updater_version(uint8_t *version) +{ + struct hci_request rq; + get_updater_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_VERSION; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) +{ + struct hci_request rq; + get_updater_bufsize_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_BUFSIZE; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_reset_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = htobl(address); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_SECTOR; + rq.cparam = &cp; + rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_program_data_block(uint32_t address, + uint16_t len, + const uint8_t *data) +{ + struct hci_request rq; + uint8_t status; + updater_prog_data_block_cp cp; + + if( len > sizeof(cp.data)) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(len); + Osal_MemCpy(cp.data, data, len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_read_data_block(uint32_t address, + uint16_t data_len, + uint8_t *data) +{ + struct hci_request rq; + updater_read_data_block_cp cp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + + if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(data_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; + rq.rparam = buffer; + rq.rlen = data_len + 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + // First byte is status + Osal_MemCpy(data, buffer+1, data_len); + + return buffer[0]; +} + +tBleStatus aci_updater_calc_crc(uint32_t address, + uint8_t num_sectors, + uint32_t *crc) +{ + struct hci_request rq; + updater_calc_crc_cp cp; + updater_calc_crc_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + cp.address = htobl(address); + cp.num_sectors = num_sectors; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_CALC_CRC; + rq.cparam = &cp; + rq.clen = UPDATER_CALC_CRC_CP_SIZE; + rq.rparam = &resp; + rq.rlen = UPDATER_CALC_CRC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *crc = btohl(resp.crc); + + return resp.status; +} + +tBleStatus aci_updater_hw_version(uint8_t *version) +{ + struct hci_request rq; + updater_hw_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_HW_VERSION; + rq.rparam = &resp; + rq.rlen = UPDATER_HW_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,423 @@ + +#include "ble_hal.h" +#include "ble_hal_types.h" +#include "ble_status.h" +#include "bluenrg_aci.h" +#include "bluenrg_utils.h" +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "ble_osal.h" +#include "string.h" +#include "stm32_bluenrg_ble.h" + +#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 +#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 + +#define BASE_ADDRESS 0x10010000 + +#define FW_OFFSET (2*1024) // 2 KB +#define FW_OFFSET_MS 0 +#define FULL_STACK_SIZE (66*1024) // 66 KB +#define BOOTLOADER_SIZE (2*1024) // 2 kB +#define SECTOR_SIZE (2*1024) // 2 KB + +// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + +// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 +#define CRC_POLY 0x04C11DB7 // the poly without the x**32 + +#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC + +#define IFR_SIZE 192 +#define IFR_BASE_ADDRESS 0x10020000 +#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data + +#if BLUENRG_MS +#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET +#else +#define IFR_WRITE_OFFSET_BEGIN 0 +#endif + + +#define BLUE_FLAG_OFFSET 0x8C0 +#define MAX_ERASE_RETRIES 2 +#define MAX_WRITE_RETRIES 2 +#define MIN_WRITE_BLOCK_SIZE 4 +#define MAX_WRITE_BLOCK_SIZE 64 // 64 bytes +#define READ_BLOCK_SIZE 64 // 64 bytes + +#define RETRY_COMMAND(func, num_ret, error) \ +{ \ + uint8_t num_retries; \ + num_retries = 0; \ + error = 0; \ + while (num_retries++ < num_ret) { \ + if (func == BLE_STATUS_SUCCESS) \ + break; \ + if (num_retries == num_ret) \ + error = BLE_UTIL_ACI_ERROR; \ + } \ +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, + they are extended with 0xFF until sector size is reached +*/ +static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) +{ + uint32_t i, j, a1; + uint32_t crc, value; + + crc = 0; + for (i = 0; i < SECTOR_SIZE; i += 4) { + uint8_t *dataw = (uint8_t *) &value; + + dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; + dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; + dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; + dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; + + crc = crc ^ value; + for (j = 0; j < 32; j ++) { + a1 = (crc >> 31) & 0x1; + crc = (crc << 1) ^ (a1 * CRC_POLY); + } + } + + return crc; +} + +int program_device(const uint8_t *fw_image, uint32_t fw_size) +{ + uint8_t version, num_erase_retries, status, write_block_size; + uint32_t address; + uint32_t crc, crc2, crc_size; + uint32_t fw_offset = FW_OFFSET; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + if(aci_updater_hw_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version==0x31){ + // It does not contain bootloader inside first sector. It may contain code. + fw_offset = FW_OFFSET_MS; + } + + if (fw_size != FULL_STACK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + if (fw_size % MIN_WRITE_BLOCK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + + /*********************************************************************** + * Erase BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + /*********************************************************************** + * Erase and Program sectors + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE) { + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(BASE_ADDRESS + i); + for (int j=i; ((j<i+SECTOR_SIZE)&&(j<fw_size)); j += write_block_size) { + + write_block_size = MIN(fw_size-j, MAX_WRITE_BLOCK_SIZE); + + RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, write_block_size, fw_image+j), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + break; + } + if (status == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + } + + /*********************************************************************** + * Verify firmware + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE){ + address = BASE_ADDRESS + i; + if(aci_updater_calc_crc(address, 1, &crc)) + return BLE_UTIL_ACI_ERROR; + + crc_size = MIN(fw_size-i,SECTOR_SIZE); + + crc2 = updater_calc_crc(fw_image+i,crc_size); + if(crc!=crc2) + return BLE_UTIL_CRC_ERROR; + } + + /*********************************************************************** + * Write BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +int read_IFR(uint8_t *data) +{ + uint8_t version, offset; + tBleStatus ret; + + offset = 0; + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + /*********************************************************************** + * Reading last 3 IFR 64-byte blocks + ************************************************************************/ + for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(BASE_ADDRESS+i, READ_BLOCK_SIZE, (data+offset)); + offset += READ_BLOCK_SIZE; + if(ret) return BLE_UTIL_ACI_ERROR; + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; + +} + +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) +{ + IFR_config->stack_mode = data[0]; + IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); + IFR_config->master_sca = data[30]; + IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); + IFR_config->year = BCD_TO_INT(data[41]); + IFR_config->month = BCD_TO_INT(data[42]); + IFR_config->day = BCD_TO_INT(data[43]); +} + +int IFR_validate(IFR_config2_TypeDef *IFR_config) +{ +#if BLUENRG_MS + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) +#else + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) +#endif + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode + if(IFR_config->master_sca > 7) + return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->day > 31 || IFR_config->day < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + + return BLE_STATUS_SUCCESS; +} + +/* TODO: Function to generate data from given options. */ + +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) +{ + data[0] = IFR_config->stack_mode; + HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); + data[30] = IFR_config->master_sca; + HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); + data[41] = INT_TO_BCD(IFR_config->year); + data[42] = INT_TO_BCD(IFR_config->month); + data[43] = INT_TO_BCD(IFR_config->day); +} + + +int program_IFR(const IFR_config_TypeDef *ifr_image) +{ + uint8_t version, num_erase_retries; + tBleStatus ret; +#if BLUENRG_MS + const uint8_t *ifr_data = (uint8_t *)ifr_image; +#else + uint8_t ifr_data[SECTOR_SIZE]; +#endif + uint8_t hwVersion; + uint16_t fwVersion; + + if(getBlueNRGVersion(&hwVersion, &fwVersion)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + +#ifndef BLUENRG_MS + /*********************************************************************** + * READ IFR data + ************************************************************************/ + for(int i = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_data+i); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + } +#endif + + /*********************************************************************** + * Erase & Flashing IFR sectors + ************************************************************************/ +#ifndef BLUENRG_MS + Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); +#endif + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(IFR_BASE_ADDRESS); + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += MAX_WRITE_BLOCK_SIZE, j += MAX_WRITE_BLOCK_SIZE) { + RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, MAX_WRITE_BLOCK_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); + if (ret != BLE_STATUS_SUCCESS) + break; + } + if (ret == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + + /*********************************************************************** + * Verify IFR + ************************************************************************/ + { + uint8_t ifr_updated[READ_BLOCK_SIZE]; + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE, j += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ifr_data+j, READ_BLOCK_SIZE) != 0) + return BLE_UTIL_WRONG_VERIFY; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) +{ + uint8_t ifr_updated[READ_BLOCK_SIZE]; + uint8_t version, ret = BLE_STATUS_SUCCESS; + + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + for(int i = 0; i < IFR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, READ_BLOCK_SIZE) != 0) + { + ret = BLE_UTIL_WRONG_VERIFY; + break; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return ret; +} + +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) +{ + uint8_t status; + uint8_t hci_version, lmp_pal_version; + uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; + + status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, + &manufacturer_name, &lmp_pal_subversion); + + if (status == BLE_STATUS_SUCCESS) { + *hwVersion = hci_revision >> 8; + *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number + *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number + *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number + } + + return status; +} + +uint8_t getBlueNRGUpdaterVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(version)) + return BLE_UTIL_ACI_ERROR; + + if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_updater_hw_version(version)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t isHWBootloader_Patched(void) +{ + uint8_t status, version; + uint32_t crc, address = 0x10010000; + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); + if (status != BLE_STATUS_SUCCESS) + return 0; + + if (crc == BOOTLOADER_CRC_NOT_PATCHED) + return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +#include "ble_gp_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function sets a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * @param[in] t A pointer to the timer + * @param[in] interval The interval before the timer expires. + * + */ +void +Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +Timer_Expired(struct timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + tClockTime diff = (Clock_Time() - t->start) + 1; + return t->interval < diff; + +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +tClockTime +Timer_Remaining(struct timer *t) +{ + return t->start + t->interval - Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +#ifdef __DMA_LP__ + +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID) +{ + TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, + (pf_TIMER_TimerCallBack_t) timercb); + TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); + + return (BLE_STATUS_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) +{ + TIMER_Delete(timerID); + + return (BLE_STATUS_SUCCESS); +} + +#endif /* __DMA_LP__ */ +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,119 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Circular Linked List Implementation. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/****************************************************************************** + * Include Files +******************************************************************************/ +#include <ble_hal_types.h> +#include "ble_list.h" + +/****************************************************************************** + * Function Definitions +******************************************************************************/ +void list_init_head (tListNode * listHead) +{ + listHead->next = listHead; + listHead->prev = listHead; +} + +uint8_t list_is_empty (tListNode * listHead) +{ + return ((listHead->next == listHead)? TRUE:FALSE); +} + +void list_insert_head (tListNode * listHead, tListNode * node) +{ + node->next = listHead->next; + node->prev = listHead; + listHead->next = node; + (node->next)->prev = node; +} + + +void list_insert_tail (tListNode * listHead, tListNode * node) +{ + node->next = listHead; + node->prev = listHead->prev; + listHead->prev = node; + (node->prev)->next = node; +} + + +void list_remove_node (tListNode * node) +{ + (node->prev)->next = node->next; + (node->next)->prev = node->prev; +} + + +void list_remove_head (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->next; + list_remove_node (listHead->next); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_remove_tail (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->prev; + list_remove_node (listHead->prev); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_insert_node_after (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node->next; + node->prev = ref_node; + ref_node->next = node; + (node->next)->prev = node; +} + + +void list_insert_node_before (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node; + node->prev = ref_node->prev; + ref_node->prev = node; + (node->prev)->next = node; +} + + +int list_get_size (tListNode * listHead) +{ + int size = 0; + tListNode * temp = listHead->next; + while (temp != listHead) + { + size++; + temp = temp->next; + } + return (size); +} + +void list_get_next_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->next; +} + + +void list_get_prev_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->prev; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,72 @@ +/** +****************************************************************************** +* @file ble_osal.c +* @author AMS - HEA&RF BU / CL +* @version V1.0.0 +* @date 04-July-2014 +* @brief Implementation of OS abstraction layer functions used by the +* library. +****************************************************************************** +* @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> +#include <ble_osal.h> + + /** + * @brief Osal_MemCpy + * @param dest: Pointer to the destination buffer + * @param src : Pointer to the source buffer + * @param size: Number of bytes to copy from the source to the destination + * buffer + * @retval Pointer to the destination buffer + */ +void* Osal_MemCpy(void *dest, const void *src, unsigned int size) +{ + return(memcpy(dest,src,size)); +} + +/** + * @brief Osal_MemSet + * @param ptr : Pointer to block of memory to fill + * @param value: Value to assign to each byte of the memory block + * @param size : Number of bytes to be set to "value" + * @retval Pointer to the filled block of memory + */ +void* Osal_MemSet(void *ptr, int value, unsigned int size) +{ + return(memset(ptr,value,size)); +} + +/****************************************************************************** + * local Functions + *****************************************************************************/ + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ + +#include "ble_clock.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/wait_api.h" + #include "mbed-drivers/rtc_time.h" +#else + #include "wait_api.h" + #include "rtc_time.h" +#endif + +const uint32_t CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + //Not Used +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return clock(); +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,715 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file btle.cpp + * @author STMicroelectronics + * @brief Implementation BlueNRG Init and helper functions. + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + + +#include "btle.h" +#include "ble/Gap.h" +#include "ble/GapEvents.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" + +#include "bluenrg_targets.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* C File Includes ------------------------------------------------------------------*/ +#include <stdio.h> +#include <string.h> +#include "ble_hci.h" +#include "ble_hci_const.h" +#include "bluenrg_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" +#include "bluenrg_utils.h" + +#include "ble_hal_types.h" +#include "ble_hal.h" +#include "ble_gp_timer.h" +#include "ble_osal.h" +#include "ble_sm.h" +#include "ble_debug.h" + +#ifdef __cplusplus +} +#endif + +#define IDB04A1 0 +#define IDB05A1 1 + +/* See file 'bluenrg_targets.h' for details regarding the BLUENRG_STACK_MODE */ +#define STACK_MODE BLUENRG_STACK_MODE + +void HCI_Input(tHciDataPacket * hciReadPacket); + +uint16_t g_gap_service_handle = 0; +uint16_t g_appearance_char_handle = 0; +uint16_t g_device_name_char_handle = 0; +uint16_t g_preferred_connection_parameters_char_handle = 0; + +/* Private variables ---------------------------------------------------------*/ +volatile uint8_t set_connectable = 1; + +static char versionString[32]; +uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ + +/**************************************************************************/ +/*! + @brief Init the BTLE stack with the specified role + @returns void +*/ +/**************************************************************************/ +void btleInit(void) +{ + PRINTF("btleInit>>\n\r"); + + int ret; + uint8_t hwVersion; + uint16_t fwVersion; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* get the BlueNRG HW and FW versions */ + getBlueNRGVersion(&hwVersion, &fwVersion); + + /* + * Reset BlueNRG again otherwise we won't + * be able to change its MAC address. + * aci_hal_write_config_data() must be the first + * command after reset otherwise it will fail. + */ + BlueNRG_RST(); + + if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ + bnrg_expansion_board = IDB05A1; + } + + /* set BLE version string */ + setVersionString(hwVersion, fwVersion); + + if (bnrg_expansion_board == IDB05A1) { + uint8_t stackMode = STACK_MODE; + ret = aci_hal_write_config_data(CONFIG_DATA_MODE_OFFSET, + CONFIG_DATA_MODE_LEN, + &stackMode); + } + + ret = aci_gatt_init(); + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GATT_Init failed.\n"); + } + if (bnrg_expansion_board == IDB05A1) { + ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1, + 0, + 0x18, + &service_handle, + &dev_name_char_handle, + &appearance_char_handle); + } else { + // IDB04A1 is configured as peripheral by default + ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + } + + // read the default static address and inject it into the GAP object + { + Gap::Address_t BLE_address_BE = { 0 }; + uint8_t data_len_out; + aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS, BDADDR_SIZE, &data_len_out, BLE_address_BE); + // FIXME error handling of this function + BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE); + } + + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GAP_Init failed.\n"); + } + + //FIXME: Security and passkey set by default + ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, + OOB_AUTH_DATA_ABSENT, + NULL, + 7, + 16, + USE_FIXED_PIN_FOR_PAIRING, + 123456, + BONDING); + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Auth Req set failed.\n"); + } + + aci_hal_set_tx_power_level(1,4); + + g_gap_service_handle = service_handle; + g_appearance_char_handle = appearance_char_handle; + g_device_name_char_handle = dev_name_char_handle; + //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API + /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, + strlen(name), (tHalUint8 *)name);*/ + + signalEventsToProcess(); + // update the peripheral preferred conenction parameters handle + // This value is hardcoded at the moment. + g_preferred_connection_parameters_char_handle = 10; + + return; +} + +/**************************************************************************/ +/*! + @brief mbedOS + + @param[in] void + + @returns +*/ +/**************************************************************************/ +int btle_handler_pending = 0; + +void btle_handler(void) +{ + btle_handler_pending = 0; + BlueNRGGap::getInstance().Process(); + HCI_HandleSPI(); + HCI_Process(); +} + +/* set BLE Version string */ +void setVersionString(uint8_t hwVersion, uint16_t fwVersion) +{ + if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) { + snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u", + hwVersion>>4, (hwVersion&0x0F), + fwVersion>>8, (fwVersion&0x00F0)>>4); + } else { + snprintf(versionString, sizeof(versionString), "ST (unknown spec)"); + } +} + +/* get BLE Version string */ +const char* getVersionString(void) +{ + return versionString; +} + +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type) +{ + tBleStatus ret; + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + if(bnrg_expansion_board == IDB05A1) { + PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window); + PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type); + ret = aci_gap_start_observation_procedure(scan_interval, + scan_window, + scan_type, + own_address_type, + 0); // 1 to filter duplicates + } else { + ret = BLE_STATUS_INVALID_CID; + } + + return ret; + +} + +/*! + @brief Not Used + + @param[in] void + + @returns +*/ +void SPI_Poll(void) +{ + //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); + return; +} + +void Attribute_Modified_CB(evt_blue_aci *blue_evt) +{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t *att_data; + uint8_t offset; + + if (bnrg_expansion_board == IDB05A1) { + evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = evt->offset; + } else { + evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = 0; + } + + //Extract the GattCharacteristic from p_characteristics[] and find the properties mask + GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle); + if(p_char!=NULL) { + GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE; + PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]); + PRINTF("getProperties 0x%x\n\r",p_char->getProperties()); + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; + } + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; + } + PRINTF("currentHandle %d\n\r", currentHandle); + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && + currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { + + GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1; + + PRINTF("*****NOTIFICATION CASE\n\r"); + //Now Check if data written in Enable or Disable + if((uint16_t)att_data[0]==1) { + //PRINTF("Notify ENABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle); + } else { + //PRINTF("Notify DISABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle); + } + return; + } + + //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) && + currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) { + + PRINTF("*****WRITE CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = p_char->getValueAttribute().getHandle(); + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle); + //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + BlueNRGGattServer::getInstance().write( + p_char->getValueAttribute().getHandle(), + (uint8_t*)att_data, + data_length, + false + ); + } + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } else { + PRINTF("*****WRITE DESCRIPTOR CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = attr_handle; + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } + } + +} + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************************/ + /*! + @brief Handle HCI Stack Event + + @param[in] pckt + Event Packet sent by the stack to be decoded + + @returns + */ + /**************************************************************************/ + extern void HCI_Event_CB(void *pckt) { + hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; + hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; + + if(hci_pckt->type != HCI_EVENT_PKT) + return; + + switch(event_pckt->evt){ + + case EVT_DISCONN_COMPLETE: + { + PRINTF("EVT_DISCONN_COMPLETE\n"); + + evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data; + + if(BlueNRGGap::getInstance().getGapRole() == Gap::CENTRAL) { + BlueNRGGattClient::getInstance().removeGattConnectionClient(evt->handle, evt->reason); + } + + BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason); + } + break; + + case EVT_LE_META_EVENT: + { + PRINTF("EVT_LE_META_EVENT\n"); + + evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; + + switch(evt->subevent){ + + case EVT_LE_CONN_COMPLETE: + { + PRINTF("EVT_LE_CONN_COMPLETE\n"); + Gap::Address_t ownAddr; + Gap::AddressType_t ownAddrType; + BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr); + + Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + Gap::Role_t role; + + evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; + + BlueNRGGap::getInstance().setConnectionHandle(cc->handle); + BlueNRGGap::ConnectionParams_t connectionParams = { + /* minConnectionInterval = */ cc->interval, + /* maxConnectionInterval = */ cc->interval, + /* slaveLatency = */ cc->latency, + /* connectionSupervisionTimeout = */ cc->supervision_timeout + }; + + BlueNRGGap::getInstance().setConnectionInterval(cc->interval); + + switch (cc->peer_bdaddr_type) { + case PUBLIC_ADDR: + peerAddrType = BLEProtocol::AddressType::PUBLIC; + break; + case STATIC_RANDOM_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + break; + case RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE; + break; + case NON_RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE; + break; + } + //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role); + switch (cc->role) { + case 0: //master + role = Gap::CENTRAL; + BlueNRGGattClient::getInstance().createGattConnectionClient(cc->handle); + break; + case 1: + role = Gap::PERIPHERAL; + break; + default: + role = Gap::PERIPHERAL; + break; + } + + BlueNRGGap::getInstance().setGapRole(role); + + BlueNRGGap::getInstance().processConnectionEvent(cc->handle, + role, + peerAddrType, + cc->peer_bdaddr, + ownAddrType, + ownAddr, + &connectionParams); + } + break; + + case EVT_LE_ADVERTISING_REPORT: + PRINTF("EVT_LE_ADVERTISING_REPORT\n\r"); + /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */ + // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT) + // Formally the structure related to both events are identical except that for the ADV REPORT + // there is one more field (number of reports) which is not forwarded to upper layer. + // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT. + le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1); + PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + break; + } + } + break; + + case EVT_VENDOR: + { + evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; + //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode); + + switch(blue_evt->ecode){ + + case EVT_BLUE_GATT_WRITE_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_WRITE_PERMIT_REQ\r\n"); + evt_gatt_write_permit_req* write_req = (evt_gatt_write_permit_req*)blue_evt->data; + + // ask the local server if the write operation is authorized + uint8_t err_code = BlueNRGGattServer::getInstance().Write_Request_CB( + write_req->conn_handle, + write_req->attr_handle, + write_req->data_length, + write_req->data + ); + uint8_t write_status = err_code == 0 ? 0 : 1; + + // reply to the shield + aci_gatt_write_response( + write_req->conn_handle, + write_req->attr_handle, + write_status, + err_code, + write_req->data_length, + write_req->data + ); + } + break; + + case EVT_BLUE_GATT_READ_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r"); + evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle); + BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle); + } + break; + + case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: + { + PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r"); + /* this callback is invoked when a GATT attribute is modified + extract callback data and pass to suitable handler function */ + Attribute_Modified_CB(blue_evt); + } + break; + + //Any cases for Data Sent Notifications? + case EVT_BLUE_GATT_NOTIFICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_NOTIFICATION"); + break; + case EVT_BLUE_GATT_INDICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_INDICATION"); + break; + + case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r"); + evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_data_length, + pr->attribute_data_list); + } + break; + case EVT_BLUE_ATT_READ_BY_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r"); + evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle, + pr->event_data_length, + pr->handle_value_pair_length, + pr->handle_value_pair); + } + break; + case EVT_BLUE_ATT_READ_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_RESP\n\r"); + evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_value); + } + break; + case EVT_BLUE_ATT_EXEC_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle, + pr->event_data_length); + } + break; + case EVT_BLUE_ATT_PREPARE_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_handle, + pr->offset, + pr->part_attr_value); + } + break; + case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP: + { + PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r"); + evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle, + pr->event_data_length, + pr->attr_handle, + pr->attr_value); + } + break; + case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r"); + evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle, + pr->event_data_length, + pr->handles_info_list); + } + break; + case EVT_BLUE_ATT_FIND_INFORMATION_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r"); + evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle, + pr->event_data_length, + pr->format, + pr->handle_uuid_pair); + } + break; + case EVT_BLUE_GATT_PROCEDURE_COMPLETE: + { + evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code); + BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code); + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_REQ: + { + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_REQ\r\n"); + evt_l2cap_conn_upd_req *evt = (evt_l2cap_conn_upd_req*)blue_evt->data; + if(bnrg_expansion_board == IDB05A1) { + // we assume the application accepts the request from the slave + aci_l2cap_connection_parameter_update_response_IDB05A1(evt->conn_handle, + evt->interval_min, + evt->interval_max, + evt->slave_latency, + evt->timeout_mult, + CONN_L1, CONN_L2, + evt->identifier, + 0x0000); + } + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_RESP: + { + evt_l2cap_conn_upd_resp *evt = (evt_l2cap_conn_upd_resp*)blue_evt->data; + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_RESP code=0x%x, result=0x%x\r\n", evt->code, evt->result); + } + break; + + case EVT_LE_CONN_UPDATE_COMPLETE: + { + evt_le_connection_update_complete *evt = (evt_le_connection_update_complete*)blue_evt->data; + PRINTF("EVT_LE_CONN_UPDATE_COMPLETE status=0x%x\r\n", evt->status); + } + break; + + case EVT_BLUE_GAP_DEVICE_FOUND: + { + evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data; + PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + } + break; + + case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + { + evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data; + //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code); + + switch(pr->procedure_code) { + case GAP_OBSERVATION_PROC_IDB05A1: + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL); + break; + } + } + break; + } + } + break; + } + return ; + } + + +#ifdef __cplusplus +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,217 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.cpp + * @author CL + * @version V1.0.0 + * @date 15-June-2015 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRGGap.h" +#include "BlueNRGDevice.h" +#include "btle.h" + +// FIXME: find a better way to get the instance of the BlueNRG device +extern BlueNRGDevice bluenrgDeviceInstance; + + +//////////////////////////////////////// +// Start of C function wrappers +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32_bluenrg_ble.h" +#include "ble_debug.h" + + +void BlueNRG_RST(void) +{ + bluenrgDeviceInstance.reset(); +} + +uint8_t BlueNRG_DataPresent(void) +{ + return (bluenrgDeviceInstance.dataPresent()); +} + + +/** + * @brief This function is a utility to print the log time +* in the format HH:MM:SS:MSS (DK GUI time format) + * @param None + * @retval None + */ +void print_csv_time(void){ +#ifdef PRINT_CSV_FORMAT + uint32_t ms = 0;//ms_counter; + PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000); +#endif +} + +/** + * @brief Writes data to a serial interface. + * @param data1 : 1st buffer + * @param data2 : 2nd buffer + * @param n_bytes1: number of bytes in 1st buffer + * @param n_bytes2: number of bytes in 2nd buffer + * @retval None + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, + int32_t n_bytes2) +{ + struct timer t; + + Timer_Set(&t, CLOCK_SECOND/10); + +#ifdef PRINT_CSV_FORMAT + print_csv_time(); + for (int i=0; i<n_bytes1; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data1)[i]); + } + for (int i=0; i<n_bytes2; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data2)[i]); + } + PRINT_CSV("\n"); +#endif + + while(1){ + if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; + if(Timer_Expired(&t)){ + break; + } + } +} + + +/** + * @brief Activate internal bootloader using pin. + * @param None + * @retval None + */ +void BlueNRG_HW_Bootloader(void) +{ + // Reset BlueNRG SPI interface + BlueNRG_RST(); + + // Send an ACI command to reboot BlueNRG in bootloader mode + // The safest way to get in bootloader mode is keeping high + // the interrupt pin during reset, but this would require many + // changes to the current mbed driver + aci_updater_start(); +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size) +{ + int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size); + + return ret; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2); + + return ret; +} + +/** + * @brief Enable SPI IRQ. + * @param None + * @retval None + */ +void Enable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.enable_irq(); +} + +void signalEventsToProcess(void) { + if(btle_handler_pending == 0) { + btle_handler_pending = 1; + bluenrgDeviceInstance.signalEventsToProcess(BLE::DEFAULT_INSTANCE); + } +} + +/** + * @brief Disable SPI IRQ. + * @param None + * @retval None + */ +void Disable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.disable_irq(); +} + +/** + * @brief Clear Pending SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_IRQ(void) +{ +} + +/** + * @brief Clear EXTI (External Interrupt) line for SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_EXTI_Flag(void) +{ +} + + + + +#ifdef __cplusplus +} +#endif +// End of C function wrappers +//////////////////////////////////////// + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <ble_payload.h> + +Payload::Payload() { + stringLength = 0; + payloadUnitCount = 0; + payload = NULL; +} + +Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + stringLength = string_ength; + payloadUnitCount = 0; + payload = NULL; + + int index = 0; + while( index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + UnitPayload *obj = new UnitPayload[payloadUnitCount]; + int i=0; + int c=0; + int j,k; + + while(i<payloadUnitCount) + { + obj[i].length=tokenString[c]; + obj[i].id=tokenString[c+1]; + + obj[i].data = new uint8_t[obj[i].length]; + for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) + { + obj[i].data[k]=tokenString[j]; + + } + + c=c+obj[i].length+1; + i++; + + } + payload = obj; +} + +uint8_t Payload::getPayloadUnitCount() { + return payloadUnitCount; +} + +uint8_t Payload::getIDAtIndex(int index) { + return payload[index].get_id(); +} + +uint8_t Payload::getLengthAtIndex(int index) { + return payload[index].get_length(); +} + +uint8_t* Payload::getDataAtIndex(int index) { + return payload[index].get_data(); +} + +int8_t Payload::getInt8AtIndex(int index) { + uint8_t* str = payload[index].get_data(); + int8_t value = (int8_t)str[0]; + return value; +} + +uint16_t Payload::getUint16AtIndex(int index) { + uint16_t* str = (uint16_t*)payload[index].get_data(); + uint16_t value = str[0]; + return value; +} + +uint8_t* Payload::getSerializedAdDataAtIndex(int index) { + uint8_t length = payload[index].get_length(); + uint8_t* data = payload[index].get_data(); + uint8_t id = payload[index].get_id(); + uint8_t *serializedAdData = new uint8_t[length]; + + serializedAdData[0] = id; + for(int i=0; i<length-1; i++) { + serializedAdData[i+1] = data[i]; + } + return serializedAdData; +} + +Payload::~Payload() { + int i = 0; + + if(payload) { + while(i<payloadUnitCount) { + if(payload->data) { + delete[] payload->data; + payload->data = NULL; + } + } + delete[] payload; + payload = NULL; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,93 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ble_utils.h" + +/**************************************************************************/ +/*! + @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power + +*/ +/**************************************************************************/ +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(dBMLevel==-18) { + EN_HIGH_POWER = 0; + PA_LEVEL = 0; + } + else if(dBMLevel==-15) { + EN_HIGH_POWER = 0; + PA_LEVEL = 1; + } + else if(dBMLevel==-14) { + EN_HIGH_POWER = 1; + PA_LEVEL = 0; + } + else if(dBMLevel==-12) { + EN_HIGH_POWER = 0; + PA_LEVEL = 2; + } + else if(dBMLevel==-11) { + EN_HIGH_POWER = 1; + PA_LEVEL = 1; + } + else if(dBMLevel==-9) { + EN_HIGH_POWER = 0; + PA_LEVEL = 3; + } + else if(dBMLevel==-8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 2; + } + else if(dBMLevel==-6) { + EN_HIGH_POWER = 0; + PA_LEVEL = 4; + } + else if(dBMLevel==-5) { + EN_HIGH_POWER = 1; + PA_LEVEL = 3; + } + else if(dBMLevel==-2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 4; + } + else if(dBMLevel==0) { + EN_HIGH_POWER = 0; + PA_LEVEL = 6; + } + else if(dBMLevel==2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 5; + } + else if(dBMLevel==4) { + EN_HIGH_POWER = 1; + PA_LEVEL = 6; + } + else if(dBMLevel==5) { + EN_HIGH_POWER = 0; + PA_LEVEL = 7; + } + else if(dBMLevel==8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + else { + ret = ERR_INVALID_HCI_CMD_PARAMS; + } + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_HeartRate/source/main.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,127 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <events/mbed_events.h> +#include <mbed.h> +#include "ble/BLE.h" +#include "ble/Gap.h" +#include "ble/services/HeartRateService.h" + +DigitalOut led1(LED1, 1); + +const static char DEVICE_NAME[] = "HRM"; +static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE}; + +static uint8_t hrmCounter = 100; // init HRM to 100bps +static HeartRateService *hrServicePtr; + +static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); + +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) +{ + BLE::Instance().gap().startAdvertising(); // restart advertising +} + +void updateSensorValue() { + // Do blocking calls or whatever is necessary for sensor polling. + // In our case, we simply update the HRM measurement. + hrmCounter++; + + // 100 <= HRM bps <=175 + if (hrmCounter == 175) { + hrmCounter = 100; + } + + hrServicePtr->updateHeartRate(hrmCounter); +} + +void periodicCallback(void) +{ + led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ + + if (BLE::Instance().getGapState().connected) { + eventQueue.call(updateSensorValue); + } +} + +void onBleInitError(BLE &ble, ble_error_t error) +{ + (void)ble; + (void)error; + /* Initialization error handling should go here */ +} + +void printMacAddress() +{ + /* Print out device MAC address to the console*/ + Gap::AddressType_t addr_type; + Gap::Address_t address; + BLE::Instance().gap().getAddress(&addr_type, address); + printf("DEVICE MAC ADDRESS: "); + for (int i = 5; i >= 1; i--){ + printf("%02x:", address[i]); + } + printf("%02x\r\n", address[0]); +} + +void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) +{ + BLE& ble = params->ble; + ble_error_t error = params->error; + + if (error != BLE_ERROR_NONE) { + onBleInitError(ble, error); + return; + } + + if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { + return; + } + + ble.gap().onDisconnection(disconnectionCallback); + + /* Setup primary service. */ + hrServicePtr = new HeartRateService(ble, hrmCounter, HeartRateService::LOCATION_FINGER); + + /* Setup advertising. */ + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.gap().setAdvertisingInterval(1000); /* 1000ms */ + ble.gap().startAdvertising(); + + printMacAddress(); +} + +void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { + BLE &ble = BLE::Instance(); + eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); +} + +int main() +{ + eventQueue.call_every(500, periodicCallback); + + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(scheduleBleEventsProcessing); + ble.init(bleInitComplete); + + eventQueue.dispatch_forever(); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/.mbed Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +ROOT=.
Binary file mbed-os-example-ble-master/BLE_LED/img/LED_OFF.png has changed
Binary file mbed-os-example-ble-master/BLE_LED/img/LED_ON.png has changed
Binary file mbed-os-example-ble-master/BLE_LED/img/connection.png has changed
Binary file mbed-os-example-ble-master/BLE_LED/img/discovery.png has changed
Binary file mbed-os-example-ble-master/BLE_LED/img/scan_results.png has changed
Binary file mbed-os-example-ble-master/BLE_LED/img/start_scan.png has changed
Binary file mbed-os-example-ble-master/BLE_LED/img/write_characteristic.png has changed
Binary file mbed-os-example-ble-master/BLE_LED/img/write_pannel.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/mbed-os.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/mbed_app.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "target_overrides": { + "K64F": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "NUCLEO_F401RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "DISCO_L475VG_IOT01A": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "ble-led", + "version": "0.0.1", + "description": "A simple service that demonstrates the use of a read-write characteristic to control a LED", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "dependencies": { + "ble": "^2.0.0" + }, + "targetDependencies": {}, + "bin": "./source" +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/readme.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,93 @@ +To help you create your own BLE services, we have created this service template. +The LED example demonstrates the use of a read-write characteristic to control a +LED through a phone app. + +The template covers: + +* Setting up advertising and connection states. +* Assigning UUIDs to the service and its characteristic. +* Creating an input characteristic: read-write, boolean. This characteristic offers control of the LED. +* Constructing a service class and adding it to the BLE stack. + +# Running the application + +## Requirements + +The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install: + +- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. + +- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +*NOTE:* If you have more than a single mbed board (e.g. nrf51dk or mkit) you can +run the BLE_LED and BLE_LEDBlinker at the same time. For more information please +refer to the BLE_LEDBlinker demo. + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Checking for success + +**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. + + +1. Build the application and install it on your board as explained in the building instructions. +1. Open the BLE scanner on your phone. + +1. Start a scan. + +  + + **figure 1** How to start scan using nRF Master Control Panel 4.0.5 + +1. Find your device; it should be named `LED`. + +  + + **figure 2** Scan results using nRF Master Control Panel 4.0.5 + +1. Establish a connection with your device. + +  + + **figure 3** How to establish a connection using Master Control Panel 4.0.5 + +1. Discover the services and the characteristics on the device. The *LED service* has the UUID `0xA000` and includes the *LED state characteristic* which has the UUID `0xA001`. Depending on your scanner, non standard 16-bit UUID's can be displayed as 128-bit UUID's. If it is the case the following format will be used: `0000XXXX-0000-1000-8000-00805F9B34FB` where `XXXX` is the hexadecimal representation of the 16-bit UUID value. + +  + + **figure 4** Representation of the Led service using Master Control Panel 4.0.5 + +1. Open the write pannel of the *LED state* characteristic. + +  + + **figure 5** How to read and write a characteristic value using Master Control Panel 4.0.5 + + +1. The characteristic accept a 1 byte value: + +  + + **figure 6** Write characteristic panel using Master Control Panel 4.0.5 + + * `0x00`: LED ON/OFF (board dependant) + +  + + **figure 6** Write characteristic panel to set the LED on using Master Control Panel 4.0.5 + + + * `0x01`: LED OFF/ON (board dependant) + +  + + **figure 6** Write characteristic panel to set the LED off using Master Control Panel 4.0.5 + + +1. Toggle the LED characteristic value and see the LED turn ON or turn OFF according to the value you set. + +If you can see the characteristic, and the LED is turned on/off as you toggle its value, the application is working properly.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/#b630517008bbe47592927cc8e5dfcd2e5b9de968
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/.gitignore Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,9 @@ +# vim temporary files +*.sw* + +# yotta files +build +yotta_modules +yotta_targets +.yotta.json +upload.tar.gz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,34 @@ +# BLE-X-NUCLEO-IDB0XA1 + +BLE_API wrapper Library for X-NUCLEO-IDB05A1 BlueNRG (Bluetooth Low Energy) Expansion Board + +## Introduction + +This firmware package implements the port of BLE_API to STMicroelectronics' [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) Bluetooth Low Energy Nucleo Expansion Board. + +### Arduino Connector Compatibility Warning + +X-NUCLEO-IDB05A1 is Arduino compatible with an exception: instead of using pin **D13** for the SPI clock, pin **D3** is used. +The default configuration for this library is having the SPI clock on pin **D3**. + +To be fully Arduino compatible, X-NUCLEO-IDB05A1 needs a small HW patch. + +For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor **R4** and instead soldering zero resistor **R6**. + +In case you patch your board, then you also have to configure this library to use pin **D13** to drive the SPI clock. To this aim you need to compile this driver with macro `BLUENRG_PIN_SPI_SCK=D13` defined. + +If you use pin **D13** for the SPI clock, please be aware that on STM32 Nucleo boards you may **not** drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin **D13**. + +Referring to the current list of tested platforms (see [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) page), the patch is required by [ST-Nucleo-F103RB](https://developer.mbed.org/platforms/ST-Nucleo-F103RB/); [ST-Nucleo-F302R8](https://developer.mbed.org/platforms/ST-Nucleo-F302R8/); [ST-Nucleo-F411RE](https://developer.mbed.org/platforms/ST-Nucleo-F411RE/); [ST-Nucleo-F446RE](https://developer.mbed.org/platforms/ST-Nucleo-F446RE/); and [FRDM-K64F](https://developer.mbed.org/platforms/FRDM-K64F/). + +### Firmware update + +For better performance and compatibility with latest mbed API, you should update firmware of X-NUCLEO-IDB05A1 component by using this simple [application](https://developer.mbed.org/teams/ST/code/BlueNRG-MS-Stack-Updater). + +### Driver configuration + +In order to use the BlueNRG-MS module together with other targets, you need to set the macros defined in file [bluenrg_targets.h](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/bluenrg/bluenrg_targets.h). Please, update the [mbed_lib.json](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/mbed_lib.json) to include the list of extra macros that configure the driver for your target. + +## Example Applications + +To run BLE example applications using X-NUCLEO-IDB05A1 Expansion Board based on mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli), please refer to section [Using ST shield on other targets](https://github.com/ARMmbed/mbed-os-example-ble#using-st-nucleo-shield-on-other-targets) in the official [mbed-os-example-ble](https://github.com/ARMmbed/mbed-os-example-ble) page.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.h + * @author STMicroelectronics + * @brief Header file for BLEDeviceInstanceBase based BlueNRGDevice + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_DEVICE_H__ +#define __BLUENRG_DEVICE_H__ + +#define BLUENRG +#define DEBUG_BLUENRG_USER + +#include "btle.h" + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "ble/BLEInstanceBase.h" +#include "ble/BLE.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" + + +class BlueNRGDevice : public BLEInstanceBase +{ + +public: + BlueNRGDevice(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, PinName irq); + virtual ~BlueNRGDevice(void); + + virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback); + virtual ble_error_t shutdown(void); + virtual const char *getVersion(void); + virtual Gap& getGap(); + virtual const Gap& getGap() const; + virtual GattServer& getGattServer(); + virtual const GattServer& getGattServer() const; + virtual void waitForEvent(void); + + virtual GattClient& getGattClient() { + return BlueNRGGattClient::getInstance(); + } + + virtual SecurityManager& getSecurityManager() { + return *sm; + } + + virtual const SecurityManager& getSecurityManager() const { + return *sm; + } + void reset(void); + virtual bool hasInitialized(void) const { + return isInitialized; + } + + uint8_t getUpdaterHardwareVersion(uint8_t *hw_version); + int updateFirmware(const uint8_t *fw_image, uint32_t fw_size); + bool dataPresent(); + int32_t spiRead(uint8_t *buffer, uint8_t buff_size); + int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2); + void disable_irq(); + void enable_irq(); + + virtual void processEvents(); + +private: + bool isInitialized; + + SPI spi_; + DigitalOut nCS_; + DigitalOut rst_; + InterruptIn irq_; + + //FIXME: TBI (by now just placeholders to let build + /*** betzw: placeholders ***/ + SecurityManager *sm; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ +#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ + +#include "ble/DiscoveredCharacteristic.h" + +class BlueNRGGattClient; /* forward declaration */ + +class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic { +public: + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + + void setLastHandle(GattAttribute::Handle_t lastHandleIn); +}; + +#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGGap.h + * @author STMicroelectronics + * @brief Header file for BlueNRG BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GAP_H__ +#define __BLUENRG_GAP_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/Gap.h" + +#define BLE_CONN_HANDLE_INVALID 0x0 +#define BDADDR_SIZE 6 + +#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020) +#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000) +#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0) + +// Scanning and Connection Params used by Central for creating connection +#define GAP_OBSERVATION_PROC (0x80) + +#define SCAN_P (0x0010) +#define SCAN_L (0x0010) +#define SUPERV_TIMEOUT (0xC80) +#define CONN_P(x) ((int)((x)/1.25f)) +#define CONN_L(x) ((int)((x)/0.625f)) +#define CONN_P1 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_P2 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_L1 (0x0008) +#define CONN_L2 (0x0008) +#define GUARD_INT 5 //msec +#define MIN_INT_CONN 0x0006 //=>7.5msec +#define MAX_INT_CONN 0x0C80 //=>4000msec +#define DEF_INT_CONN 0x0140 //=>400msec (default value for connection interval) + +/**************************************************************************/ +/*! + \brief + +*/ +/**************************************************************************/ +class BlueNRGGap : public Gap +{ +public: + static BlueNRGGap &getInstance() { + static BlueNRGGap m_instance; + return m_instance; + } + + enum Reason_t { + DEVICE_FOUND, + DISCOVERY_COMPLETE + }; + + /* Functions that must be implemented from Gap */ + virtual ble_error_t setAddress(addr_type_t type, const BLEProtocol::AddressBytes_t address); + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address); + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &); + virtual ble_error_t startAdvertising(const GapAdvertisingParams &); + virtual ble_error_t stopAdvertising(void); + virtual ble_error_t stopScan(); + virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);} + virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);} + virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);} + virtual ble_error_t disconnect(DisconnectionReason_t reason); + virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason); + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params); + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); + + virtual ble_error_t setDeviceName(const uint8_t *deviceName); + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); + virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance); + virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP); + + virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode); + virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode); + virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const; + virtual ScanningPolicyMode_t getScanningPolicyMode(void) const; + + virtual ble_error_t setTxPower(int8_t txPower); + virtual void getPermittedTxPowerValues(const int8_t **, size_t *); + + virtual ble_error_t connect(const Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams); + + virtual ble_error_t reset(void); + + void Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI); + ble_error_t createConnection(void); + + void setConnectionHandle(uint16_t con_handle); + uint16_t getConnectionHandle(void); + + bool getIsSetAddress(); + + // ADV timeout handling + Timeout& getAdvTimeout(void) { + return advTimeout; + } + uint8_t getAdvToFlag(void) { + return AdvToFlag; + } + void setAdvToFlag(void); + + // SCAN timeout handling + Timeout& getScanTimeout(void) { + return scanTimeout; + } + uint8_t getScanToFlag(void) { + return ScanToFlag; + } + void setScanToFlag(void); + + void Process(void); + + GapScanningParams* getScanningParams(void); + + virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams); + + void setConnectionInterval(uint16_t interval); + Gap::Role_t getGapRole(void); + void setGapRole(Gap::Role_t role); + +private: + uint16_t m_connectionHandle; + Role_t gapRole; + AddressType_t addr_type; + Address_t _peerAddr; + AddressType_t _peerAddrType; + uint8_t bdaddr[BDADDR_SIZE]; + bool _scanning; + bool _connecting; + bool isSetAddress; + uint8_t deviceAppearance[2]; + + // ADV timeout handling + Timeout advTimeout; + bool AdvToFlag; + + // SCAN timeout handling + Timeout scanTimeout; + bool ScanToFlag; + + static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) { + return (duration * 625) / 1000; + } + + uint16_t scanInterval; + uint16_t scanWindow; + uint16_t advInterval; + uint16_t slaveConnIntervMin; + uint16_t slaveConnIntervMax; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + void setAdvParameters(void); + void setConnectionParameters(void); + + Gap::AdvertisingPolicyMode_t advertisingPolicyMode; + Gap::ScanningPolicyMode_t scanningPolicyMode; + + Whitelist_t whitelistAddresses; + + ble_error_t updateAdvertisingData(void); + + BlueNRGGap() : AdvToFlag(false), ScanToFlag(false) { + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + addr_type = BLEProtocol::AddressType::RANDOM_STATIC; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + isSetAddress = false; + memset(deviceAppearance, 0, sizeof(deviceAppearance)); + } + + BlueNRGGap(BlueNRGGap const &); + void operator=(BlueNRGGap const &); + + GapAdvertisingData _advData; + GapAdvertisingData _scanResponse; +}; + +#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,157 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattClient.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CLIENT_H__ +#define __BLUENRG_GATT_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattConnectionClient.h" + +using namespace std; + +#define MAX_ACTIVE_CONNECTIONS 7 + +class BlueNRGGattClient : public GattClient +{ +public: + static BlueNRGGattClient &getInstance() { + static BlueNRGGattClient m_instance; + return m_instance; + } + + ble_error_t createGattConnectionClient(Gap::Handle_t connectionHandle); + ble_error_t removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason); + + /* Functions that must be implemented from GattClient */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + virtual bool isServiceDiscoveryActive(void) const; + virtual void terminateServiceDiscovery(void); + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback); + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + virtual ble_error_t write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + virtual ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + virtual ble_error_t reset(void); + + void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code); + + void primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(Gap::Handle_t connectionHandle); + + void serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length); + + +protected: + + BlueNRGGattClient(): _connectionPool() {}; + + ServiceDiscovery::TerminationCallback_t terminationCallback; + +private: + + BlueNRGGattClient(BlueNRGGattClient const &); + void operator=(BlueNRGGattClient const &); + + BlueNRGGattConnectionClient *_connectionPool[MAX_ACTIVE_CONNECTIONS]; + uint8_t _numConnections; + + BlueNRGGattConnectionClient * getGattConnectionClient(Gap::Handle_t connectionHandle); + +}; + +#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,185 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattConnectionClient.cpp + * @author STMicroelectronics + * @brief Header file for BlueNRGGattConnectionClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CONNECTION_CLIENT_H__ +#define __BLUENRG_GATT_CONNECTION_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" + +using namespace std; + +#define BLE_TOTAL_DISCOVERED_SERVICES 10 +#define BLE_TOTAL_DISCOVERED_CHARS 10 + +class BlueNRGGattConnectionClient +{ +public: + + enum { + GATT_IDLE, + GATT_SERVICE_DISCOVERY, + GATT_CHAR_DESC_DISCOVERY, + //GATT_CHARS_DISCOVERY_COMPLETE, + //GATT_DISCOVERY_TERMINATED, + GATT_READ_CHAR, + GATT_WRITE_CHAR + }; + + /* Functions that must be implemented from GattClient */ + ble_error_t launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + bool isServiceDiscoveryActive(void) const; + void terminateServiceDiscovery(void); + void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + } + ble_error_t read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + ble_error_t write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + ble_error_t reset(void); + + void gattProcedureCompleteCB(uint8_t error_code); + + void primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(void); + + void serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(uint8_t event_data_length); + +protected: + + BlueNRGGattConnectionClient(BlueNRGGattClient *gattClient, Gap::Handle_t connectionHandle): + discoveredService(), + discoveredChar(), + readCBParams(), + writeCBParams(), + _characteristic() { + + //PRINTF("BlueNRGGattConnectionClient construtor: connHandle=%d\n\r", connectionHandle); + + _gattClient = gattClient; + _connectionHandle = connectionHandle; + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + } + + ServiceDiscovery::ServiceCallback_t serviceDiscoveryCallback; + ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback; + ServiceDiscovery::TerminationCallback_t terminationCallback; + CharacteristicDescriptorDiscovery::DiscoveryCallback_t charDescDiscoveryCallback; + CharacteristicDescriptorDiscovery::TerminationCallback_t charDescTerminationCallback; + +private: + + BlueNRGGattConnectionClient(BlueNRGGattConnectionClient const &); + void operator=(BlueNRGGattConnectionClient const &); + ~BlueNRGGattConnectionClient() {}; + + BlueNRGGattClient *_gattClient; + + Gap::Handle_t _connectionHandle; + DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES]; + BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS]; + + GattReadCallbackParams readCBParams; + GattWriteCallbackParams writeCBParams; + + // The char for which the descriptor discovery has been launched + DiscoveredCharacteristic _characteristic; + + UUID _matchingServiceUUID; + UUID _matchingCharacteristicUUIDIn; + uint8_t _currentState; + uint8_t _numServices, _servIndex; + uint8_t _numChars; + uint8_t _numCharDesc; + + friend class BlueNRGGattClient; +}; + +#endif /* __BLUENRG_GATT_CONNECTION_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_SERVER_H__ +#define __BLUENRG_GATT_SERVER_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattService.h" +#include "ble/GattServer.h" +#include <vector> +#include <map> + +#define BLE_TOTAL_CHARACTERISTICS 10 + +using namespace std; + +class BlueNRGGattServer : public GattServer +{ +public: + static BlueNRGGattServer &getInstance() { + static BlueNRGGattServer m_instance; + return m_instance; + } + + enum HandleEnum_t { + CHAR_HANDLE = 0, + CHAR_VALUE_HANDLE, + CHAR_DESC_HANDLE + }; + + /* Functions that must be implemented from GattServer */ + virtual ble_error_t addService(GattService &); + virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t initializeGATTDatabase(void); + + virtual bool isOnDataReadAvailable() const { + return true; + } + + virtual ble_error_t reset(void); + + /* BlueNRG Functions */ + void eventCallback(void); + //void hwCallback(void *pckt); + ble_error_t Read_Request_CB(uint16_t attributeHandle); + uint8_t Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, + uint8_t data_length, const uint8_t* data + ); + GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle); + void HCIDataWrittenEvent(const GattWriteCallbackParams *params); + void HCIDataReadEvent(const GattReadCallbackParams *params); + void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle); + void HCIDataSentEvent(unsigned count); + +private: + + // compute the number of attribute record needed by a service + static uint16_t computeAttributesRecord(GattService& service); + + + static const int MAX_SERVICE_COUNT = 10; + uint8_t serviceCount; + uint8_t characteristicCount; + uint16_t servHandle, charHandle; + + std::map<uint16_t, uint16_t> bleCharHandleMap; // 1st argument is characteristic, 2nd argument is service + GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS]; + uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS]; + + BlueNRGGattServer() { + serviceCount = 0; + characteristicCount = 0; + }; + + BlueNRGGattServer(BlueNRGGattServer const &); + void operator=(BlueNRGGattServer const &); + + static const int CHAR_DESC_TYPE_16_BIT=0x01; + static const int CHAR_DESC_TYPE_128_BIT=0x02; + static const int CHAR_DESC_SECURITY_PERMISSION=0x00; + static const int CHAR_DESC_ACCESS_PERMISSION=0x03; + static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_CLOCK_H__ +#define __BLE_CLOCK_H__ + +#include <ble_hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __BLE_CLOCK_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file ble_debug.h + * @author CL + * @version V1.0.0 + * @date 04-July-2014 + * @brief This file defines print functions for debug purposes. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLE_DEBUG_H +#define __BLE_DEBUG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> + +/* Exported macro ------------------------------------------------------------*/ +//#define DEBUG +#ifdef DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Print the data travelling over the SPI in the .csv format for the GUI*/ +//#define PRINT_CSV_FORMAT +#ifdef PRINT_CSV_FORMAT +#include <stdio.h> +#define PRINT_CSV(...) printf(__VA_ARGS__) +#else +#define PRINT_CSV(...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __BLE_DEBUG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_gp_timer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : General purpose timer library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_GP_TIMER_H__ +#define __BLE_GP_TIMER_H__ + +#include "ble_clock.h" +#include "ble_status.h" +#ifdef __DMA_LP__ +#include "stm32xx_timerserver.h" +#endif /* __DMA_LP__ */ + +/** + * timer + * + * A structure that represents a timer. Use Timer_Set() to set the timer. + * + */ +struct timer { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + tClockTime start; + tClockTime interval; + +#endif +}; + +typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); + +/** + * Timer_Set + * + * @param[in] t Pointer to a timer structure + * @param[in] interval timeout value + * + * This function sets the timeout value of a timer. + * + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * Timer_Reset + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the time it previously expired. + * + */ +void Timer_Reset(struct timer *t); + +/** + * Timer_Restart + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the current time. + * + */ +void Timer_Restart(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns TRUE if timer is expired, FALSE otherwise. + * + */ +int Timer_Expired(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns the time needed for expiration. + * + * @return Time before timer's expiration. + */ +tClockTime Timer_Remaining(struct timer *t); + +#ifdef __DMA_LP__ +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID); + +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); +#endif /* __DMA_LP__ */ + +#endif /* __BLE_GP_TIMER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,108 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_H__ +#define __BLE_HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void signalEventsToProcess(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __BLE_HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_TYPES_H__ +#define __BLE_HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __BLE_HAL_TYPES_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,126 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.0, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_H_ +#define __BLE_HCI_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ble_hal_types.h" +#include "ble_link_layer.h" +#include <ble_list.h> + +#define HCI_READ_PACKET_SIZE 128 //71 + +/** + * Maximum payload of HCI commands that can be sent. Change this value if needed. + * This value can be up to 255. + */ +#define HCI_MAX_PAYLOAD_SIZE 128 + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_READ_PACKET_SIZE]; + uint8_t data_len; +} tHciDataPacket; + +struct hci_request { + uint16_t ogf; + uint16_t ocf; + int event; + void *cparam; + int clen; + void *rparam; + int rlen; +}; + +typedef enum +{ + BUSY, + AVAILABLE +} HCI_CMD_STATUS_t; + + +/** + * This function must be used to pass the packet received from the HCI + * interface to the BLE Stack HCI state machine. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * + */ +void HCI_Input(tHciDataPacket *hciReadPacket); + +/** + * Initialization function. Must be done before any data can be received from + * BLE controller. + */ +void HCI_Init(void); + +/** + * Callback used to pass events to application. + * + * @param[in] pckt The event. + * + */ +extern void HCI_Event_CB(void *pckt); + +/** + * Processing function that must be called after an event is received from + * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if + * necessary. +*/ +void HCI_Process(void); + +/** + * @brief Check if queue of HCI event is empty or not. + * @note This funtion can be used to check if the event queue from BlueNRG is empty. This + * is useful when checking if it is safe to go to sleep. + * @return TRUE if event queue is empty. FALSE otherwhise. + */ +BOOL HCI_Queue_Empty(void); +/** + * Iterrupt service routine that must be called when the BlueNRG + * reports a packet received or an event to the host through the + * BlueNRG interrupt line. + */ +#ifdef __DMA_LP__ +void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); +void HCI_Process_Notification_Request(void); +void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); +void HCI_Wait_For_Response(void); +#else +void HCI_Isr(void); +void HCI_HandleSPI(void); + +int hci_send_req(struct hci_request *r, BOOL async); +#endif /* __DMA_LP__ */ + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#ifdef __cplusplus +} +#endif + + +#endif /* __BLE_HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,548 @@ +/****************************************************************************** +* +* File Description +* --------------------- +* This file defines constants and functions for HCI layer. +* See Bluetooth Core v 4.0, Vol. 2, Part E. +* +*******************************************************************************/ + +#ifndef __HCI_INTERNAL_H_ +#define __HCI_INTERNAL_H_ + +#include "ble_compiler.h" +#include "ble_hal_types.h" +#include "ble_clock.h" +#include "ble_link_layer.h" +#include "ble_hci.h" + +#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) + + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +typedef __packed struct _hci_uart_pckt{ + uint8_t type; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef __packed struct _hci_command_hdr{ + uint16_t opcode; /* OCF & OGF */ + uint8_t plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef __packed struct _hci_event_pckt{ + uint8_t evt; + uint8_t plen; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef __packed struct _hci_acl_hdr{ + uint16_t handle; /* Handle & Flags(PB, BC) */ + uint16_t dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef __packed struct _disconnect_cp{ + uint16_t handle; + uint8_t reason; +} PACKED disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 + +#define OCF_SET_EVENT_MASK 0x0001 +#define OCF_RESET 0x0003 + +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D +typedef __packed struct _read_transmit_power_level_cp{ + uint16_t handle; + uint8_t type; +} PACKED read_transmit_power_level_cp; +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 +typedef __packed struct _read_transmit_power_level_rp{ + uint8_t status; + uint16_t handle; + int8_t level; +} PACKED read_transmit_power_level_rp; +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 + +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 +#define OCF_HOST_BUFFER_SIZE 0x0033 +#define OCF_HOST_NUM_COMP_PKTS 0x0035 + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef __packed struct _read_local_version_rp{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t manufacturer_name; + uint16_t lmp_pal_subversion; +} PACKED read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_COMMANDS 0x0002 +#define OCF_READ_LOCAL_FEATURES 0x0003 + +#define OCF_READ_BD_ADDR 0x0009 +typedef __packed struct _read_bd_addr_rp{ + uint8_t status; + tBDAddr bdaddr; +} PACKED read_bd_addr_rp; +#define READ_BD_ADDR_RP_SIZE 7 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +#define OCF_READ_RSSI 0x0005 +typedef __packed struct _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef __packed struct _read_rssi_rp{ + uint8_t status; + uint16_t handle; + int8_t rssi; +} PACKED read_rssi_rp; +#define READ_RSSI_RP_SIZE 4 + + +/* LE commands */ +#define OGF_LE_CTL 0x08 + +#define OCF_LE_SET_EVENT_MASK 0x0001 +typedef __packed struct _le_set_event_mask_cp{ + uint8_t mask[8]; +} PACKED le_set_event_mask_cp; +#define LE_SET_EVENT_MASK_CP_SIZE 8 + +#define OCF_LE_READ_BUFFER_SIZE 0x0002 +typedef __packed struct _le_read_buffer_size_rp{ + uint8_t status; + uint16_t pkt_len; + uint8_t max_pkt; +} PACKED le_read_buffer_size_rp; +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 + +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 +typedef __packed struct _le_read_local_supported_features_rp{ + uint8_t status; + uint8_t features[8]; +} PACKED le_read_local_supported_features_rp; +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 + +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 +typedef __packed struct _le_set_random_address_cp{ + tBDAddr bdaddr; +} PACKED le_set_random_address_cp; +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 + +#define OCF_LE_SET_ADV_PARAMETERS 0x0006 +typedef __packed struct _le_set_adv_parameters_cp{ + uint16_t min_interval; + uint16_t max_interval; + uint8_t advtype; + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint8_t chan_map; + uint8_t filter; +} PACKED le_set_adv_parameters_cp; +#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 + +#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 +typedef __packed struct _le_read_adv_channel_tx_power_rp{ + uint8_t status; + int8_t level; +} PACKED le_read_adv_channel_tx_power_rp; +#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 + +#define OCF_LE_SET_ADV_DATA 0x0008 +typedef __packed struct _le_set_adv_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_adv_data_cp; +#define LE_SET_ADV_DATA_CP_SIZE 32 + +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 +typedef __packed struct _le_set_scan_response_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_scan_response_data_cp; +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 + +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A +typedef __packed struct _le_set_advertise_enable_cp{ + uint8_t enable; +} PACKED le_set_advertise_enable_cp; +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 + +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B +typedef __packed struct _le_set_scan_parameters_cp{ + uint8_t type; + uint16_t interval; + uint16_t window; + uint8_t own_bdaddr_type; + uint8_t filter; +} PACKED le_set_scan_parameters_cp; +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 + +#define OCF_LE_SET_SCAN_ENABLE 0x000C +typedef __packed struct _le_set_scan_enable_cp{ + uint8_t enable; + uint8_t filter_dup; +} PACKED le_set_scan_enable_cp; +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 + +#define OCF_LE_CREATE_CONN 0x000D +typedef __packed struct _le_create_connection_cp{ + uint16_t interval; + uint16_t window; + uint8_t initiator_filter; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_create_connection_cp; +#define LE_CREATE_CONN_CP_SIZE 25 + +#define OCF_LE_CREATE_CONN_CANCEL 0x000E + +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F +typedef __packed struct _le_read_white_list_size_rp{ + uint8_t status; + uint8_t size; +} PACKED le_read_white_list_size_rp; +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 + +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 +typedef __packed struct _le_add_device_to_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_add_device_to_white_list_cp; +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 +typedef __packed struct _le_remove_device_from_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_remove_device_from_white_list_cp; +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_CONN_UPDATE 0x0013 +typedef __packed struct _le_connection_update_cp{ + uint16_t handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_connection_update_cp; +#define LE_CONN_UPDATE_CP_SIZE 14 + +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 +typedef __packed struct _le_set_host_channel_classification_cp{ + uint8_t map[5]; +} PACKED le_set_host_channel_classification_cp; +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 + +#define OCF_LE_READ_CHANNEL_MAP 0x0015 +typedef __packed struct _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef __packed struct _le_read_channel_map_rp{ + uint8_t status; + uint16_t handle; + uint8_t map[5]; +} PACKED le_read_channel_map_rp; +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 + +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 +typedef __packed struct _le_read_remote_used_features_cp{ + uint16_t handle; +} PACKED le_read_remote_used_features_cp; +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 + +#define OCF_LE_ENCRYPT 0x0017 +typedef __packed struct _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef __packed struct _le_encrypt_rp{ + uint8_t status; + uint8_t encdata[16]; +} PACKED le_encrypt_rp; +#define LE_ENCRYPT_RP_SIZE 17 + +#define OCF_LE_RAND 0x0018 +typedef __packed struct _le_rand_rp{ + uint8_t status; + uint8_t random[8]; +} PACKED le_rand_rp; +#define LE_RAND_RP_SIZE 9 + +#define OCF_LE_START_ENCRYPTION 0x0019 +typedef __packed struct _le_start_encryption_cp{ + uint16_t handle; + uint8_t random[8]; + uint16_t diversifier; + uint8_t key[16]; +} PACKED le_start_encryption_cp; +#define LE_START_ENCRYPTION_CP_SIZE 28 + +#define OCF_LE_LTK_REPLY 0x001A +typedef __packed struct _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef __packed struct _le_ltk_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_reply_rp; +#define LE_LTK_REPLY_RP_SIZE 3 + +#define OCF_LE_LTK_NEG_REPLY 0x001B +typedef __packed struct _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef __packed struct _le_ltk_neg_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_neg_reply_rp; +#define LE_LTK_NEG_REPLY_RP_SIZE 3 + +#define OCF_LE_READ_SUPPORTED_STATES 0x001C +typedef __packed struct _le_read_supported_states_rp{ + uint8_t status; + uint8_t states[8]; +} PACKED le_read_supported_states_rp; +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 + +#define OCF_LE_RECEIVER_TEST 0x001D +typedef __packed struct _le_receiver_test_cp{ + uint8_t frequency; +} PACKED le_receiver_test_cp; +#define LE_RECEIVER_TEST_CP_SIZE 1 + +#define OCF_LE_TRANSMITTER_TEST 0x001E +typedef __packed struct _le_transmitter_test_cp{ + uint8_t frequency; + uint8_t length; + uint8_t payload; +} PACKED le_transmitter_test_cp; +#define LE_TRANSMITTER_TEST_CP_SIZE 3 + +#define OCF_LE_TEST_END 0x001F +typedef __packed struct _le_test_end_rp{ + uint8_t status; + uint16_t num_pkts; +} PACKED le_test_end_rp; +#define LE_TEST_END_RP_SIZE 3 + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3f + + +/*------------- Events -------------*/ +#define EVT_CONN_COMPLETE 0x03 +typedef __packed struct _evt_conn_complete{ + uint8_t status; + uint16_t handle; + tBDAddr bdaddr; + uint8_t link_type; + uint8_t encr_mode; +} PACKED evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef __packed struct _evt_disconn_complete{ + uint8_t status; + uint16_t handle; + uint8_t reason; +} PACKED evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef __packed struct _evt_encrypt_change{ + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} PACKED evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C + +#define EVT_CMD_COMPLETE 0x0E +typedef __packed struct _evt_cmd_complete{ + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef __packed struct _evt_cmd_status{ + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef __packed struct _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef __packed struct _evt_num_comp_pkts{ + uint8_t num_hndl; + /* variable length part */ +} PACKED evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +/* variable length part of evt_num_comp_pkts. */ +typedef __packed struct _evt_num_comp_pkts_param{ + uint16_t hndl; + uint16_t num_comp_pkts; +} PACKED evt_num_comp_pkts_param; +#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 + +#define EVT_DATA_BUFFER_OVERFLOW 0x1A +typedef __packed struct _evt_data_buffer_overflow{ + uint8_t link_type; +} PACKED evt_data_buffer_overflow; +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 + +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef __packed struct _evt_encryption_key_refresh_complete{ + uint8_t status; + uint16_t handle; +} PACKED evt_encryption_key_refresh_complete; +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 + +#define EVT_LE_META_EVENT 0x3E +typedef __packed struct _evt_le_meta_event{ + uint8_t subevent; + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef __packed struct _evt_le_connection_complete{ + uint8_t status; + uint16_t handle; + uint8_t role; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; +} PACKED evt_le_connection_complete; +#define EVT_LE_CONN_COMPLETE_SIZE 18 + +#define EVT_LE_ADVERTISING_REPORT 0x02 +typedef __packed struct _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t data_length; + uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef __packed struct _evt_le_connection_update_complete{ + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; +} PACKED evt_le_connection_update_complete; +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 + +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +typedef __packed struct _evt_le_read_remote_used_features_complete{ + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} PACKED evt_le_read_remote_used_features_complete; +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 + +#define EVT_LE_LTK_REQUEST 0x05 +typedef __packed struct _evt_le_long_term_key_request{ + uint16_t handle; + uint8_t random[8]; + uint16_t ediv; +} PACKED evt_le_long_term_key_request; +#define EVT_LE_LTK_REQUEST_SIZE 12 + +/** +* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, +* application can use @ref evt_blue_aci structure to parse the packet. +*/ +#define EVT_VENDOR 0xFF + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + + + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); + +typedef enum { + WAITING_TYPE, + WAITING_OPCODE1, + WAITING_OPCODE2, + WAITING_EVENT_CODE, + WAITING_HANDLE, + WAITING_HANDLE_FLAG, + WAITING_PARAM_LEN, + WAITING_DATA_LEN1, + WAITING_DATA_LEN2, + WAITING_PAYLOAD +}hci_state; + +typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); + +/* HCI library functions. */ + +int hci_send_req(struct hci_request *r, BOOL async); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,170 @@ +/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +* File Name : ble_hci_le.h +* Author : AMG RF FW team +* Version : V1.1.0 +* Date : 18-July-2016 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.1, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_LE_H_ +#define __BLE_HCI_LE_H_ + +#include "ble_hal_types.h" +#include "ble_link_layer.h" + +/** + * @defgroup HCI_Error_codes HCI Error codes + * @{ + */ +#define HCI_UNKNOWN_COMMAND 0x01 +#define HCI_NO_CONNECTION 0x02 +#define HCI_HARDWARE_FAILURE 0x03 +#define HCI_PAGE_TIMEOUT 0x04 +#define HCI_AUTHENTICATION_FAILURE 0x05 +#define HCI_PIN_OR_KEY_MISSING 0x06 +#define HCI_MEMORY_FULL 0x07 +#define HCI_CONNECTION_TIMEOUT 0x08 +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a +#define HCI_ACL_CONNECTION_EXISTS 0x0b +#define HCI_COMMAND_DISALLOWED 0x0c +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d +#define HCI_REJECTED_SECURITY 0x0e +#define HCI_REJECTED_PERSONAL 0x0f +#define HCI_HOST_TIMEOUT 0x10 +#define HCI_UNSUPPORTED_FEATURE 0x11 +#define HCI_INVALID_PARAMETERS 0x12 +#define HCI_OE_USER_ENDED_CONNECTION 0x13 +#define HCI_OE_LOW_RESOURCES 0x14 +#define HCI_OE_POWER_OFF 0x15 +#define HCI_CONNECTION_TERMINATED 0x16 +#define HCI_REPEATED_ATTEMPTS 0x17 +#define HCI_PAIRING_NOT_ALLOWED 0x18 +#define HCI_UNKNOWN_LMP_PDU 0x19 +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a +#define HCI_SCO_OFFSET_REJECTED 0x1b +#define HCI_SCO_INTERVAL_REJECTED 0x1c +#define HCI_AIR_MODE_REJECTED 0x1d +#define HCI_INVALID_LMP_PARAMETERS 0x1e +#define HCI_UNSPECIFIED_ERROR 0x1f +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 +#define HCI_UNIT_LINK_KEY_USED 0x26 +#define HCI_QOS_NOT_SUPPORTED 0x27 +#define HCI_INSTANT_PASSED 0x28 +#define HCI_PAIRING_NOT_SUPPORTED 0x29 +#define HCI_TRANSACTION_COLLISION 0x2a +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c +#define HCI_QOS_REJECTED 0x2d +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e +#define HCI_INSUFFICIENT_SECURITY 0x2f +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 +#define HCI_ROLE_SWITCH_PENDING 0x32 +#define HCI_SLOT_VIOLATION 0x34 +#define HCI_ROLE_SWITCH_FAILED 0x35 +#define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 +#define HCI_CONN_REJ_NO_CH_FOUND 0x39 +#define HCI_CONTROLLER_BUSY 0x3A +#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B +#define HCI_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_CONN_TERM_MIC_FAIL 0x3D +#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E +#define HCI_MAC_CONN_FAILED 0x3F +/** + * @} + */ + + +/* + * HCI library functions. + * Each function returns 0 in case of success, otherwise one of the error codes. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(uint8_t enable); + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter); + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter); + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); + +int hci_le_rand(uint8_t random_number[8]); + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); + +int hci_acl_data(const uint8_t * data, uint16_t len); + +int hci_le_set_random_address(tBDAddr bdaddr); + +int hci_read_bd_addr(tBDAddr bdaddr); + +int hci_le_read_white_list_size(uint8_t *size); + +int hci_le_clear_white_list(); + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); + +int hci_le_ltk_request_reply(uint8_t key[16]); + +int hci_le_ltk_request_neg_reply(); + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); + +int hci_le_create_connection_cancel(void); + +int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level); + +int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi); + +int hci_le_read_local_supported_features(uint8_t *features); + +int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); + +int hci_le_read_supported_states(uint8_t states[8]); + +int hci_le_receiver_test(uint8_t frequency); + +int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); + +int hci_le_test_end(uint16_t *num_pkts); + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion); + + + +#endif /* __BLE_HCI_LE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,161 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_link_layer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's link layer. It contains +* definition of functions for link layer, most of which are +* mapped to HCI commands. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef _BLE_LINK_LAYER_H +#define _BLE_LINK_LAYER_H + +#include <ble_status.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + *@name Advertising filter + *Advertising policy for filtering (white list related) + *@{ + */ +#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ +#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ +/** + * @} + */ + + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef uint8_t tBDAddr[6]; + + +/** + *@name Bluetooth address types + * Bluetooth address types + *@{ + */ +#define PUBLIC_ADDR (0) +#define RANDOM_ADDR (1) +#define STATIC_RANDOM_ADDR (1) +#define RESOLVABLE_PRIVATE_ADDR (2) +#define NON_RESOLVABLE_PRIVATE_ADDR (3) +/** + * @} + */ + +/** + *@name Directed advertising types + * Type of advertising during directed advertising + *@{ + */ +#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) +#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) +/** + * @} + */ + +/** + * @name Advertising type + * @{ + */ + +/** + * undirected scannable and connectable + */ +#define ADV_IND (0x00) + +/** + * directed non scannable + */ +#define ADV_DIRECT_IND (0x01) + +/** + * scannable non connectable + */ +#define ADV_SCAN_IND (0x02) + +/** + * non-connectable and no scan response + */ +#define ADV_NONCONN_IND (0x03) + +/** + * scan response + */ +#define SCAN_RSP (0x04) + +/** + * @} + */ + +/* 0X05-0XFF RESERVED */ + +/** + * @name Advertising ranges + * @{ + */ + +/** + * lowest allowed interval value for connectable types(20ms)..multiple of 625us + */ +#define ADV_INTERVAL_LOWEST_CONN (0X0020) + +/** + * highest allowed interval value (10.24s)..multiple of 625us. + */ +#define ADV_INTERVAL_HIGHEST (0X4000) + +/** + * lowest allowed interval value for non connectable types + * (100ms)..multiple of 625us. + */ +#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) + +/** + * @} + */ + +/** + * @name Advertising channels + * @{ + */ +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 +/** + * @} + */ + +/** + * @name Scan_types Scan types + * @{ + */ +#define PASSIVE_SCAN 0 +#define ACTIVE_SCAN 1 +/** + * @} + */ + +/** + * @} + */ + + +#endif /* _BLE_LINK_LAYER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,47 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for linked list library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef _BLE_LIST_H_ +#define _BLE_LIST_H_ + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +uint8_t list_is_empty (tListNode * listHead); + +void list_insert_head (tListNode * listHead, tListNode * node); + +void list_insert_tail (tListNode * listHead, tListNode * node); + +void list_remove_node (tListNode * node); + +void list_remove_head (tListNode * listHead, tListNode ** node ); + +void list_remove_tail (tListNode * listHead, tListNode ** node ); + +void list_insert_node_after (tListNode * node, tListNode * ref_node); + +void list_insert_node_before (tListNode * node, tListNode * ref_node); + +int list_get_size (tListNode * listHead); + +void list_get_next_node (tListNode * ref_node, tListNode ** node); + +void list_get_prev_node (tListNode * ref_node, tListNode ** node); + +#endif /* _BLE_LIST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_OSAL_H__ +#define __BLE_OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __BLE_OSAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,158 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_sm.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's security manager. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_SM_H__ +#define __BLE_SM_H__ + +/****************************************************************************** +* Macros +*****************************************************************************/ + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/* IO capabilities */ +/** + * @anchor IO_capabilities + * @name IO capabilities + * @{ + */ +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define IO_CAP_KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) +/** + * @} + */ + +/** + * @anchor Auth_req + * @name Authentication requirements + * @{ + */ +#define BONDING (0x01) +#define NO_BONDING (0x00) +/** + * @} + */ + +/** + * @anchor MITM_req + * @name MITM protection requirements + * @{ + */ +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor OOB_Data + * @name Out-Of-Band data + * @{ + */ +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) +/** + * @} + */ + +/** + * @anchor Author_req + * @name Authorization requirements + * @{ + */ +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor Conn_authorization + * @name Connection authorization + * @{ + */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) +/** + * @} + */ + +/** + * @anchor Use_fixed_pin + * @name Use fixed pin + * @{ + */ +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +/** + * @} + */ + +/** + * @anchor link_security_status + * @name Link security status + * @{ + */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) +/** + * @} + */ + +/** + * @anchor SMP_pairing_failed_codes + * @name SMP pairing failed reason codes + * @{ + */ +#define PASSKEY_ENTRY_FAILED (0x01) +#define OOB_NOT_AVAILABLE (0x02) +#define AUTH_REQ_CANNOT_BE_MET (0x03) +#define CONFIRM_VALUE_FAILED (0x04) +#define PAIRING_NOT_SUPPORTED (0x05) +#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) +#define CMD_NOT_SUPPORTED (0x07) +#define UNSPECIFIED_REASON (0x08) +#define VERY_EARLY_NEXT_ATTEMPT (0x09) +#define SM_INVALID_PARAMS (0x0A) +/** + * @} + */ + +/** + * @anchor pairing_failed_codes + * @name Pairing failed error codes + * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event + * @{ + */ +#define SM_PAIRING_SUCCESS (0x00) +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,188 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_status.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file with BLE Stack status codes. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_STATUS_H__ +#define __BLE_STATUS_H__ + +#include <ble_hal_types.h> + +/** @addtogroup Middlewares + * @{ + */ + +/** @defgroup ST + * @{ + */ + +/** @defgroup SimpleBlueNRG_HCI + * @{ + */ + +/** @defgroup ble_status Bluetooth Status/Error Codes + * @{ + */ + +typedef uint8_t tBleStatus; + +/* Error Codes as specified by the specification + * according to the spec the error codes range + * from 0x00 to 0x3F + */ +/** + * @name Standard error codes + * @brief Standard error codes. See Core v 4.1, Vol. 2, part D. + * @{ + */ +#define ERR_CMD_SUCCESS (0x00) +#define BLE_STATUS_SUCCESS (0x00) +#define ERR_UNKNOWN_HCI_COMMAND (0x01) +#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) + +#define ERR_AUTH_FAILURE (0x05) +#define ERR_PIN_OR_KEY_MISSING (0x06) +#define ERR_MEM_CAPACITY_EXCEEDED (0x07) +#define ERR_CONNECTION_TIMEOUT (0x08) + +#define ERR_COMMAND_DISALLOWED (0x0C) + +#define ERR_UNSUPPORTED_FEATURE (0x11) +#define ERR_INVALID_HCI_CMD_PARAMS (0x12) +#define ERR_RMT_USR_TERM_CONN (0x13) +#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) +#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) +#define ERR_LOCAL_HOST_TERM_CONN (0x16) + +#define ERR_UNSUPP_RMT_FEATURE (0x1A) + +#define ERR_INVALID_LMP_PARAM (0x1E) +#define ERR_UNSPECIFIED_ERROR (0x1F) + +#define ERR_LL_RESP_TIMEOUT (0x22) +#define ERR_LMP_PDU_NOT_ALLOWED (0x24) + +#define ERR_INSTANT_PASSED (0x28) + +#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) +#define ERR_CONTROLLER_BUSY (0x3A) + +#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) + +#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) + +#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) + + +/** + * @} + */ +/** + * @name Vendor-specific error codes + * @brief Error codes defined by ST related to BlueNRG stack + * @{ + */ +/** + * The command cannot be executed due to the current state of the device. + */ +#define BLE_STATUS_FAILED (0x41) +/** + * Some parameters are invalid. + */ +#define BLE_STATUS_INVALID_PARAMS (0x42) +/** + * It is not allowed to start the procedure (e.g. another the procedure is ongoing + * or cannot be started on the given handle). + */ +#define BLE_STATUS_NOT_ALLOWED (0x46) +/** + * Unexpected error. + */ +#define BLE_STATUS_ERROR (0x47) +#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) + +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +#define BLE_STATUS_INVALID_CID (0x50) + +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) +#define BLE_STATUS_IRK_NOT_FOUND (0x5B) +#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) +#define BLE_STATUS_SEC_DB_FULL (0x5D) +#define BLE_STATUS_DEV_NOT_BONDED (0x5E) +#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) + +#define BLE_STATUS_INVALID_HANDLE (0x60) +#define BLE_STATUS_INVALID_PARAMETER (0x61) +#define BLE_STATUS_OUT_OF_HANDLE (0x62) +#define BLE_STATUS_INVALID_OPERATION (0x63) +#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) +#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) +#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) + +/** + * Returned when no valid slots are available (e.g. when there are no available state machines). + */ +#define BLE_STATUS_NO_VALID_SLOT (0x82) + +/** + * Returned when a scan window shorter than minimum allowed value has been requested (i.e. 2ms) + */ + +#define BLE_STATUS_SCAN_WINDOW_SHORT (0x83) +/** + * Returned when the maximum requested interval to be allocated is shorter then the current + * anchor period and a there is no submultiple for the current anchor period that is between + * the minimum and the maximum requested intervals. + */ + +#define BLE_STATUS_NEW_INTERVAL_FAILED (0x84) +/** + * Returned when the maximum requested interval to be allocated is greater than the current anchor + * period and there is no multiple of the anchor period that is between the minimum and the maximum + * requested intervals. + */ + +#define BLE_STATUS_INTERVAL_TOO_LARGE (0x85) +/** + * Returned when the current anchor period or a new one can be found that is compatible to the + * interval range requested by the new slot but the maximum available length that can be allocated is + * less than the minimum requested slot length. + */ + +#define BLE_STATUS_LENGTH_FAILED (0x86) +/** + * @} + */ + +/** + * @name Library Error Codes + * @brief Error codes defined by ST related to MCU library. + * @{ + */ +#define BLE_STATUS_TIMEOUT (0xFF) +#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) +#define BLE_STATUS_NULL_PARAM (0xF1) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,813 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci_const.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with ACI definitions for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_CONST_H_ +#define __BLUENRG_ACI_CONST_H_ + +#include "ble_compiler.h" +#include "ble_link_layer.h" +#include "ble_hci_const.h" +#include "bluenrg_gatt_server.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define OCF_HAL_GET_FW_BUILD_NUMBER 0x0000 +typedef __packed struct _hal_get_fw_build_number_rp{ + uint8_t status; + uint16_t build_number; +} PACKED hal_get_fw_build_number_rp; +#define HAL_GET_FW_BUILD_NUMBER_RP_SIZE 3 +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +#define OCF_HAL_READ_CONFIG_DATA 0x000D +typedef __packed struct _hal_read_config_data_cp{ + uint8_t offset; +} PACKED hal_read_config_data_cp; +#define HAL_READ_CONFIG_DATA_RP_SIZE 1 +typedef __packed struct _hal_read_config_data_rp{ + uint8_t status; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE]; +} PACKED hal_read_config_data_rp; + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef __packed struct _hal_set_tx_power_level_cp{ + uint8_t en_high_power; + uint8_t pa_level; +} PACKED hal_set_tx_power_level_cp; +#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 + +#define OCF_HAL_DEVICE_STANDBY 0x0013 + +#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014 +typedef __packed struct _hal_le_tx_test_packet_number_rp{ + uint8_t status; + uint32_t number_of_packets; +} PACKED hal_le_tx_test_packet_number_rp; + +#define OCF_HAL_TONE_START 0x0015 +typedef __packed struct _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_HAL_TONE_STOP 0x0016 +#define OCF_HAL_GET_LINK_STATUS 0x0017 +typedef __packed struct _hal_get_link_status_rp{ + uint8_t status; + uint8_t link_status[8]; + uint16_t conn_handle[8]; +} PACKED hal_get_link_status_rp; + +#define OCF_HAL_GET_ANCHOR_PERIOD 0x0019 +typedef __packed struct _hal_get_anchor_period_rp{ + uint8_t status; + uint32_t anchor_period; + uint32_t max_free_slot; +} PACKED hal_get_anchor_period_rp; + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef __packed struct _get_updater_version_rp{ + uint8_t status; + uint8_t version; +} PACKED get_updater_version_rp; +#define GET_UPDATER_VERSION_RP_SIZE 2 + +#define OCF_GET_UPDATER_BUFSIZE 0x0023 +typedef __packed struct _get_updater_bufsize_rp{ + uint8_t status; + uint8_t buffer_size; +} PACKED get_updater_bufsize_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 + +#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 + +#define OCF_UPDATER_ERASE_SECTOR 0x0026 +typedef __packed struct _updater_erase_sector_cp{ + uint32_t address; +} PACKED updater_erase_sector_cp; +#define UPDATER_ERASE_SECTOR_CP_SIZE 4 + +#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 +#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_prog_data_block_cp{ + uint32_t address; + uint16_t data_len; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; +} PACKED updater_prog_data_block_cp; + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef __packed struct _updater_read_data_block_cp{ + uint32_t address; + uint16_t data_len; +} PACKED updater_read_data_block_cp; +#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[VARIABLE_SIZE]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef __packed struct _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef __packed struct _updater_calc_crc_rp{ + uint8_t status; + uint32_t crc; +} PACKED updater_calc_crc_rp; +#define UPDATER_CALC_CRC_RP_SIZE 5 + +#define OCF_UPDATER_HW_VERSION 0x002A +typedef __packed struct _updater_hw_version_rp{ + uint8_t status; + uint8_t version; +} PACKED updater_hw_version_rp; +#define UPDATER_HW_VERSION_RP_SIZE 2 + +#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 + +#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 + +#define OCF_GAP_SET_DISCOVERABLE 0x0083 + +#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 +typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ + uint8_t own_bdaddr_type; + uint8_t directed_adv_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint16_t adv_interv_min; + uint16_t adv_interv_max; +} PACKED gap_set_direct_conectable_cp_IDB05A1; + +typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB04A1; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef __packed struct _gap_set_io_capability_cp{ + uint8_t io_capability; +} PACKED gap_set_io_capability_cp; +#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 + +#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 +typedef __packed struct _gap_set_auth_requirement_cp{ + uint8_t mitm_mode; + uint8_t oob_enable; + uint8_t oob_data[16]; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t bonding_mode; +} PACKED gap_set_auth_requirement_cp; +#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 + +#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 +typedef __packed struct _gap_set_author_requirement_cp{ + uint16_t conn_handle; + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef __packed struct _gap_passkey_response_cp{ + uint16_t conn_handle; + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef __packed struct _gap_authorization_response_cp{ + uint16_t conn_handle; + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 + +#define OCF_GAP_INIT 0x008A +typedef __packed struct _gap_init_cp_IDB05A1{ + uint8_t role; + uint8_t privacy_enabled; + uint8_t device_name_char_len; +} PACKED gap_init_cp_IDB05A1; +#define GAP_INIT_CP_SIZE_IDB05A1 3 + +typedef __packed struct _gap_init_cp_IDB04A1{ + uint8_t role; +} PACKED gap_init_cp_IDB04A1; +#define GAP_INIT_CP_SIZE_IDB04A1 1 +typedef __packed struct _gap_init_rp{ + uint8_t status; + uint16_t service_handle; + uint16_t dev_name_char_handle; + uint16_t appearance_char_handle; +} PACKED gap_init_rp; +#define GAP_INIT_RP_SIZE 7 + +#define OCF_GAP_SET_NON_CONNECTABLE 0x008B +typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ + uint8_t advertising_event_type; + uint8_t own_address_type; +#endif +} PACKED gap_set_non_connectable_cp_IDB05A1; + +typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp_IDB04A1; + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef __packed struct _gap_set_undirected_connectable_cp{ + uint8_t adv_filter_policy; + uint8_t own_addr_type; +} PACKED gap_set_undirected_connectable_cp; +#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 + +#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D +typedef __packed struct _gap_slave_security_request_cp{ + uint16_t conn_handle; + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef __packed struct _gap_delete_ad_type_cp{ + uint8_t ad_type; +} PACKED gap_delete_ad_type_cp; +#define GAP_DELETE_AD_TYPE_CP_SIZE 1 + +#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 +typedef __packed struct _gap_get_security_level_rp{ + uint8_t status; + uint8_t mitm_protection; + uint8_t bonding; + uint8_t oob_data; + uint8_t passkey_required; +} PACKED gap_get_security_level_rp; +#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 + +#define OCF_GAP_SET_EVT_MASK 0x0091 +typedef __packed struct _gap_set_evt_mask_cp{ + uint16_t evt_mask; +} PACKED gap_set_evt_mask_cp; +#define GAP_SET_EVT_MASK_CP_SIZE 2 + +#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 + +#define OCF_GAP_TERMINATE 0x0093 +typedef __packed struct _gap_terminate_cp{ + uint16_t handle; + uint8_t reason; +} PACKED gap_terminate_cp; +#define GAP_TERMINATE_CP_SIZE 3 + +#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 + +#define OCF_GAP_ALLOW_REBOND_DB 0x0095 + +typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ + uint16_t conn_handle; +} PACKED gap_allow_rebond_cp_IDB05A1; + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef __packed struct _gap_start_limited_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_limited_discovery_proc_cp; +#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 +typedef __packed struct _gap_start_general_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_general_discovery_proc_cp; +#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 +typedef __packed struct _gap_start_name_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_name_discovery_proc_cp; +#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 + +#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 + +#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; + +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t use_reconn_addr; + tBDAddr reconn_addr; +} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; + +#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B +#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 +typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t num_whitelist_entries; + uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; +} PACKED gap_start_selective_conn_establish_proc_cp; + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef __packed struct _gap_create_connection_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_create_connection_cp; +#define GAP_CREATE_CONNECTION_CP_SIZE 24 + +#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D + +#define OCF_GAP_START_CONNECTION_UPDATE 0x009E +typedef __packed struct _gap_start_connection_update_cp{ + uint16_t conn_handle; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_connection_update_cp; +#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 + +#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F +typedef __packed struct _gap_send_pairing_request_cp{ + uint16_t conn_handle; + uint8_t force_rebond; +} PACKED gap_send_pairing_request_cp; +#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 + +#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 +typedef __packed struct _gap_resolve_private_address_cp{ + tBDAddr address; +} PACKED gap_resolve_private_address_cp; +#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 +typedef __packed struct _gap_resolve_private_address_rp{ + uint8_t status; + tBDAddr address; +} PACKED gap_resolve_private_address_rp; + +#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 +#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 +typedef __packed struct _gap_set_broadcast_mode_cp{ + uint16_t adv_interv_min; + uint16_t adv_interv_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; +} PACKED gap_set_broadcast_mode_cp; + +#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 +typedef __packed struct _gap_start_observation_proc_cp{ + uint16_t scan_interval; + uint16_t scan_window; + uint8_t scan_type; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_observation_proc_cp; + +#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 +typedef __packed struct _gap_get_bonded_devices_rp{ + uint8_t status; + uint8_t num_addr; + uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; +} PACKED gap_get_bonded_devices_rp; + +#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 +typedef __packed struct _gap_is_device_bonded_cp{ + uint8_t peer_address_type; + tBDAddr peer_address; +} PACKED gap_is_device_bonded_cp; + + +#define OCF_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef __packed struct _gatt_add_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_serv_rp; +#define GATT_ADD_SERV_RP_SIZE 3 + +#define OCF_GATT_INCLUDE_SERV 0x0103 +typedef __packed struct _gatt_include_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_include_serv_rp; +#define GATT_INCLUDE_SERV_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR 0x0104 +typedef __packed struct _gatt_add_char_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_rp; +#define GATT_ADD_CHAR_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR_DESC 0x0105 +typedef __packed struct _gatt_add_char_desc_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_desc_rp; +#define GATT_ADD_CHAR_DESC_RP_SIZE 3 + +#define OCF_GATT_UPD_CHAR_VAL 0x0106 + +#define OCF_GATT_DEL_CHAR 0x0107 +typedef __packed struct _gatt_del_char_cp{ + uint16_t service_handle; + uint16_t char_handle; +} PACKED gatt_del_char_cp; +#define GATT_DEL_CHAR_CP_SIZE 4 + +#define OCF_GATT_DEL_SERV 0x0108 +typedef __packed struct _gatt_del_serv_cp{ + uint16_t service_handle; +} PACKED gatt_del_serv_cp; +#define GATT_DEL_SERV_CP_SIZE 2 + +#define OCF_GATT_DEL_INC_SERV 0x0109 +typedef __packed struct _gatt_del_inc_serv_cp{ + uint16_t service_handle; + uint16_t inc_serv_handle; +} PACKED gatt_del_inc_serv_cp; +#define GATT_DEL_INC_SERV_CP_SIZE 4 + +#define OCF_GATT_SET_EVT_MASK 0x010A +typedef __packed struct _gatt_set_evt_mask_cp{ + uint32_t evt_mask; +} PACKED gatt_set_evt_mask_cp; +#define GATT_SET_EVT_MASK_CP_SIZE 4 + +#define OCF_GATT_EXCHANGE_CONFIG 0x010B +typedef __packed struct _gatt_exchange_config_cp{ + uint16_t conn_handle; +} PACKED gatt_exchange_config_cp; +#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 + +#define OCF_ATT_FIND_INFO_REQ 0x010C +typedef __packed struct _att_find_info_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED att_find_info_req_cp; +#define ATT_FIND_INFO_REQ_CP_SIZE 6 + +#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D +#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 +typedef __packed struct _att_find_by_type_value_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[2]; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU - 7]; +} PACKED att_find_by_type_value_req_cp; + +#define OCF_ATT_READ_BY_TYPE_REQ 0x010E +#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_type_req_cp; + +#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F +#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_group_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_group_type_req_cp; + +#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 +#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val +typedef __packed struct _att_prepare_write_req_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t value_offset; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU-5]; +} PACKED att_prepare_write_req_cp; + +#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 +typedef __packed struct _att_execute_write_req_cp{ + uint16_t conn_handle; + uint8_t execute; +} PACKED att_execute_write_req_cp; +#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 + +#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 +typedef __packed struct _gatt_disc_all_prim_serivces_cp{ + uint16_t conn_handle; +} PACKED gatt_disc_all_prim_services_cp; +#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 + +#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 +typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ + uint16_t conn_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_disc_prim_service_by_uuid_cp; +#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid + +#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 +typedef __packed struct _gatt_disc_find_included_services_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED gatt_find_included_services_cp; +#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 + +#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 +typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ + uint16_t conn_handle; + uint16_t start_attr_handle; + uint16_t end_attr_handle; +} PACKED gatt_disc_all_charac_of_serv_cp; +#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 + +#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 + +#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ + uint16_t conn_handle; + uint16_t char_val_handle; + uint16_t char_end_handle; +} PACKED gatt_disc_all_charac_descriptors_cp; +#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 + +#define OCF_GATT_READ_CHARAC_VAL 0x0118 +typedef __packed struct _gatt_read_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_val_cp; +#define GATT_READ_CHARAC_VAL_CP_SIZE 4 + +#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 +typedef __packed struct _gatt_read_using_charac_uuid_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_read_using_charac_uuid_cp; +#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID + +#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A +typedef __packed struct _gatt_read_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_val_cp; +#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 + +#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B +#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles +typedef __packed struct _gatt_read_multiple_charac_val_cp{ + uint16_t conn_handle; + uint8_t num_handles; + uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_read_multiple_charac_val_cp; + +#define OCF_GATT_WRITE_CHAR_VALUE 0x011C + +#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D +#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_write_long_charac_val_cp; + +#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E +#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_charac_reliable_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; +} PACKED gatt_write_charac_reliable_cp; + +#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F +#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; +} PACKED gatt_write_long_charac_desc_cp; + +#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 +typedef __packed struct _gatt_read_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_desc_cp; +#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 + +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 +typedef __packed struct _gatt_read_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_desc_cp; +#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 +#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 3]; +} PACKED gatt_write_without_resp_cp; + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 +#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_signed_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 13]; +} PACKED gatt_signed_write_without_resp_cp; + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 +typedef __packed struct _gatt_confirm_indication_cp{ + uint16_t conn_handle; +} PACKED gatt_confirm_indication_cp; +#define GATT_CONFIRM_INDICATION_CP_SIZE 2 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef __packed struct _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 +typedef __packed struct _gatt_set_security_permission_cp{ + uint16_t service_handle; + uint16_t attr_handle; + uint8_t security_permission; +} PACKED gatt_set_security_permission_cp; +#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_GATT_READ_HANDLE_VALUE 0x012A +typedef __packed struct _gatt_read_handle_val_cp{ + uint16_t attr_handle; +} PACKED gatt_read_handle_val_cp; +#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 +typedef __packed struct _gatt_read_handle_val_rp{ + uint8_t status; + uint16_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; +} PACKED gatt_read_handle_val_rp; + +#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B +typedef __packed struct _gatt_read_handle_val_offset_cp{ + uint16_t attr_handle; + uint8_t offset; +} PACKED gatt_read_handle_val_offset_cp; +#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 +typedef __packed struct _gatt_read_handle_val_offset_rp{ + uint8_t status; + uint8_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; +} PACKED gatt_read_handle_val_offset_rp; + +#define OCF_GATT_UPD_CHAR_VAL_EXT 0x012C +#define GATT_UPD_CHAR_VAL_EXT_CP_SIZE 10 // without value +typedef __packed struct _gatt_upd_char_val_ext_cp{ + uint16_t service_handle; + uint16_t char_handle; + uint8_t update_type; + uint16_t char_length; + uint16_t value_offset; + uint8_t value_length; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_UPD_CHAR_VAL_EXT_CP_SIZE]; +} PACKED gatt_upd_char_val_ext_cp; + +#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 +typedef __packed struct _l2cap_conn_param_update_req_cp{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_update_req_cp; +#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 + +#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint16_t min_ce_length; + uint16_t max_ce_length; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; + +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; + +/** + * @defgroup BlueNRG_Events BlueNRG events (vendor specific) + * @{ + */ + +/** + * Vendor specific event for BlueNRG. + */ +typedef __packed struct _evt_blue_aci{ + uint16_t ecode; /**< One of the BlueNRG event codes. */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_blue_aci; + + +/** + * @} + */ + +#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gap.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GAP layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BNRG_GAP_H__ +#define __BNRG_GAP_H__ + +#include <ble_link_layer.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + * @name GAP UUIDs + * @{ + */ +#define GAP_SERVICE_UUID (0x1800) +#define DEVICE_NAME_UUID (0x2A00) +#define APPEARANCE_UUID (0x2A01) +#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) +#define RECONNECTION_ADDR_UUID (0x2A03) +#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) +/** + * @} + */ + +/** + * @name Characteristic value lengths + * @{ + */ +#define DEVICE_NAME_CHARACTERISTIC_LEN (8) +#define APPEARANCE_CHARACTERISTIC_LEN (2) +#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) +#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) +#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) +/** + * @} + */ + +/*------------- AD types for adv data and scan response data ----------------*/ + +/** + * @defgroup AD_Types AD Types + * @brief AD Types + * @{ + */ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +/** + * @anchor Flags_AD_Type_bits + * @name Flags AD Type bits + * @brief Bits in Flags AD Type + * @{ + */ +#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) +#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) +#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) +#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) +#define FLAG_BIT_LE_BR_EDR_HOST (0x10) +/** + * @} + */ + +/** + * @name Service UUID AD types + * @{ + */ +#define AD_TYPE_16_BIT_SERV_UUID (0x02) +#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) +#define AD_TYPE_32_BIT_SERV_UUID (0x04) +#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) +#define AD_TYPE_128_BIT_SERV_UUID (0x06) +#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) +/** + * @} + */ + +/* LOCAL NAME AD types */ +/** + * @name Local name AD types + * @{ + */ +#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) +#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) +/** + * @} + */ + +/* TX power level AD type*/ +#define AD_TYPE_TX_POWER_LEVEL (0x0A) + +/* Class of device */ +#define AD_TYPE_CLASS_OF_DEVICE (0x0D) + +/* security manager TK value AD type */ +#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) + +/* security manager OOB flags */ +#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) + +/* slave connection interval AD type */ +#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) + +/* service solicitation UUID list Ad types*/ +/** + * @name Service solicitation UUID list AD types + * @{ + */ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) +#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) +/** + * @} + */ + +/* service data AD type */ +#define AD_TYPE_SERVICE_DATA (0x16) + +/* manufaturer specific data AD type */ +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/* appearance AD type */ +#define AD_TYPE_APPEARANCE (0x19) + +/* advertising interval AD type */ +#define AD_TYPE_ADVERTISING_INTERVAL (0x1A) + +/** + * @} + */ + +#define MAX_ADV_DATA_LEN (31) + +#define DEVICE_NAME_LEN (7) +#define BD_ADDR_SIZE (6) + +/** + * @name Privacy flag values + * @{ + */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) +/** + * @} + */ + +/** + * @name Intervals + * Intervals in terms of 625 micro sec + * @{ + */ +#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ +#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ +#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ +#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ +#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ +#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ +#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ +#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ +/** + * @} + */ + +/** + * @name Timeout values + * @{ + */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ +/** + * @} + */ + +/** + * @anchor gap_roles + * @name GAP Roles + * @{ +*/ +#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) +#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) + +#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) +#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) +/** + * @} + */ + +/** + * @anchor gap_procedure_codes + * @name GAP procedure codes + * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event + * and aci_gap_terminate_gap_procedure() command. + * @{ + */ +#define GAP_LIMITED_DISCOVERY_PROC (0x01) +#define GAP_GENERAL_DISCOVERY_PROC (0x02) +#define GAP_NAME_DISCOVERY_PROC (0x04) +#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) +#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) +#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) +#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) +#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1231 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gap_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GAP_ACI_H__ +#define __BLUENRG_GAP_ACI_H__ + +/** + *@addtogroup GAP GAP + *@brief GAP layer. + *@{ + */ + +/** + *@defgroup GAP_Functions GAP functions + *@brief API for GAP layer. + *@{ + */ + +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". + * @param privacy_enabled Enable (1) or disable (0) privacy. + * @param device_name_char_len Length of the device name characteristic + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, + uint8_t device_name_char_len, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Privacy Flag (peripheral role only) + * @li Reconnection Address (peripheral role only) + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB04A1(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); + +/** + * @brief Set the Device in non-discoverable mode. + * @note This command will disable the LL advertising. + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_discoverable(void); + +/** + * @brief Put the device in limited discoverable mode + * (as defined in GAP specification volume 3, section 9.2.3). + * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. + * The advertising can be disabled at any time by issuing + * aci_gap_set_non_discoverable() command. + * The AdvIntervMin and AdvIntervMax parameters are optional. If both + * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). + * Host can set the Local Name, a Service UUID list and the Slave Connection + * Minimum and Maximum. If provided, these data will be inserted into the + * advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() + * separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following + * standard AD types: + * @li AD Flags + * @li TX Power Level + * + * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates + * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. + * + * Example: + * @code + * + * #define ADV_INTERVAL_MIN_MS 100 + * #define ADV_INTERVAL_MAX_MS 200 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, + * (ADV_INTERVAL_MAX_MS*1000)/0.625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * sizeof(serviceUUIDList), serviceUUIDList, + * 0, 0); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 250 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 500 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg NO_WHITE_LIST_USE + * @arg WHITE_LIST_FOR_ONLY_SCAN + * @arg WHITE_LIST_FOR_ONLY_CONN + * @arg WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +/** + * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4). + * @note The device will be discoverable until the Host issue Aci_Gap_Set_Non_Discoverable command. + * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses + * the default values for advertising intervals (1.28 s and 2.56 s respectively for IDB04A1). + * When using connectable undirected advertising events:\n + * @li Adv_Interval_Min = 30 ms + * @li Adv_Interval_Max = 60 ms + * \nWhen using non-connectable advertising events or scannable undirected advertising events:\n + * @li Adv_Interval_Min = 100 ms + * @li Adv_Interval_Max = 150 ms + * Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided, + * these data will be inserted into the advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following standard AD types: + * @li AD Flags + * @li TX Power Level + * + * Usage example: + * + * @code + * + * #define ADV_INTERVAL_MIN_MS 800 + * #define ADV_INTERVAL_MAX_MS 900 + * #define CONN_INTERVAL_MIN_MS 100 + * #define CONN_INTERVAL_MAX_MS 300 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625, + * (ADV_INTERVAL_MAX_MS*1000)/625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * 0, NULL, + * (CONN_INTERVAL_MIN_MS*1000)/1250, + * (CONN_INTERVAL_MAX_MS*1000)/1250); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 1.28 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 2.56 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ONLY_SCAN + * @arg @ref WHITE_LIST_FOR_ONLY_CONN + * @arg @ref WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); + +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @param adv_interv_min Minimum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @param adv_interv_max Maximum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max); +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); + +/** + * @brief Set the IO capabilities of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param io_capability One of the allowed codes for IO Capability: + * @arg @ref IO_CAP_DISPLAY_ONLY + * @arg @ref IO_CAP_DISPLAY_YES_NO + * @arg @ref IO_CAP_KEYBOARD_ONLY + * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT + * @arg @ref IO_CAP_KEYBOARD_DISPLAY + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_io_capability(uint8_t io_capability); + +/** + * @brief Set the authentication requirements for the device. + * @note If the oob_enable is set to 0, oob_data will be ignored. + * This command has to be given only when the device is not in a connected state. + * @param mitm_mode MITM mode: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @param oob_enable If OOB data are present or not: + * @arg @ref OOB_AUTH_DATA_ABSENT + * @arg @ref OOB_AUTH_DATA_PRESENT + * @param oob_data Out-Of-Band data + * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process + * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process + * @param use_fixed_pin If application wants to use a fixed pin or not: + * @arg @ref USE_FIXED_PIN_FOR_PAIRING + * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING + * If a fixed pin is not used, it has to be provided by the application with + * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will + * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is + * accepted. + * @param bonding_mode One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode); + /** + * @brief Set the authorization requirements of the device. + * @note This command has to be given when connected to a device if authorization is required to access services + * which require authorization. + * @param conn_handle Handle of the connection. + * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required + * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables + * the authorization requirement in the device and when a remote device + * tries to read/write a characeristic with authorization requirements, the stack will + * send back an error response with "Insufficient authorization" error code. + * After pairing is complete a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event + * will be sent to the Host. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); + +/** + * @brief Provide the pass key that will be used during pairing. + * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param conn_handle Connection handle + * @param passkey Pass key that will be used during the pairing process. Must be a number between + * 0 and 999999. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); + +/** + * @brief Authorize a device to access attributes. + * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. + * + * @param conn_handle Connection handle + * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) + * @arg @ref CONNECTION_REJECTED : Reject (reject connection) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); + +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @param own_address_type If Privacy is disabled, then the peripheral address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the peripheral address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); + +/** + * @brief Put the device into undirected connectable mode. + * @note If privacy is enabled in the device, a resolvable private address is generated and used + * as the advertiser's address. If not, the address of the type specified in own_addr_type + * is used for advertising. + * @param own_addr_type Type of our address used during advertising: + * if BLUENRG (IDB04A1) + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * else if BLUENRG_MS (IDB05A1) + * If Privacy is disabled: + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled: + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_filter_policy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ALL + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); + +/** + * @brief Send a slave security request to the master. + * @note This command has to be issued to notify the master of the security requirements of the slave. + * The master may encrypt the link, initiate the pairing procedure, or reject the request. + * @param conn_handle Connection handle + * @param bonding One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @param mitm_protection If MITM protection is required or not: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); + +/** + * @brief Update advertising data. + * @note This command can be used to update the advertising data for a particular AD type. + * If the AD type specified does not exist, then it is added to the advertising data. + * If the overall advertising data length is more than 31 octets after the update, then + * the command is rejected and the old data is retained. + * @param AdvLen Length of AdvData array + * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification + * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. + * Example + * @code + * tBleStatus ret; + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; + * + * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * 8, local_name, 3, serviceUUIDList, 0, 0); + * ret = aci_gap_update_adv_data(5, manuf_data); + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); + +/** + * @brief Delete an AD Type + * @note This command can be used to delete the specified AD type from the advertisement data if + * present. + * @param ad_type One of the allowed AD types (see @ref AD_Types) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); + +/** + * @brief Get the current security settings + * @note This command can be used to get the current security settings of the device. + * @param mitm_protection @arg 0: Not required + * @arg 1: Required + * @param bonding @arg 0: No bonding mode + * @arg 1: Bonding mode + * @param oob_data @arg 0: Data absent + * @arg 1: Data present + * @param passkey_required @arg 0: Not required + * @arg 1: Fixed pin is present which is being used + * @arg 2: Passkey required for pairing. An event will be generated + * when required. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required); + +/** + * @brief Add addresses of bonded devices into the controller's whitelist. + * @note The command will return an error if there are no devices in the database or if it was unable + * to add the device into the whitelist. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_configure_whitelist(void); + +/** + * @brief Terminate a connection. + * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. + * @param conn_handle Connection handle + * @param reason Reason for requesting disconnection. The error code can be any of ones as specified + * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); + +/** + * @brief Clear the security database. + * @note All the devices in the security database will be removed. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_clear_security_database(void); + +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @param conn_handle + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB04A1(void); + +/** + * @brief Start the limited discovery procedure. + * @note The controller is commanded to start active scanning. When this procedure is started, + * only the devices in limited discoverable mode are returned to the upper layers. + * The procedure is terminated when either the upper layers issue a command to terminate the + * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code + * set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated + * due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC. + * The device found when the procedure is ongoing is returned to the upper layers through the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the general discovery procedure. + * @note The controller is commanded to start active scanning. The procedure is terminated when + * either the upper layers issue a command to terminate the procedure by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC + * or a timeout happens. When the procedure is terminated due to any of the above reasons, + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to + * @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to + * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the name discovery procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. Once a connection is established, GATT procedure is started to read the + * device name characteristic. When the read is completed (successfully or unsuccessfully), + * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also + * contains the name of the device if the device name was read successfully. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Start the auto connection establishment procedure. + * @note The devices specified are added to the white list of the controller and a LE_Create_Connection + * call will be made to the controller by GAP with the initiator filter policy set to + * use whitelist to determine which advertiser to connect to. When a command is issued to + * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the + * controller by GAP. + * The procedure is terminated when either a connection is successfully established with one of + * the specified devices in the white list or the procedure is explicitly terminated by issuing + * the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start a general connection establishment procedure. + * @note The host enables scanning in the controller with the scanner filter policy set + * to accept all advertising packets and from the scanning results all the devices + * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * The upper layer then has to select one of the devices to which it wants to connect + * by issuing the command aci_gap_create_connection(). The procedure is terminated + * when a connection is established or the upper layer terminates the procedure by + * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates); +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); + +/** + * @brief Start a selective connection establishment procedure. + * @note The GAP adds the specified device addresses into white list and enables scanning in + * the controller with the scanner filter policy set to accept packets only from + * devices in whitelist. All the devices found are sent to the upper layer by the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the + * devices to which it wants to connect by issuing the command aci_gap_create_connection(). + * On completion of the procedure a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated + * with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * The procedure is terminated when a connection is established or the upper layer terminates + * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure + * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start the direct connection establishment procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. The procedure can be terminated explicitly by the upper layer by issuing + * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the + * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller + * by GAP. + * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can + * be explicitly terminated by the upper layer by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is + * returned with the procedure code set to the corresponding procedure. + * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes"). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); + +/** + * @brief Start the connection parameter update procedure. + * @note Allowed by the Central to update the connection parameter of the specified connection. + * A Link Layer Connection Update procedure is started on the controller. + * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to + * the upper layer. + * @param conn_handle Handle of the connection for which the update procedure has to be started. + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Send a pairing request. + * @note Send the SM pairing request to start a pairing process from a Central. The authentication + * requirements and IO capabilities should be set before issuing this command using + * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). + * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. + * @param conn_handle Handle of the connection for which the pairing request has to be sent. + * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded + * @arg 0x01: Pairing request will be sent even if the device was previously bonded + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param[in] address Address to be resolved. + * @param[out] actual_address The public or static random address of the peer device, distributed during pairing phase. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); + +/** + * @brief This command gets the list of bonded devices. + * @note It returns the number of addresses and the corresponding address types and values. + * Example: + * @code + * tBleStatus ret; + * uint8_t num_devices = 0; + * uint8_t device_list[12*7]; + * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); + * for(int i = 0; i < num_devices; i+=7){ + * uint8_t addr_type = device_list[i]; + * uint8_t addr = device_list[i+1]; + * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); + * } + * @endcode + * + * @param[out] num_devices The number of bonded devices. + * @param[out] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address + * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. + * @param device_list_size Maximum size of the device_list buffer used to return the device list. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); + +/** + * @brief Puts the device into broadcast mode + * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address + * as specified in the own_addr_type parameter of the command. + * @param adv_interv_min Minimum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_interv_max Maximum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param own_addr_type If Privacy is disabled, the broadcaster address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the broadcaster address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_data_length Length of the advertising data in the advertising packet + * @param adv_data Advertising data used by the device while advertising + * @param num_whitelist_entries Number of devices to be added to whitelist + * @param addr_array It will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Starts an observation procedure, when the device is in Observer role. + * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer + * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth + * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. + * The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. + * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param own_address_type If Privacy is disabled, then the scanner address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the scanner address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates); + +/** + * @brief The command finds whether a device is bonded. + * @note If the device is using a resolvable private address and it has been bonded, then the command will return + * BLE_STATUS_SUCCESS. + * @param peer_address_type The address type of the peer device + * @arg @ref PUBLIC_ADDR. + * @arg @ref RANDOM_ADDR. + * @param peer_address Address used by the peer device while advertising. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address); + + +/** + * @} + */ + +/** + * @defgroup GAP_Events GAP events + * @{ + */ + +/** + * This event is generated by the controller when the limited discoverable + * mode ends due to timeout (180 seconds). No parameters in the event. + */ +#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) + + +/** + * This event is generated when the pairing process has completed successfully + * or a pairing procedure timeout has occurred or the pairing has failed. + * This is to notify the application that we have paired with a remote device + * so that it can take further actions or to notify that a timeout has occurred + * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. + */ +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +typedef __packed struct _evt_gap_pairing_cmplt{ + uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ + /** + * 0x00: Pairing Success. Pairing with a remote device was successful\n + * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n + * 0x02: Pairing Failed. The pairing failed with the remote device. + */ + uint8_t status; +} PACKED evt_gap_pairing_cmplt; + + +/** + * This event is generated by the Security manager to the application when a pass key is required for pairing. + * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. + * See @ref _evt_gap_pass_key_req. + */ +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +typedef __packed struct _evt_gap_pass_key_req{ + uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ +} PACKED evt_gap_pass_key_req; + + +/** + * This event is generated by the Security manager to the application when the application + * has set that authorization is required for reading/writing of attributes. This event will + * be generated as soon as the pairing is complete. When this event is received, + * aci_gap_authorization_response() command should be used by the application. + * See @ref _evt_gap_author_req. + */ +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +typedef __packed struct _evt_gap_author_req{ + uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ +} PACKED evt_gap_author_req; + +/** + * This event is generated when the slave security request is successfully sent to the master. + * No parameters for this event. + */ +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) + +/** + * This event is generated on the slave when a aci_gap_slave_security_request() is called to reestablish the bond + * with a master but the master has lost the bond. When this event is received, the upper layer has to issue the + * command aci_gap_allow_rebond() in order to allow the slave to continue the pairing process with the master. + * On the master this event is raised when aci_gap_send_pairing_request() is called to reestablish a bond with a slave + * but the slave has lost the bond. In order to create a new bond the master has to launch aci_gap_send_pairing_request() + * with force_rebond set to 1. + * No parameters for this event + */ +#define EVT_BLUE_GAP_BOND_LOST (0X0405) + +/** + * The event is given by the GAP layer to the upper layers when a device is discovered during scanning + * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. + */ +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef __packed struct _evt_gap_device_found{ + uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ + uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ + tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ + uint8_t data_length; /**< Length of advertising or scan response data. */ + uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ +} PACKED evt_gap_device_found; + +/** + * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated + * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. + */ +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef __packed struct _evt_gap_procedure_complete{ + uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ + /** + * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed + * due to authentication requirements). + */ + uint8_t status; + /** + * Procedure specific data.\n + * @li For Name Discovery Procedure:\n + * the name of the peer device if the procedure completed successfully. + * @li For General Connection Establishment Procedure:\n + * The reconnection address written to the peripheral device if the peripheral is privacy enabled + */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_gap_procedure_complete; + +/** + * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral + * is not able to resolve the private address of the peer device after connecting to it. + */ +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) +typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ + uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ +} PACKED evt_gap_addr_not_resolved_IDB05A1; +/** + * This event is raised when the reconnection address is generated during the general connection + * establishment procedure. The same address is set into the peer device also as a part of the general + * connection establishment procedure. In order to make use of the reconnection address the next time + * while connecting to the bonded peripheral, the application needs to use this reconnection address + * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() + * and aci_gap_start_auto_conn_establish_proc(). + */ +#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) +typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ + uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ +} PACKED evt_gap_reconnection_addr_IDB04A1; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1128 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GATT_ACI_H__ +#define __BLUENRG_GATT_ACI_H__ + +#include "bluenrg_gatt_server.h" + +/** + *@addtogroup GATT GATT + *@brief GATT layer. + *@{ + */ + +/** + *@defgroup GATT_Functions GATT functions + *@brief API for GATT layer. + *@{ + */ + +/** + * @brief Initialize the GATT layer for server and client roles. + * @note It adds also the GATT service with Service Changed Characteristic. + * Until this command is issued the GATT channel will not process any commands + * even if the connection is opened. This command has to be given + * before using any of the GAP features. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_init(void); + +/** + * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs + * to reserve the handle ranges for this service using max_attr_records parameter. This + * parameter specifies the maximum number of attribute records that can be added to this + * service (including the service attribute, include attribute, characteristic attribute, + * characteristic value attribute and characteristic descriptor attribute). Handle of the + * created service is returned. + * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors + * are allocated from the attribute pool. + * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field + * @param service_type Primary or secondary service. See @ref Service_type "Service Type". + * @param max_attr_records Maximum number of attribute records that can be added to this service + * (including the service declaration itself) + * @param[out] serviceHandle Handle of the Service. When this service is added to the service, + * a handle is allocated by the server to this service. Server also + * allocates a range of handles for this service from serviceHandle to + * <serviceHandle + max_attr_records>. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, + const uint8_t* service_uuid, + uint8_t service_type, + uint8_t max_attr_records, + uint16_t *serviceHandle); + +/** + * @brief Include a service given by included_start_handle and included_end_handle to another service + * given by service_handle. Attribute server creates an INCLUDE definition attribute and return + * the handle of this attribute in included_handle. + * @param service_handle Handle of the service to which another service has to be included + * @param included_start_handle Start Handle of the service which has to be included in service + * @param included_end_handle End Handle of the service which has to be included in service + * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". + * @param[in] included_uuid 16-bit or 128-bit UUID. + * @param[out] included_handle Handle of the include declaration. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle); + +/** + * @brief Add a characteristic to a service. + * @param serviceHandle Handle of the service to which the characteristic has to be added. + * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param charUuid 16-bit or 128-bit UUID. + * @param charValueLen Maximum length of the characteristic value. + * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, + * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". + * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @arg GATT_DONT_NOTIFY_EVENTS + * @arg GATT_NOTIFY_ATTRIBUTE_WRITE + * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP + * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. + * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client + * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE + * properties. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle); + +/** + * Add a characteristic descriptor to a service. + * @param serviceHandle Handle of the service to which the characteristic belongs + * @param charHandle Handle of the characteristic to which description has to be added. + * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG + * (Well_known_UUIDs) or a user-defined one. + * @param descValueMaxLen The maximum length of the descriptor value + * @param descValueLen Current Length of the characteristic descriptor value + * @param[in] descValue Value of the characteristic description + * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". + * @arg ATTR_NO_ACCESS + * @arg ATTR_ACCESS_READ_ONLY + * @arg ATTR_ACCESS_WRITE_REQ_ONLY + * @arg ATTR_ACCESS_READ_WRITE + * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE + * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param[out] descHandle Handle of the Characteristic Descriptor. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle); + +/** + * @brief Update a characteristic value in a service. + * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. The command is queued into the + * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, + * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or + * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate + * than what is allowed by the link. Throughput on BLE link depends on connection interval and + * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() + * for more info on how to suggest new connection parameters from a slave). If the application does not + * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function + * returns @ref BLE_STATUS_SUCCESS or any other error code.\n + * Example:\n + * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some + * notifications will be lost. + * @code + * tBleStatus Free_Fall_Notify(void) + * { + * uint8_t val; + * tBleStatus ret; + * + * val = 0x01; + * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); + * + * if (ret != BLE_STATUS_SUCCESS){ + * PRINTF("Error while updating FFall characteristic.\n") ; + * return BLE_STATUS_ERROR ; + * } + * return BLE_STATUS_SUCCESS; + * } + * @endcode + * Here if BlueNRG buffer become full, the application try again to send the notification. + * @code + * struct timer t; + * Timer_Set(&t, CLOCK_SECOND*10); + * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ + * // Radio is busy (buffer full). + * if(Timer_Expired(&t)) + * break; + * } + * @endcode + * + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic + * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, + * and the attribute value is of variable length, then the length of the attribute will + * be set to the charValueLen. If the charValOffset is set to a value greater than 0, + * then the length of the attribute will be set to the maximum length as specified for + * the attribute while adding the characteristic. + * @param charValueLen Length of the characteristic value in octets + * @param[in] charValue Characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue); +/** + * @brief Delete the specified characteristic from the service. + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); + +/** + * @brief Delete the specified service from the GATT server database. + * @param servHandle Handle of the service to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_service(uint16_t servHandle); + +/** + * @brief Delete the Include definition from the service. + * @param servHandle Handle of the service to which Include definition belongs + * @param includeServHandle Handle of the Included definition to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); + +/** + * @brief Perform an ATT MTU exchange procedure. + * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP + * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated + * to indicate the end of the procedure. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); + +/** + * @brief Send a @a Find @a Information @a Request. + * @note This command is used to obtain the mapping of attribute handles with their associated + * types. The responses of the procedure are given through the + * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by + * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range of attributes to be discovered on the server + * @param end_handle Ending handle of the range of attributes to be discovered on the server + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send a @a Find @a By @a Type @a Value @a Request + * @note The Find By Type Value Request is used to obtain the handles of attributes that + * have a given 16-bit UUID attribute type and a given attribute value. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid 2 octet UUID to find (little-endian) + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). + * @param attr_val Attribute value to find + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send a @a Read @a By @a Type @a Request + * @note The Read By Type Request is used to obtain the values of attributes where the attribute type + * is known but the handle is not known. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Read @a By @a Group @a Type @a Request + * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute + * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping + * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Prepare @a Write @a Request + * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param attr_handle The handle of the attribute to be written + * @param value_offset The offset of the first octet to be written + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). + * @param attr_val The value of the attribute to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send an @a Execute @a Write @a Request + * @note The Execute Write Request is used to request the server to write or cancel the write of all the + * prepared values currently held in the prepare queue from this client. + * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param execute @arg 0x00 Cancel all prepared writes + * @arg 0x01 Immediately write all pending prepared values. + * @return Value indicating success or error code. + */ +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); + +/** + * @brief This command will start the GATT client procedure to discover all primary services on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +/** + * @brief Start the procedure to discover the primary services of the specified UUID on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to find all included services. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle Start handle of the service + * @param end_handle End handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Start the procedure to discover all the characteristics of a given service. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_attr_handle Start attribute handle of the service + * @param end_attr_handle End attribute handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +/** + * @brief Start the procedure to discover all the characteristics specified by a UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Start attribute handle of the service + * @param end_handle End attribute handle of the service + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); + +/** + * @brief Start the procedure to discover all characteristic descriptors on the server. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. + * @param conn_handle Connection handle for which the command is given. + * @param char_val_handle Starting handle of the characteristic + * @param char_end_handle End handle of the characteristic + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +/** + * @brief Start the procedure to read the attribute value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to read all the characteristics specified by the UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range to be searched + * @param end_handle End handle of the range to be searched + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start a procedure to read multiple characteristic values from a server. + * @note This sub-procedure is used to read multiple Characteristic Values from a server when the + * client knows the Characteristic Value Handles. + * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param num_handles The number of handles for which the value has to be read + * @param set_of_handles The handles for which the attribute value has to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles); + +/** + * @brief Start the procedure to write a characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to write a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start the procedure to write a characteristic reliably. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to write a long characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP + * event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic descriptor + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start the procedure to write a characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to read the descriptor specified. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the descriptor to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to write a characteristic value without waiting for any response from the server. + * @note No events are generated after this command is executed. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 3) + * @param[in] attr_val Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start a signed write without response from the server. + * @note The procedure i used to write a characteristic value with an authentication signature without waiting + * for any response from the server. It cannot be used when the link is encrypted. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 13). + * @param attr_val Value to be written + * @return Value indicating success or error code + */ +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Confirm an indication + * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); + +/** + * @brief Allow or reject a write request from a client. + * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, + * then the status has to be set to 1 and the error code has to be set to the error code that has to be + * passed to the client. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n + * 0x01: The value cannot be written to the attribute specified by the attr_handle. + * @param err_code The error code that has to be passed to the client in case the write has to be rejected. + * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val); + +/** + * @brief Allow the GATT server to send a response to a read request from a client. + * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ + * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response + * can be sent to the client. So if the application wishes to update any of the attributes before + * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value + * and then give this command. The application should perform the required operations within 30 seconds, + * otherwise the GATT procedure will go to timeout. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_allow_read(uint16_t conn_handle); + +/** + * @brief Set the security permission for the attribute handle specified. + * @note Currently the setting of security permission is allowed only for client configuration descriptor. + * @param service_handle Handle of the service which contains the attribute whose security + * permission has to be modified. + * @param attr_handle Handle of the attribute whose security permission has to be modified. + * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission); + +/** + * @brief This command sets the value of the descriptor specified by charDescHandle. + * @param servHandle Handle of the service which contains the descriptor. + * @param charHandle Handle of the characteristic which contains the descriptor. + * @param charDescHandle Handle of the descriptor whose value has to be set. + * @param charDescValOffset Offset from which the descriptor value has to be updated. + * @param charDescValueLen Length of the descriptor value + * @param[in] charDescValue descriptor value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue); + +/** + * @brief Reads the value of the attribute handle specified from the local GATT database. + * @param attr_handle Handle of the attribute to read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + + /** + * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. + * @param attr_handle Handle of the attribute to read + * @param offset Offset from which the value needs to be read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); +/** + * @brief Update the value of a characteristic and sends notifications or indications. + * @note This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute + * up to 512 bytes and indicate selectively the generation of indications and notifications. + * @param service_handle Handle of the service to which the characteristic belongs. + * @param char_handle Handle of the characteristic + * @param update_type Bitmask that controls generation of notifications and indications. It can be a combination + * @arg @ref NOTIFICATION (0x01): send notification, if enabled. + * @arg @ref INDICATION (0x02): send indication, if enabled. + * If set to 0 no notifications or indications are sent. + * @param char_length Total length of the characteristic value. In case of a variable size characteristic, + * this field specifies the new length of the characteristic value after the update; + * in case of fixed length characteristic this field is ignored. + * @param value_offset The offset from which the attribute value has to be updated + * @param value_length Length of the value to be updated + * @param[out] value Updated characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value); + +/** + * @} + */ + + +/** + * @defgroup GATT_Events GATT events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** + * This event (if enabled, see @ref Gatt_Event_Mask "Gatt Event Mask") is raised to the application + * by the GATT server when a client modifies any attribute on the server, as consequence of one of + * the following GATT procedures: + * @li write without response + * @li signed write without response + * @li write characteristic value + * @li write long characteristic value + * @li reliable write. + * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. + */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint16_t offset; /**< Offset from which the write has been performed by the peer device */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB05A1; + +typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB04A1; + +/** + * This event is generated by the client/server to the application on a GATT timeout (30 seconds). + * See @ref _evt_gatt_procedure_timeout. + */ +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +typedef __packed struct _evt_gatt_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ +} PACKED evt_gatt_procedure_timeout; + +/** + * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). + * See @ref _evt_att_exchange_mtu_resp. + */ +#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) +typedef __packed struct _evt_att_exchange_mtu_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data (always 1). */ + uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ +} PACKED evt_att_exchange_mtu_resp; + +/** + * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and + * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. + */ +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef __packed struct _evt_att_find_information_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ + /** + * A sequence of handle-uuid pairs.\n + * @li if format=1, each pair is:\n + * [2 octets for handle, 2 octets for UUIDs] \n + * @li if format=2, each pair is:\n + * [2 octets for handle, 16 octets for UUIDs] + */ + uint8_t handle_uuid_pair[VARIABLE_SIZE]; +} PACKED evt_att_find_information_resp; + +/** + * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See + * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. + */ +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +typedef __packed struct _evt_att_find_by_type_val_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + /** + * Handles Information List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] + */ + uint8_t handles_info_list[VARIABLE_SIZE]; +} PACKED evt_att_find_by_type_val_resp; + +/** + * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and + * aci_gatt_disc_all_charac_of_serv(). + * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. + */ +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef __packed struct _evt_att_read_by_type_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ + /** + * Attribute Data List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] + */ + uint8_t handle_value_pair[VARIABLE_SIZE]; +} PACKED evt_att_read_by_type_resp; + +/** + * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). + * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. + */ +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +typedef __packed struct _evt_att_read_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ +} PACKED evt_att_read_resp; + +/** + * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). + * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. + */ +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +typedef __packed struct _evt_att_read_blob_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ +} PACKED evt_att_read_blob_resp; + +/** + * This event is generated in response to a @a Read @a Multiple @a Request. + * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. + */ +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +typedef __packed struct _evt_att_read_mult_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ +} PACKED evt_att_read_mult_resp; + +/** + * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). + * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. + */ +#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) +typedef __packed struct _evt_att_read_by_group_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_data_length; /**< The size of each Attribute Data. */ + /** + * A list of Attribute Data where the attribute data is composed by: + * @li 2 octets for Attribute Handle + * @li 2 octets for End Group Handle + * @li (attribute_data_length - 4) octets for Attribute Value + */ + uint8_t attribute_data_list[VARIABLE_SIZE]; +} PACKED evt_att_read_by_group_resp; + +/** + * This event is generated in response to a @a Prepare @a Write @a Request. + * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. + */ +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +typedef __packed struct _evt_att_prepare_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attribute_handle; /**< The handle of the attribute to be written. */ + uint16_t offset; /**< The offset of the first octet to be written. */ + uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ +} PACKED evt_att_prepare_write_resp; + +/** + * This event is generated in response to an @a Execute @a Write @a Request. + * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. + */ +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +typedef __packed struct _evt_att_exec_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Always 0. */ +} PACKED evt_att_exec_write_resp; + +/** + * This event is generated when an indication is received from the server. + * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. + */ +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +typedef __packed struct _evt_gatt_indication{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_indication; + +/** + * This event is generated when a notification is received from the server. + * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. + */ +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef __packed struct _evt_gatt_notification{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_attr_notification; + +/** + * This event is generated when a GATT client procedure completes either with error or successfully. + * See @ref _evt_gatt_procedure_complete. + */ +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef __packed struct _evt_gatt_procedure_complete{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ + uint8_t data_length; /**< Length of error_code field (always 1). */ + /** + * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). + */ + uint8_t error_code; +} PACKED evt_gatt_procedure_complete; + +/** + * This event is generated when an Error Response is received from the server. The error response can be given + * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended + * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. + */ +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +typedef __packed struct _evt_gatt_error_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t req_opcode; /**< The request that generated this error response. */ + uint16_t attr_handle; /**< The attribute handle that generated this error response. */ + uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ +} PACKED evt_gatt_error_resp; + +/** + * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using + * Characteristic UUID" procedure. + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. + */ +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + /** + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. + */ + uint8_t attr_value[VARIABLE_SIZE]; +} PACKED evt_gatt_disc_read_char_by_uuid_resp; + +/** + * This event is given to the application when a write request, write command or signed write command + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * If the write is rejected by the application, then the value of the attribute will not be modified. + * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. + * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef __packed struct _evt_gatt_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_write_permit_req; + +/** + * This event is given to the application when a read request or read blob request is received by the server + * from the client. This event will be given to the application only if the event bit for this event generation + * is set when the characteristic was added. + * On receiving this event, the application can update the value of the handle if it desires and when done + * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef __packed struct _evt_gatt_read_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ + uint8_t data_length; /**< Length of offset field. */ + uint16_t offset; /**< Contains the offset from which the read has been requested */ +} PACKED evt_gatt_read_permit_req; + +/** + * This event is given to the application when a read multiple request or read by type request is received + * by the server from the client. This event will be given to the application only if the event bit for this + * event generation is set when the characteristic was added. + * On receiving this event, the application can update the values of the handles if it desires and when done + * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_multi_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) +typedef __packed struct _evt_gatt_read_multi_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ +} PACKED evt_gatt_read_multi_permit_req; + +/** + * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2). + * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES. + * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value(). + * See @ref evt_gatt_tx_pool_vailable. + * + */ +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE (0x0C16) +typedef __packed struct _evt_gatt_tx_pool_available{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t available_buffers; /**< Length of data field. */ +} PACKED evt_gatt_tx_pool_available; + +/** + * This event is raised on the server when the client confirms the reception of an indication. + */ +#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT (0x0C17) +typedef __packed struct _evt_gatt_server_confirmation{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ +} PACKED evt_gatt_server_confirmation; +/** + * This event is given to the application when a prepare write request + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * Based on the response from the application, the attribute value will be modified by the stack. + * If the write is rejected by the application, then the value of the attribute will not be modified + * and an error response will be sent to the client, with the error code as specified by the application. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ (0x0C18) +typedef __packed struct _evt_gatt_prepare_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint16_t offset; /**< The offset from which the prepare write has been requested */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_prepare_write_permit_req; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,229 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gatt_server.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GATT server layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BNRG_GATT_SERVER_H__ +#define __BNRG_GATT_SERVER_H__ + +#include "ble_compiler.h" +#include "ble_status.h" + +/** + *@addtogroup GATT GATT + *@{ + */ + +/** + * @anchor Well-Known_UUIDs + * @name Well-Known UUIDs + * @{ + */ +#define PRIMARY_SERVICE_UUID (0x2800) +#define SECONDARY_SERVICE_UUID (0x2801) +#define INCLUDE_SERVICE_UUID (0x2802) +#define CHARACTERISTIC_UUID (0x2803) +#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) +#define CHAR_USER_DESC_UUID (0x2901) +#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) +#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) +#define CHAR_FORMAT_DESC_UUID (0x2904) +#define CHAR_AGGR_FMT_DESC_UUID (0x2905) +#define GATT_SERVICE_UUID (0x1801) +#define GAP_SERVICE_UUID (0x1800) +#define SERVICE_CHANGED_UUID (0x2A05) +/** + * @} + */ + +/** + * @anchor Access_permissions + * @name Access permissions + * Access permissions for an attribute + * @{ + */ +#define ATTR_NO_ACCESS (0x00) +#define ATTR_ACCESS_READ_ONLY (0x01) +#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) +#define ATTR_ACCESS_READ_WRITE (0x03) +#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) +#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) +/** + * Allows all write procedures + */ +#define ATTR_ACCESS_WRITE_ANY (0x0E) +/** + * @} + */ + +/** + * @anchor Char_properties + * @name Characteristic properties. + * @{ + */ +#define CHAR_PROP_BROADCAST (0x01) +#define CHAR_PROP_READ (0x02) +#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) +#define CHAR_PROP_WRITE (0x08) +#define CHAR_PROP_NOTIFY (0x10) +#define CHAR_PROP_INDICATE (0x20) +#define CHAR_PROP_SIGNED_WRITE (0x40) +#define CHAR_PROP_EXT (0x80) +/** + * @} + */ + + +/** + * @anchor Security_permissions + * @name Security permissions for an attribute. + * @{ + */ +#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ +#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ +#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ +#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ +/** + * @} + */ + +/** + * @anchor UUID_Types + * @name Type of UUID (16 bit or 128 bit). + * @{ + */ +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) +/** + * @} + */ + +/** + * @anchor Service_type + * @name Type of service (primary or secondary) + * @{ + */ +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) +/** + * @} + */ + +/** + * @anchor Gatt_Event_Mask + * @name Gatt Event Mask + * Type of event generated by GATT server + * @{ + */ +#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ +#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. + An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ +#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd + or a signed write cmd are received by the server for this attribute. + An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ +#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is + received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ +/** + * @} + */ + +/** + * @name Type of characteristic length + * See aci_gatt_add_char() + * @{ + */ +#define CHAR_VALUE_LEN_CONSTANT (0x00) +#define CHAR_VALUE_LEN_VARIABLE (0x01) +/** + * @} + */ + + +/** + * @name Encryption key size + * @{ + */ +/** + * Minimum encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Maximum encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) +/** + * @} + */ + +/** + * @name Characteristic Presentation Format + * @{ + */ +typedef __packed struct _charactFormat { + uint8_t format; + int8_t exp; + uint16_t unit; + uint8_t name_space; + uint16_t desc; +} PACKED charactFormat; + +/** + * @} + */ + +/** + * @name Format + * @{ + */ +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F +/** + * @} + */ + +/** + * @name Unit + * @{ + */ +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 +/** + * @} + */ + + +/** + * ATT MTU size + */ +#define ATT_MTU (23) + +/** + * @} + */ + + /** + * @name Update type of aci_gatt_upd_char_val_ext(). + * @{ + */ + +#define NOTIFICATION 1 +#define INDICATION 2 + +#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,385 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hal_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with HCI commands for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_HAL_ACI_H__ +#define __BLUENRG_HAL_ACI_H__ + +/** + *@addtogroup HAL HAL + *@brief Hardware Abstraction Layer. + *@{ + */ + +/** + * @defgroup HAL_Functions HAL functions + * @brief API for BlueNRG HAL layer. + * @{ + */ + +/** + * @brief This command retrieves the buid number of the firmware. + * @param[out] build_number Build number identifying the firmware release. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number); + +/** + * @brief This command writes a value to a low level configure data structure. + * @note It is useful to setup directly some low level parameters for the system at runtime. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * + * @param len Length of data to be written + * @param[out] val Data to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val); + +/** + * @brief This command requests the value in the low level configure data structure. + * The number of read bytes changes for different Offset. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * @param data_len Length of the data buffer + * @param[out] data_len_out_p length of the data returned by the read. + * @param[out] data Read data + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data); + +/** + * @brief This command sets the TX power level of the BlueNRG. + * @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines + * the output power level (dBm). + * When the system starts up or reboots, the default TX power level will be used, which is + * the maximum value of 8dBm. Once this command is given, the output power will be changed + * instantly, regardless if there is Bluetooth communication going on or not. For example, + * for debugging purpose, the BlueNRG can be set to advertise all the time and use this + * command to observe the signal strength changing. The system will keep the last received + * TX power level from the command, i.e. the 2nd command overwrites the previous TX power + * level. The new TX power level remains until another Set TX Power command, or the system + * reboots.\n + * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the + * right value, depending on the selected hardware configuration for the RF network: + * normal mode or high power mode. + * @param pa_level Can be from 0 to 7. Set the PA level value. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +/** + * @brief This command returns the number of packets sent in Direct Test Mode. + * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets + * have been transmitted. This command can be used to check how many packets have been sent + * during the Direct TX test.\n + * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again. + * The counter is not cleared until the next Direct TX test starts. + * @param[out] number_of_packets Number of packets sent during the last Direct TX test. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets); + +/** + * @brief Put the device in standby mode. + * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the + * device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode, + * the device can still wake up itself with the internal timer. But in standby mode, this timer is + * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command + * sent via SPI bus. + * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code + * ERR_COMMAND_DISALLOWED will be returned. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_device_standby(void); + +/** + * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. + * @note The frequency sine wave at the specific channel may be used for test purpose only. + * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. + * This command shouldn't be used when normal Bluetooth activities are ongoing. + * The tone should be stopped by aci_hal_tone_stop() command. + * + * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the + * channel central frequency minus 250 kHz. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +/** + * This command is used to stop the previously started aci_hal_tone_start() command. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_stop(void); + +/** + * @brief This command returns the status of all the connections. + * @note This command returns the status of the 8 Bluetooth low energy links managed by the device. + * @param[out] link_status Array of link status (8 links). See @ref Link_Status. + * @param[out] conn_handle Array of connection handles for each link. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]); + +/** + * @brief This command returns the anchor period and the largest available slot. + * @note This command returns information about the anchor period to help application in selecting + * slot timings when operating in multi-link scenarios. + * @param anchor_period Current anchor period (multiple of 0.625 ms). + * @param max_free_slot Maximum available time (multiple of 0.625 ms) that can be allocated for a new slot. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot); + +/** + * @} + */ + +/** + * @defgroup HAL_Events HAL events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_HAL_INITIALIZED (0x0001) +typedef __packed struct _evt_hal_initialized{ + uint8_t reason_code; /**< Reset reason. See @ref Reset_Reasons */ +} PACKED evt_hal_initialized; + +/** + * This event is generated when an overflow occurs in the event queue read by the external microcontroller. + * This is normally caused when the external microcontroller does not read pending events. + * The returned bitmap indicates which event has been lost. Please note that one bit set to 1 indicates one or + * more occurrences of the particular events. The event EVT_BLUE_HAL_EVENTS_LOST cannot be lost and it will + * be inserted in the event queue as soon as a position is freed in the event queue. This event should not + * happen under normal operating condition where external microcontroller promptly reads events signaled by + * IRQ pin. It is provided to detected unexpected behavior of the external microcontroller or to allow + * application to recover situations where critical events are lost. + */ +#define EVT_BLUE_HAL_EVENTS_LOST_IDB05A1 (0x0002) +typedef __packed struct _evt_hal_events_lost{ + uint8_t lost_events[8]; /**< Bitmap of lost events. Each bit indicates one or more occurrences of the specific event. See @ref Lost_Events */ +} PACKED evt_hal_events_lost_IDB05A1; + + +/** + * This event is given to the application after the @ref ACI_BLUE_INITIALIZED_EVENT + * when a system crash is detected. This events returns system crash information for debugging purposes. + * Information reported are useful to understand the root cause of the crash. + */ +#define EVT_BLUE_HAL_CRASH_INFO_IDB05A1 (0x0003) +typedef __packed struct _evt_hal_crash_info{ + uint8_t crash_type; /**< Type of crash: Assert failed (0), NMI Fault (1), Hard Fault (2) */ + uint32_t sp; /**< SP register */ + uint32_t r0; /**< R0 register */ + uint32_t r1; /**< R1 register */ + uint32_t r2; /**< R2 register */ + uint32_t r3; /**< R3 register */ + uint32_t r12; /**< R12 register */ + uint32_t lr; /**< LR register */ + uint32_t pc; /**< PC register */ + uint32_t xpsr; /**< xPSR register */ + uint8_t debug_data_len; /**< length of debug_data field */ + uint8_t debug_data[VARIABLE_SIZE]; /**< Debug data */ +} PACKED evt_hal_crash_info_IDB05A1; + + +/** + * @} + */ + + +/** + * @anchor Reset_Reasons + * @name Reset Reasons + * See @ref EVT_BLUE_HAL_INITIALIZED. + * @{ + */ +#define RESET_NORMAL 1 /**< Normal startup. */ +#define RESET_UPDATER_ACI 2 /**< Updater mode entered with ACI command */ +#define RESET_UPDATER_BAD_FLAG 3 /**< Updater mode entered due to a bad BLUE flag */ +#define RESET_UPDATER_PIN 4 /**< Updater mode entered with IRQ pin */ +#define RESET_WATCHDOG 5 /**< Reset caused by watchdog */ +#define RESET_LOCKUP 6 /**< Reset due to lockup */ +#define RESET_BROWNOUT 7 /**< Brownout reset */ +#define RESET_CRASH 8 /**< Reset caused by a crash (NMI or Hard Fault) */ +#define RESET_ECC_ERR 9 /**< Reset caused by an ECC error */ +/** + * @} + */ + + +/** + * @defgroup Config_vals Offsets and lengths for configuration values. + * @brief Offsets and lengths for configuration values. + * See aci_hal_write_config_data(). + * @{ + */ + +/** + * @name Configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ +#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ +#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ +#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ +#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. + It can be written only if aci_hal_write_config_data() is the first command after reset. */ +#define CONFIG_DATA_RANDOM_ADDRESS (0x80) /**< Stored static random address. Read-only. */ + +/** + * Select the BlueNRG mode configurations.\n + * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) + * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) + * @li Mode 3: master/slave, 8 connections, RAM1 and RAM2. + * @li Mode 4: master/slave, 4 connections, RAM1 and RAM2 simultaneous scanning and advertising. + */ +#define CONFIG_DATA_MODE_OFFSET (0x2D) + +#define CONFIG_DATA_WATCHDOG_DISABLE (0x2F) /**< Set to 1 to disable watchdog. It is enabled by default. */ +/** + * @} + */ + +/** + * @name Length for configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_LEN (6) +#define CONFIG_DATA_DIV_LEN (2) +#define CONFIG_DATA_ER_LEN (16) +#define CONFIG_DATA_IR_LEN (16) +#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) +#define CONFIG_DATA_MODE_LEN (1) +#define CONFIG_DATA_WATCHDOG_DISABLE_LEN (1) +/** + * @} + */ + +/** + * @anchor Link_Status + * @name Status of the link + * See @ref aci_hal_get_link_status(). + * @{ + */ +#define STATUS_IDLE 0 +#define STATUS_ADVERTISING 1 +#define STATUS_CONNECTED_AS_SLAVE 2 +#define STATUS_SCANNING 3 +#define STATUS_CONNECTED_AS_MASTER 5 +#define STATUS_TX_TEST 6 +#define STATUS_RX_TEST 7 +/** + * @} + */ + +/** + * @} + */ + + /** + * @anchor Lost_Events + * @name Lost events bitmap + * See @ref EVT_BLUE_HAL_EVENTS_LOST. + * @{ + */ +#define EVT_DISCONN_COMPLETE_BIT 0 +#define EVT_ENCRYPT_CHANGE_BIT 1 +#define EVT_READ_REMOTE_VERSION_COMPLETE_BIT 2 +#define EVT_CMD_COMPLETE_BIT 3 +#define EVT_CMD_STATUS_BIT 4 +#define EVT_HARDWARE_ERROR_BIT 5 +#define EVT_NUM_COMP_PKTS_BIT 6 +#define EVT_ENCRYPTION_KEY_REFRESH_BIT 7 +#define EVT_BLUE_HAL_INITIALIZED_BIT 8 +#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE_BIT 9 +#define EVT_BLUE_GAP_PAIRING_CMPLT_BIT 10 +#define EVT_BLUE_GAP_PASS_KEY_REQUEST_BIT 11 +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST_BIT 12 +#define EVT_BLUE_GAP_SECURITY_REQ_INITIATED_BIT 13 +#define EVT_BLUE_GAP_BOND_LOST_BIT 14 +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE_BIT 15 +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_BIT 16 +#define EVT_BLUE_L2CAP_CONN_UPDATE_RESP_BIT 17 +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT_BIT 18 +#define EVT_BLUE_L2CAP_CONN_UPDATE_REQ_BIT 19 +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_BIT 20 +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT_BIT 21 +#define EVT_BLUE_EXCHANGE_MTU_RESP_BIT 22 +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP_BIT 23 +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP_BIT 24 +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP_BIT 25 +#define EVT_BLUE_ATT_READ_RESP_BIT 26 +#define EVT_BLUE_ATT_READ_BLOB_RESP_BIT 27 +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP_BIT 28 +#define EVT_BLUE_ATT_READ_BY_GROUP_RESP_BIT 29 +#define EVT_BLUE_ATT_WRITE_RESP_BIT 30 +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP_BIT 31 +#define EVT_BLUE_ATT_EXEC_WRITE_RESP_BIT 32 +#define EVT_BLUE_GATT_INDICATION_BIT 33 +#define EVT_BLUE_GATT_NOTIFICATION_BIT 34 +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE_BIT 35 +#define EVT_BLUE_GATT_ERROR_RESP_BIT 36 +#define EVT_BLUE_GATT_DISC_READ_CHARAC_BY_UUID_RESP_BIT 37 +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ_BIT 38 +#define EVT_BLUE_GATT_READ_PERMIT_REQ_BIT 39 +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ_BIT 40 +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_BIT 41 +#define EVT_BLUE_GATT_SERVER_RX_CONFIRMATION_BIT 42 +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ_BIT 43 +#define EVT_LL_CONNECTION_COMPLETE_BIT 44 +#define EVT_LL_ADVERTISING_REPORT_BIT 45 +#define EVT_LL_CONNECTION_UPDATE_COMPLETE_BIT 46 +#define EVT_LL_READ_REMOTE_USED_FEATURES_BIT 47 +#define EVT_LL_LTK_REQUEST_BIT 48 +/** + * @} + */ + +/** + * @name Hardware error event codes + * See @ref EVT_HARDWARE_ERROR. + * @{ + */ +/** + * Error on the SPI bus has been detected, most likely caused by incorrect SPI configuration on the external micro-controller. + */ +#define SPI_FRAMING_ERROR 0 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define RADIO_STATE_ERROR 1 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define TIMER_OVERRUN_ERROR 2 + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,166 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_l2cap_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with L2CAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_L2CAP_ACI_H__ +#define __BLUENRG_L2CAP_ACI_H__ + +/** + *@addtogroup L2CAP L2CAP + *@brief L2CAP layer. + *@{ + */ + +/** + *@defgroup L2CAP_Functions L2CAP functions + *@brief API for L2CAP layer. + *@{ + */ + +/** + * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. + * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request + * (accepts or rejects). + * @param conn_handle Connection handle on which the connection parameter update request has to be sent. + * @param interval_min Defines minimum value for the connection event interval in the following manner: + * connIntervalMin = interval_min x 1.25ms + * @param interval_max Defines maximum value for the connection event interval in the following manner: + * connIntervalMax = interval_max x 1.25ms + * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). + * @param timeout_multiplier Defines connection timeout parameter in the following manner: + * timeout_multiplier x 10ms. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier); +/** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param min_ce_length Minimum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_ce_length Maximum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept); + /** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept); + +/** + * @} + */ + +/** + * @defgroup L2CAP_Events L2CAP events + * @{ + */ + +/** + * This event is generated when the master responds to the L2CAP connection update request packet. + * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. + */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef __packed struct _evt_l2cap_conn_upd_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ +/** + * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. + * @li 0x01 in case of Command Reject. + */ + uint8_t code; + uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ + uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ +/** + * Result code (parameters accepted or rejected) in case of Connection Parameter Update + * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). + */ + uint16_t result; +} PACKED evt_l2cap_conn_upd_resp; + +/** + * This event is generated when the master does not respond to the connection update request + * within 30 seconds. + */ +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) +typedef __packed struct _evt_l2cap_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */ +} PACKED evt_l2cap_procedure_timeout; + +/** + * The event is given by the L2CAP layer when a connection update request is received from the slave. + * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). + */ +#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) +typedef __packed struct _evt_l2cap_conn_upd_req{ +/** + * Handle of the connection for which the connection update request has been received. + * The same handle has to be returned while responding to the event with the command + * aci_l2cap_connection_parameter_update_response(). + */ + uint16_t conn_handle; + uint8_t event_data_length; /**< Length of following data. */ +/** + * This is the identifier which associates the request to the + * response. The same identifier has to be returned by the upper + * layer in the command aci_l2cap_connection_parameter_update_response(). + */ + uint8_t identifier; + uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ + uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ +} PACKED evt_l2cap_conn_upd_req; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_updater_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with updater commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_UPDATER_ACI_H__ +#define __BLUENRG_UPDATER_ACI_H__ + +#include <ble_compiler.h> + +/** + * @defgroup Updater Updater + * @brief Updater. + * @{ + */ + +/** + * @defgroup Updater_Functions Updater functions + * @brief API for BlueNRG Updater. + * @{ + */ + +tBleStatus aci_updater_start(void); + +tBleStatus aci_updater_reboot(void); + +tBleStatus aci_get_updater_version(uint8_t *version); + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); + +tBleStatus aci_erase_blue_flag(void); + +tBleStatus aci_reset_blue_flag(void); + +tBleStatus aci_updater_erase_sector(uint32_t address); + +tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); + +tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); + +tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); + +tBleStatus aci_updater_hw_version(uint8_t *version); + +/** + * @} + */ + +/** + * @defgroup Updater_Events Updater events + * @{ + */ +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_INITIALIZED (0x0001) +typedef __packed struct _evt_blue_initialized{ + uint8_t reason_code; +} PACKED evt_blue_initialized; +/** + * @} + */ + +/** + * @} + */ + + + +#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,204 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_utils.h +* Author : AMS - VMA, RF Application Team +* Version : V1.0.1 +* Date : 03-October-2014 +* Description : Header file for BlueNRG utility functions +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + * @file bluenrg_utils.h + * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description + * + * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> +**/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLUENRG_UTILS_H +#define __BLUENRG_UTILS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ble_hal_types.h" +#include "ble_compiler.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct{ + uint8_t stack_mode; + uint8_t day; + uint8_t month; + uint8_t year; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint16_t hs_startup_time; /* In system time units*/ +} IFR_config2_TypeDef; + +/** + * Structure inside IFR for configuration options. + */ +typedef __packed struct{ + uint8_t cold_ana_act_config_table[64]; + uint8_t hot_ana_config_table[64]; + uint8_t stack_mode; + uint8_t gpio_config; + uint8_t rsrvd1[2]; + uint32_t rsrvd2[3]; + uint32_t max_conn_event_time; + uint32_t ls_crystal_period; + uint32_t ls_crystal_freq; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint8_t rsrvd3; + uint16_t hs_startup_time; /* In system time units*/ + uint8_t rsrvd4[2]; + uint32_t uid; + uint8_t rsrvd5; + uint8_t year; + uint8_t month; + uint8_t day; + uint32_t unused[5]; +} PACKED IFR_config_TypeDef; + +/* Exported constants --------------------------------------------------------*/ +extern const IFR_config_TypeDef IFR_config; + +/* Exported macros -----------------------------------------------------------*/ +#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)+1) +#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) + +/* Convert 2 digit BCD number to an integer */ +#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) + +/* Convert 2 digit number to a BCD number */ +#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) + +/** + * Return values + */ +#define BLE_UTIL_SUCCESS 0 +#define BLE_UTIL_UNSUPPORTED_VERSION 1 +#define BLE_UTIL_WRONG_IMAGE_SIZE 2 +#define BLE_UTIL_ACI_ERROR 3 +#define BLE_UTIL_CRC_ERROR 4 +#define BLE_UTIL_PARSE_ERROR 5 +#define BLE_UTIL_WRONG_VERIFY 6 + +/* Exported functions ------------------------------------------------------- */ +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int program_device(const uint8_t *fw_image, uint32_t fw_size); + +/** + * @brief Read raw data from IFR (3 64-bytes blocks). + * @param data Pointer to the buffer that will contain the read data. + * Its size must be 192 bytes. This data can be parsed by + * parse_IFR_data_config(). + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION) + */ +int read_IFR(uint8_t data[192]); + +/** + * @brief Verify raw data from IFR (3 64-bytes blocks). + * @param ifr_data Pointer to the buffer that will contain the data to verify. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) + */ +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); + +/** + * @brief Program raw data to IFR (3 64-bytes blocks). + * @param ifr_image Pointer to the buffer that will contain the data to program. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful + */ +int program_IFR(const IFR_config_TypeDef *ifr_image); + +/** + * @brief Parse IFR raw data. + * @param data Pointer to the raw data: last 64 bytes read from IFR sector. + * @param IFR_config Data structure that will be filled with parsed data. + * @retval None + */ +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); + +/** + * @brief Check for the correctness of parsed data. + * @param IFR_config Data structure filled with parsed data. + * @retval int It returns 0 if successful, or PARSE_ERROR in case data is + * not correct. + */ +int IFR_validate(IFR_config2_TypeDef *IFR_config); + +/** + * @brief Modify IFR data. (Last 64-bytes block). + * @param IFR_config Structure that contains the new parameters inside the + * IFR configuration data. + * @note It is highly recommended to parse the IFR configuration from + * a working IFR block (this should be done with parse_IFR_data_config()). + * Then it is possible to write the new parameters inside the IFR_config + * structure. + * @param data Pointer to the buffer that contains the original data. It + * will be modified according to the new data in the IFR_config + * structure. Then this data must be written in the last + * 64-byte block in the IFR. + * Its size must be 64 bytes. + * @retval None + */ +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); + +/** + * @brief Get BlueNRG hardware and firmware version + * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). + * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN + * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. + * @retval Status of the call + */ +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); + +/** + * @brief Get BlueNRG updater version + * @param version This parameter returns the updater version. If the updadter version is 0x03 + * the chip has the updater old, needs to update the bootloader. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterVersion(uint8_t *version); + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version); + +/** + * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on + * the HW bootloader related to the 32 MHz external crystal oscillator. + * @retval TRUE if the HW bootloader is already patched, FALSE otherwise + */ +uint8_t isHWBootloader_Patched(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__BLUENRG_UTILS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file bluenrg_targets.h + * @author AST / EST + * @version V0.0.1 + * @date 24-July-2015 + * @brief This header file is intended to manage the differences between + * the different supported base-boards which might mount the + * X_NUCLEO_IDB0XA1 BlueNRG BLE Expansion Board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent from recursive inclusion --------------------------------*/ +#ifndef _BLUENRG_TARGETS_H_ +#define _BLUENRG_TARGETS_H_ + +#if !defined(BLUENRG_PIN_SPI_MOSI) +#define BLUENRG_PIN_SPI_MOSI (D11) +#endif +#if !defined(BLUENRG_PIN_SPI_MISO) +#define BLUENRG_PIN_SPI_MISO (D12) +#endif +#if !defined(BLUENRG_PIN_SPI_nCS) +#define BLUENRG_PIN_SPI_nCS (A1) +#endif +#if !defined(BLUENRG_PIN_SPI_RESET) +#define BLUENRG_PIN_SPI_RESET (D7) +#endif +#if !defined(BLUENRG_PIN_SPI_IRQ) +#define BLUENRG_PIN_SPI_IRQ (A0) +#endif + +/* NOTE: Refer to README for further details regarding BLUENRG_PIN_SPI_SCK */ +#if !defined(BLUENRG_PIN_SPI_SCK) +#define BLUENRG_PIN_SPI_SCK (D3) +#endif + +/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv) + * Mode 0x01: slave or master, 1 connection + * Mode 0x02: slave or master, 1 connection + * Mode 0x03: master/slave, 8 connections + * Mode 0x04: master/slave, 4 connections (simultaneous scanning and advertising) + * Check Table 285 of + * BlueNRG-MS Bluetooth LE stack application command interface (ACI) User Manual (UM1865) at st.com + */ +#if !defined(BLUENRG_STACK_MODE) +#define BLUENRG_STACK_MODE (0x04) +#endif + +#endif // _BLUENRG_TARGTES_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef _BTLE_H_ +#define _BTLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "bluenrg_aci.h" +#include "ble_hci_const.h" +#include "bluenrg_hal_aci.h" +#include "stm32_bluenrg_ble.h" +#include "bluenrg_gap.h" +#include "bluenrg_gatt_server.h" + +extern uint16_t g_gap_service_handle; +extern uint16_t g_appearance_char_handle; +extern uint16_t g_device_name_char_handle; +extern uint16_t g_preferred_connection_parameters_char_handle; + +void btleInit(void); +void SPI_Poll(void); +void User_Process(void); +void setConnectable(void); +void setVersionString(uint8_t hwVersion, uint16_t fwVersion); +const char* getVersionString(void); +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type); + + +extern int btle_handler_pending; +extern void btle_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.h + * @author CL + * @version V1.0.1 + * @date 15-June-2014 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_BLUENRG_BLE_H +#define __STM32_BLUENRG_BLE_H + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdint.h> +#include "ble_gp_timer.h" +#include "ble_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup X-NUCLEO-IDB04A1 + * @{ + */ + +/** @addtogroup STM32_BLUENRG_BLE + * @{ + */ + +/** @defgroup STM32_BLUENRG_BLE_Exported_Functions + * @{ + */ + +// FIXME: add prototypes for BlueNRG here +void BlueNRG_RST(void); +uint8_t BlueNRG_DataPresent(void); +void BlueNRG_HW_Bootloader(void); +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size); +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, + uint8_t Nb_bytes1, + uint8_t Nb_bytes2); +void Clear_SPI_EXTI_Flag(void); + +void print_csv_time(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_BLUENRG_BLE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_debug.h" + +#ifndef __PAYLOAD_H__ +#define __PAYLOAD_H__ + +class UnitPayload +{ +public: + uint8_t length; + uint8_t id; + uint8_t *data; + uint8_t *idptr; + + + + void set_length(uint8_t l) { + length=l; + } + + void set_id(uint8_t i) { + id=i; + } + + void set_data(uint8_t* data1) { + for(int j=0;j<length;j++) + { + data[j]=data1[j]; + } + } + + uint8_t get_length() { + return length; + } + + uint8_t get_id() { + return id; + } + + uint8_t* get_data() { + return data; + } + +}; + +class Payload { + UnitPayload *payload; + int stringLength; + int payloadUnitCount; + +public: + Payload(const uint8_t *tokenString, uint8_t string_ength); + Payload(); + ~Payload(); + uint8_t getPayloadUnitCount(); + + uint8_t getIDAtIndex(int index); + uint8_t getLengthAtIndex(int index); + uint8_t* getDataAtIndex(int index); + int8_t getInt8AtIndex(int index); + uint16_t getUint16AtIndex(int index); + uint8_t* getSerializedAdDataAtIndex(int index); +}; + + +class PayloadUnit { +private: + uint8_t* lenPtr; + uint8_t* adTypePtr; + uint8_t* dataPtr; + +public: + PayloadUnit() { + lenPtr = NULL; + adTypePtr = NULL; + dataPtr = NULL; + } + + PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { + lenPtr = len; + adTypePtr = adType; + dataPtr = data; + } + + void setLenPtr(uint8_t *len) { + lenPtr = len; + } + + void setAdTypePtr(uint8_t *adType) { + adTypePtr = adType; + } + + void setDataPtr(uint8_t *data) { + dataPtr = data; + } + + uint8_t* getLenPtr() { + return lenPtr; + } + + uint8_t* getAdTypePtr() { + return adTypePtr; + } + + uint8_t* getDataPtr() { + return dataPtr; + } + + void printDataAsHex() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("0x%x ", dataPtr[i]); + } + PRINTF("\n"); + } + + void printDataAsString() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("%c", dataPtr[i]); + } + PRINTF("\n"); + } + +}; + +class PayloadPtr { +private: + PayloadUnit *unit; + int payloadUnitCount; +public: + PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + int stringLength = string_ength; + payloadUnitCount = 0; + + int index = 0; + while(index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + // allocate memory to unit + unit = new PayloadUnit[payloadUnitCount]; + int i = 0; + int nextUnitOffset = 0; + + while(i<payloadUnitCount) { + unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); + unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); + unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); + + nextUnitOffset += *unit[i].getLenPtr()+1; + i++; + + } + } + + PayloadUnit getUnitAtIndex(int index) { + return unit[index]; + } + + int getPayloadUnitCount() { return payloadUnitCount; } + + ~PayloadPtr() { + if(unit) delete[] unit; + + unit = NULL; + } +}; + +#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include "ble_status.h" +#include "ble_hal_types.h" + +#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do {\ + uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ + }while(0) + + +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); + +#endif // __UTIL_H__ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/mbed_lib.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "bluenrg", + "target_overrides": { + "K64F": { + "target.macros_add": ["BLUENRG_PIN_SPI_SCK=D13"] + }, + "DISCO_L475VG_IOT01A": { + "target.macros_add": ["BLUENRG_PIN_SPI_MOSI=PC_12", + "BLUENRG_PIN_SPI_MISO=PC_11", + "BLUENRG_PIN_SPI_nCS=PD_13", + "BLUENRG_PIN_SPI_RESET=PA_8", + "BLUENRG_PIN_SPI_IRQ=PE_6", + "BLUENRG_PIN_SPI_SCK=PC_10"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,37 @@ +{ + "name": "x-nucleo-idb0xa1", + "version": "2.2.0", + "description": "ST driver for the mbed BLE API.", + "keywords": [ + "expansion", + "board", + "x-nucleo", + "nucleo", + "ST", + "STM", + "Bluetooth", + "BLE" + ], + "author": "Andrea Palmieri", + "repository": { + "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git", + "type": "git" + }, + "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "extraIncludes": [ + "x-nucleo-idb0xa1", + "x-nucleo-idb0xa1/utils", + "x-nucleo-idb0xa1/platform", + "x-nucleo-idb0xa1/bluenrg-hci" + ], + "dependencies": { + "mbed-drivers": ">=0.11.3", + "ble": "^2.7.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,474 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.cpp + * @author STMicroelectronics + * @brief Implementation of BLEDeviceInstanceBase + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGDevice + * @brief BlueNRG BLE_API Device Adaptation + * @{ + */ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGDevice.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" + +#include "btle.h" +#include "ble_utils.h" +#include "ble_osal.h" + +#include "ble_debug.h" +#include "stm32_bluenrg_ble.h" + +extern "C" { + #include "ble_hci.h" + #include "bluenrg_utils.h" +} + +#define HEADER_SIZE 5 +#define MAX_BUFFER_SIZE 255 + +/** + * The singleton which represents the BlueNRG transport for the BLEDevice. + * + * See file 'bluenrg_targets.h' for details regarding the peripheral pins used! + */ +#include "bluenrg_targets.h" + +BlueNRGDevice bluenrgDeviceInstance(BLUENRG_PIN_SPI_MOSI, + BLUENRG_PIN_SPI_MISO, + BLUENRG_PIN_SPI_SCK, + BLUENRG_PIN_SPI_nCS, + BLUENRG_PIN_SPI_RESET, + BLUENRG_PIN_SPI_IRQ); + +/** +* BLE-API requires an implementation of the following function in order to +* obtain its transport handle. +*/ +BLEInstanceBase * +createBLEInstance(void) +{ + return (&bluenrgDeviceInstance); +} + +/**************************************************************************/ +/** + @brief Constructor + * @param mosi mbed pin to use for MOSI line of SPI interface + * @param miso mbed pin to use for MISO line of SPI interface + * @param sck mbed pin to use for SCK line of SPI interface + * @param cs mbed pin to use for not chip select line of SPI interface + * @param rst mbed pin to use for BlueNRG reset + * @param irq mbed pin for BlueNRG IRQ +*/ +/**************************************************************************/ +BlueNRGDevice::BlueNRGDevice(PinName mosi, + PinName miso, + PinName sck, + PinName cs, + PinName rst, + PinName irq) : + isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq) +{ + // Setup the spi for 8 bit data, low clock polarity, + // 1-edge phase, with an 8MHz clock rate + spi_.format(8, 0); + spi_.frequency(8000000); + + // Deselect the BlueNRG chip by keeping its nCS signal high + nCS_ = 1; + + wait_us(500); + + // Prepare communication between the host and the BlueNRG SPI interface + HCI_Init(); + + // Set the interrupt handler for the device + irq_.mode(PullDown); // set irq mode + irq_.rise(&HCI_Isr); +} + +/**************************************************************************/ +/** + @brief Destructor +*/ +/**************************************************************************/ +BlueNRGDevice::~BlueNRGDevice(void) +{ +} + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param hw_version The HW version is written to this parameter + * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise + */ +uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version) +{ + uint8_t status; + + status = getBlueNRGUpdaterHWVersion(hw_version); + + return (status); +} + +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns BLE_STATUS_SUCCESS on success, or a number + * not equal to 0 in case of error + * (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size) +{ + int status = program_device(fw_image, fw_size); + + return (status); +} + + +/** + * @brief Initialises anything required to start using BLE + * @param[in] instanceID + * The ID of the instance to initialize. + * @param[in] callback + * A callback for when initialization completes for a BLE + * instance. This is an optional parameter set to NULL when not + * supplied. + * + * @return BLE_ERROR_NONE if the initialization procedure was started + * successfully. + */ +ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback) +{ + if (isInitialized) { + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_ALREADY_INITIALIZED + }; + callback.call(&context); + return BLE_ERROR_ALREADY_INITIALIZED; + } + + // Init the BlueNRG/BlueNRG-MS stack + btleInit(); + + isInitialized = true; + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_NONE + }; + callback.call(&context); + + return BLE_ERROR_NONE; +} + + +/** + @brief Resets the BLE HW, removing any existing services and + characteristics + @param[in] void + @returns void +*/ +void BlueNRGDevice::reset(void) +{ + /* Reset BlueNRG SPI interface. Hold reset line to 0 for 1500us */ + rst_ = 0; + wait_us(1500); + rst_ = 1; + + /* Wait for the radio to come back up */ + wait_us(5000); +} + +/*! + @brief Wait for any BLE Event like BLE Connection, Read Request etc. + @param[in] void + @returns char * +*/ +void BlueNRGDevice::waitForEvent(void) +{ + bool must_return = false; + + do { + bluenrgDeviceInstance.processEvents(); + + if(must_return) return; + + __WFE(); /* it is recommended that SEVONPEND in the + System Control Register is NOT set */ + must_return = true; /* after returning from WFE we must guarantee + that conrol is given back to main loop before next WFE */ + } while(true); + +} + +/*! + @brief get GAP version + @brief Get the BLE stack version information + @param[in] void + @returns char * + @returns char * +*/ +const char *BlueNRGDevice::getVersion(void) +{ + return getVersionString(); +} + +/**************************************************************************/ +/*! + @brief get reference to GAP object + @param[in] void + @returns Gap& +*/ +/**************************************************************************/ +Gap &BlueNRGDevice::getGap() +{ + return BlueNRGGap::getInstance(); +} + +const Gap &BlueNRGDevice::getGap() const +{ + return BlueNRGGap::getInstance(); +} + +/**************************************************************************/ +/*! + @brief get reference to GATT server object + @param[in] void + @returns GattServer& +*/ +/**************************************************************************/ +GattServer &BlueNRGDevice::getGattServer() +{ + return BlueNRGGattServer::getInstance(); +} + +const GattServer &BlueNRGDevice::getGattServer() const +{ + return BlueNRGGattServer::getInstance(); +} + +/**************************************************************************/ +/*! + @brief shut down the BLE device + @param[out] error if any +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::shutdown(void) { + PRINTF("BlueNRGDevice::reset\n"); + + if (!isInitialized) { + return BLE_ERROR_INITIALIZATION_INCOMPLETE; + } + + /* Reset the BlueNRG device first */ + reset(); + + /* Shutdown the BLE API and BlueNRG glue code */ + ble_error_t error; + + /* GattServer instance */ + error = BlueNRGGattServer::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* GattClient instance */ + error = BlueNRGGattClient::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* Gap instance */ + error = BlueNRGGap::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + isInitialized = false; + + PRINTF("BlueNRGDevice::reset complete\n"); + return BLE_ERROR_NONE; + +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size) +{ + uint16_t byte_count; + uint8_t len = 0; + uint8_t char_ff = 0xff; + volatile uint8_t read_char; + + uint8_t i = 0; + volatile uint8_t tmpreg; + + uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00}; + uint8_t header_slave[HEADER_SIZE]; + + /* Select the chip */ + nCS_ = 0; + + /* Read the header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = (uint8_t)(tmpreg); + } + + if (header_slave[0] == 0x02) { + /* device is ready */ + byte_count = (header_slave[4]<<8)|header_slave[3]; + + if (byte_count > 0) { + + /* avoid to read more data that size of the buffer */ + if (byte_count > buff_size){ + byte_count = buff_size; + } + + for (len = 0; len < byte_count; len++){ + read_char = spi_.write(char_ff); + buffer[len] = read_char; + } + } + } + /* Release CS line to deselect the chip */ + nCS_ = 1; + + // Add a small delay to give time to the BlueNRG to set the IRQ pin low + // to avoid a useless SPI read at the end of the transaction + for(volatile int i = 0; i < 2; i++)__NOP(); + +#ifdef PRINT_CSV_FORMAT + if (len > 0) { + print_csv_time(); + for (int i=0; i<len; i++) { + PRINT_CSV(" %02x", buffer[i]); + } + PRINT_CSV("\n"); + } +#endif + + return len; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRGDevice::spiWrite(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t result = 0; + uint32_t i; + volatile uint8_t tmpreg; + + unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00}; + + disable_irq(); + + /* CS reset */ + nCS_ = 0; + + /* Exchange header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = tmpreg; + } + + if (header_slave[0] == 0x02) { + /* SPI is ready */ + if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { + + /* Buffer is big enough */ + for (i = 0; i < Nb_bytes1; i++) { + spi_.write(*(data1 + i)); + } + for (i = 0; i < Nb_bytes2; i++) { + spi_.write(*(data2 + i)); + } + } else { + /* Buffer is too small */ + result = -2; + } + } else { + /* SPI is not ready */ + result = -1; + } + + /* Release CS line */ + //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); + nCS_ = 1; + + enable_irq(); + + return result; +} + +bool BlueNRGDevice::dataPresent() +{ + return (irq_ == 1); +} + +void BlueNRGDevice::disable_irq() +{ + irq_.disable_irq(); +} + +void BlueNRGDevice::enable_irq() +{ + irq_.enable_irq(); +} + +void BlueNRGDevice::processEvents() { + btle_handler(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,68 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattClient.h" + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + uuid = uuidIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + + void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) { + lastHandle = lastHandleIn; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1477 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file BlueNRGGap.cpp + * @author STMicroelectronics + * @brief Implementation of BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGap + * @brief BlueNRG BLE_API GAP Adaptation + * @{ + */ + +#include "BlueNRGDevice.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_payload.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/* + * Utility to process GAP specific events (e.g., Advertising timeout) + */ +void BlueNRGGap::Process(void) +{ + if(AdvToFlag) { + AdvToFlag = false; + stopAdvertising(); + } + + if(ScanToFlag) { + ScanToFlag = false; + stopScan(); + } +} + +/**************************************************************************/ +/*! + @brief Sets the advertising parameters and payload for the device. + Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API + + @params[in] advData + The primary advertising data payload + @params[in] scanResponse + The optional Scan Response payload if the advertising + type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED + in \ref GapAdveritinngParams + + @returns \ref ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @retval BLE_ERROR_BUFFER_OVERFLOW + The proposed action would cause a buffer overflow. All + advertising payloads must be <= 31 bytes, for example. + + @retval BLE_ERROR_NOT_IMPLEMENTED + A feature was requested that is not yet supported in the + nRF51 firmware or hardware. + + @retval BLE_ERROR_PARAM_OUT_OF_RANGE + One of the proposed values is outside the valid range. + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) +{ + PRINTF("BlueNRGGap::setAdvertisingData\n\r"); + /* Make sure we don't exceed the advertising payload length */ + if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + PRINTF("Exceeded the advertising payload length\n\r"); + return BLE_ERROR_BUFFER_OVERFLOW; + } + + /* Make sure we have a payload! */ + if (advData.getPayloadLen() != 0) { + PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); + + /* Align the GAP Service Appearance Char value coherently + This setting is duplicate (see below GapAdvertisingData::APPEARANCE) + since BLE API has an overloaded function for appearance + */ + STORE_LE_16(deviceAppearance, advData.getAppearance()); + setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0])); + + + for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { + loadPtr.getUnitAtIndex(index); + + PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); + PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); + + switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { + /**< TX Power Level (in dBm) */ + case GapAdvertisingData::TX_POWER_LEVEL: + { + PRINTF("Advertising type: TX_POWER_LEVEL\n\r"); + int8_t enHighPower = 0; + int8_t paLevel = 0; + + int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); + tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); +#ifdef DEBUG + PRINTF("dbm=%d, ret=%d\n\r", dbm, ret); + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); +#endif + if(ret == BLE_STATUS_SUCCESS) { + aci_hal_set_tx_power_level(enHighPower, paLevel); + } + break; + } + /**< Appearance */ + case GapAdvertisingData::APPEARANCE: + { + PRINTF("Advertising type: APPEARANCE\n\r"); + + GapAdvertisingData::Appearance appearanceP; + memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2); + + PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]); + /* Align the GAP Service Appearance Char value coherently */ + setAppearance(appearanceP); + break; + } + + } // end switch + + } //end for + + } + + // update the advertising data in the shield if advertising is running + if (state.advertising == 1) { + tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS != ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload()); + if (ret) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + } + + _advData = advData; + _scanResponse = scanResponse; + + return BLE_ERROR_NONE; +} + +/* + * Utility to set ADV timeout flag + */ +void BlueNRGGap::setAdvToFlag(void) { + AdvToFlag = true; + signalEventsToProcess(); +} + +/* + * ADV timeout callback + */ +#ifdef AST_FOR_MBED_OS +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().stopAdvertising(); +} +#else +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().setAdvToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getAdvTimeout(); + t.detach(); /* disable the callback from the timeout */ +} +#endif /* AST_FOR_MBED_OS */ + +/* + * Utility to set SCAN timeout flag + */ +void BlueNRGGap::setScanToFlag(void) { + ScanToFlag = true; + signalEventsToProcess(); +} + +static void scanTimeoutCB(void) +{ + BlueNRGGap::getInstance().setScanToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getScanTimeout(); + t.detach(); /* disable the callback from the timeout */ +} + +/**************************************************************************/ +/*! + @brief Starts the BLE HW, initialising any services that were + added before this function was called. + + @param[in] params + Basic advertising details, including the advertising + delay, timeout and how the device should be advertised + + @note All services must be added before calling this function! + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ + +ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) +{ + tBleStatus ret; + int err; + + /* Make sure we support the advertising type */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { + /* ToDo: This requires a proper security implementation, etc. */ + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /* Check interval range */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { + /* Min delay is slightly longer for unconnectable devices */ + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } else { + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } + + /* Check timeout is zero for Connectable Directed */ + if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { + /* Timeout must be 0 with this type, although we'll never get here */ + /* since this isn't implemented yet anyway */ + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* Check timeout for other advertising types */ + if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && + (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* + * Advertising filter policy setting + * FIXME: the Security Manager should be implemented + */ + AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode(); + if(mode != ADV_POLICY_IGNORE_WHITELIST) { + ret = aci_gap_configure_whitelist(); + if(ret != BLE_STATUS_SUCCESS) { + PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret); + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } + + uint8_t advFilterPolicy = NO_WHITE_LIST_USE; + switch(mode) { + case ADV_POLICY_FILTER_SCAN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN; + break; + case ADV_POLICY_FILTER_CONN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN; + break; + case ADV_POLICY_FILTER_ALL_REQS: + advFilterPolicy = WHITE_LIST_FOR_ALL; + break; + default: + advFilterPolicy = NO_WHITE_LIST_USE; + break; + } + + /* Check the ADV type before setting scan response data */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED || + params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) { + + /* set scan response data */ + PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen()); + ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS!=ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + } else { + hci_le_set_scan_resp_data(0, NULL); + } + + setAdvParameters(); + PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType()); + + err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload()); + + if (err) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + + tBDAddr dummy_addr = { 0 }; + uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval; + uint16_t advIntervalMax = advIntervalMin + 1; + + err = hci_le_set_advertising_parameters( + advIntervalMin, + advIntervalMax, + params.getAdvertisingType(), + addr_type, + 0x00, + dummy_addr, + /* all channels */ 7, + advFilterPolicy + ); + + if (err) { + PRINTF("impossible to set advertising parameters\n\r"); + PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1); + PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy); + return BLE_ERROR_INVALID_PARAM; + } + + err = hci_le_set_advertise_enable(0x01); + if (err) { + PRINTF("impossible to start advertising\n\r"); + return BLE_ERROR_UNSPECIFIED; + } + + if(params.getTimeout() != 0) { + PRINTF("!!! attaching adv to!!!\n"); +#ifdef AST_FOR_MBED_OS + minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000)); +#else + advTimeout.attach(advTimeoutCB, params.getTimeout()); +#endif + } + + return BLE_ERROR_NONE; + +} + + +/**************************************************************************/ +/*! + @brief Stops the BLE HW and disconnects from any devices + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::stopAdvertising(void) +{ + if(state.advertising == 1) { + + int err = hci_le_set_advertise_enable(0); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + PRINTF("Advertisement stopped!!\n\r") ; + //Set GapState_t::advertising state + state.advertising = 0; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason) +{ + tBleStatus ret; + + ret = aci_gap_terminate(connectionHandle, reason); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_COMMAND_DISALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason) +{ + return disconnect(m_connectionHandle, reason); +} + +/**************************************************************************/ +/*! + @brief Sets the 16-bit connection handle + + @param[in] conn_handle + Connection Handle which is set in the Gap Instance + + @returns void +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionHandle(uint16_t conn_handle) +{ + m_connectionHandle = conn_handle; +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit connection handle + + @param[in] void + + @returns uint16_t + Connection Handle of the Gap Instance +*/ +/**************************************************************************/ +uint16_t BlueNRGGap::getConnectionHandle(void) +{ + return m_connectionHandle; +} + +/**************************************************************************/ +/*! + @brief Sets the BLE device address. SetAddress will reset the BLE + device and re-initialize BTLE. Will not start advertising. + + @param[in] type + Type of Address + + @param[in] address[6] + Value of the Address to be set + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address) +{ + if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if(type == BLEProtocol::AddressType::PUBLIC){ + tBleStatus ret = aci_hal_write_config_data( + CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + address + ); + if(ret != BLE_STATUS_SUCCESS) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } else if (type == BLEProtocol::AddressType::RANDOM_STATIC) { + // ensure that the random static address is well formed + if ((address[5] & 0xC0) != 0xC0) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // thanks to const correctness of the API ... + tBDAddr random_address = { 0 }; + memcpy(random_address, address, sizeof(random_address)); + int err = hci_le_set_random_address(random_address); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // It is not possible to get the bluetooth address when it is set + // store it locally in class data member + memcpy(bdaddr, address, sizeof(bdaddr)); + } else { + // FIXME random addresses are not supported yet + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + // if we're here then the address was correctly set + // commit it inside the addr_type + addr_type = type; + isSetAddress = true; + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Returns boolean if the address of the device has been set + or not + + @returns bool + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +bool BlueNRGGap::getIsSetAddress() +{ + return isSetAddress; +} + +/**************************************************************************/ +/*! + @brief Returns the address of the device if set + + @returns Pointer to the address if Address is set else NULL + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) +{ + uint8_t bdaddr[BDADDR_SIZE]; + uint8_t data_len_out; + + // precondition, check that pointers in input are valid + if (typeP == NULL || address == NULL) { + return BLE_ERROR_INVALID_PARAM; + } + + if (addr_type == BLEProtocol::AddressType::PUBLIC) { + tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr); + if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) { + return BLE_ERROR_UNSPECIFIED; + } + } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) { + // FIXME hci_read_bd_addr and + // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1 + // does not work, use the address stored in class data member + memcpy(bdaddr, this->bdaddr, sizeof(bdaddr)); + } else { + // FIXME: should be implemented with privacy features + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + *typeP = addr_type; + memcpy(address, bdaddr, BDADDR_SIZE); + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief obtains preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + + if (!g_preferred_connection_parameters_char_handle) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // Peripheral preferred connection parameters are an array of 4 uint16_t + uint8_t parameters_packed[parameter_size * 4]; + uint16_t bytes_read = 0; + + tBleStatus err = aci_gatt_read_handle_value( + g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE, + sizeof(parameters_packed), + &bytes_read, + parameters_packed + ); + + PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read); + + // check that the read succeed and the result have the expected length + if (err || bytes_read != sizeof(parameters_packed)) { + return BLE_ERROR_UNSPECIFIED; + } + + // memcpy field by field + memcpy(¶ms->minConnectionInterval, parameters_packed, parameter_size); + memcpy(¶ms->maxConnectionInterval, ¶meters_packed[parameter_size], parameter_size); + memcpy(¶ms->slaveLatency, ¶meters_packed[2 * parameter_size], parameter_size); + memcpy(¶ms->connectionSupervisionTimeout, ¶meters_packed[3 * parameter_size], parameter_size); + + return BLE_ERROR_NONE; +} + + +/**************************************************************************/ +/*! + @brief sets preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + uint8_t parameters_packed[parameter_size * 4]; + + // ensure that parameters are correct + // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC + if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) && + params->minConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) && + params->maxConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (params->slaveLatency > 0x01F3) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) && + params->connectionSupervisionTimeout != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // copy the parameters inside the byte array + memcpy(parameters_packed, ¶ms->minConnectionInterval, parameter_size); + memcpy(¶meters_packed[parameter_size], ¶ms->maxConnectionInterval, parameter_size); + memcpy(¶meters_packed[2 * parameter_size], ¶ms->slaveLatency, parameter_size); + memcpy(¶meters_packed[3 * parameter_size], ¶ms->connectionSupervisionTimeout, parameter_size); + + tBleStatus err = aci_gatt_update_char_value( + g_gap_service_handle, + g_preferred_connection_parameters_char_handle, + /* offset */ 0, + sizeof(parameters_packed), + parameters_packed + ); + + if (err) { + PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ; + switch (err) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief updates preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) +{ + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(gapRole == Gap::CENTRAL) { + ret = aci_gap_start_connection_update(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout, + CONN_L1, CONN_L2); + } else { + ret = aci_l2cap_connection_parameter_update_request(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout); + } + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case ERR_COMMAND_DISALLOWED: + case BLE_STATUS_NOT_ALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sets the Device Name Characteristic + + @param[in] deviceName + pointer to device name to be set + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) +{ + tBleStatus ret; + uint8_t nameLen = 0; + + nameLen = strlen((const char*)deviceName); + PRINTF("DeviceName Size=%d\n\r", nameLen); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_device_name_char_handle, + 0, + nameLen, + deviceName); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Gets the Device Name Characteristic + + @param[in] deviceName + pointer to device name + + @param[in] lengthP + pointer to device name length + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) +{ + tBleStatus ret; + + ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + *lengthP, + (uint16_t *)lengthP, + deviceName); + PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } +} + +/**************************************************************************/ +/*! + @brief Sets the Device Appearance Characteristic + + @param[in] appearance + device appearance + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance) +{ + tBleStatus ret; + uint8_t deviceAppearance[2]; + + STORE_LE_16(deviceAppearance, appearance); + PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_appearance_char_handle, + 0, 2, (uint8_t *)deviceAppearance); + if (BLE_STATUS_SUCCESS == ret){ + return BLE_ERROR_NONE; + } + + PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Gets the Device Appearance Characteristic + + @param[in] appearance + pointer to device appearance value + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) +{ + tBleStatus ret; + uint16_t lengthP = 2; + + ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + lengthP, + &lengthP, + (uint8_t*)appearanceP); + PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + +} + +GapScanningParams* BlueNRGGap::getScanningParams(void) +{ + return &_scanningParams; +} + +static void makeConnection(void) +{ + BlueNRGGap::getInstance().createConnection(); +} + +void BlueNRGGap::Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI) +{ + switch (reason) { + case DEVICE_FOUND: + { + GapAdvertisingParams::AdvertisingType_t type; + bool isScanResponse = false; + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * Private Random Address + * => scan_results = FALSE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type); + if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV || + (addr_type == RESOLVABLE_PRIVATE_ADDR || + addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) { + return; + } + + switch(adv_type) { + case ADV_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + break; + case ADV_DIRECT_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED; + break; + case ADV_SCAN_IND: + case SCAN_RSP: + type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED; + isScanResponse = true; + break; + case ADV_NONCONN_IND: + type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED; + break; + default: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + } + + PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n", + *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + if(!_connecting) { + processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data); + } + PRINTF("!!!After processAdvertisementReport\n\r"); + } + break; + + case DISCOVERY_COMPLETE: + // The discovery is complete. If this is due to a stop scanning (i.e., the device + // we are interested in has been found) and a connection has been requested + // then we start the device connection. + PRINTF("DISCOVERY_COMPLETE\n\r"); + _scanning = false; + + // Since the DISCOVERY_COMPLETE event can be received during the scanning interval, + // we need to delay the starting of connection + uint16_t delay = (_scanningParams.getInterval()*0.625); + +#ifdef AST_FOR_MBED_OS + if(_connecting) { + minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay)); + } +#else + Clock_Wait(delay); + if(_connecting) { + makeConnection(); + } +#endif /* AST_FOR_MBED_OS */ + + break; + } +} + +ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) +{ + + tBleStatus ret = BLE_STATUS_SUCCESS; + + // Stop ADV before scanning + /* + if (state.advertising == 1) { + stopAdvertising(); + } + */ + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * White List is empty + * => scan operation = FAILURE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + uint8_t whiteListSize = whitelistAddresses.size; + if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + ret = btleStartRadioScan(scanningParams.getActiveScanning(), + scanningParams.getInterval(), + scanningParams.getWindow(), + addr_type); + + PRINTF("Scanning...\n\r"); + PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000); + PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000); + //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval()); + //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1); + //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2); + if (BLE_STATUS_SUCCESS == ret){ + PRINTF("Observation Procedure Started\n"); + _scanning = true; + + if(scanningParams.getTimeout() != 0) { + PRINTF("!!! attaching scan to!!!\n"); + scanTimeout.attach(scanTimeoutCB, scanningParams.getTimeout()); + } + + return BLE_ERROR_NONE; + } + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + switch (ret) { + case BLE_STATUS_INVALID_CID: + PRINTF("Observation Procedure not implemented!!!\n\r"); + return BLE_ERROR_NOT_IMPLEMENTED; + default: + PRINTF("Observation Procedure failed (0x%02X)\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } + +} + +ble_error_t BlueNRGGap::stopScan() { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(_scanning) { + ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC); + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Discovery Procedure Terminated\n"); + return BLE_ERROR_NONE; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief set Tx power level + @param[in] txPower Transmission Power level + @returns ble_error_t +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setTxPower(int8_t txPower) +{ + tBleStatus ret; + + int8_t enHighPower = 0; + int8_t paLevel = 0; + + ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + ret = aci_hal_set_tx_power_level(enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief get permitted Tx power values + @param[in] values pointer to pointer to permitted power values + @param[in] num number of values +*/ +/**************************************************************************/ +void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { + static const int8_t permittedTxValues[] = { + -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8 + }; + + *valueArrayPP = permittedTxValues; + *countP = sizeof(permittedTxValues) / sizeof(int8_t); +} + +/**************************************************************************/ +/*! + @brief Set advertising parameters according to the current state + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setAdvParameters(void) +{ + uint32_t advIntMS; + + if(state.connected == 1) { + advIntMS = (conn_min_interval*1.25)-GUARD_INT; + advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS); + + PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval); + } else { + advInterval = _advParams.getIntervalInADVUnits(); + } +} + +/**************************************************************************/ +/*! + @brief Set connection parameters according to the current state (ADV and/or SCAN) + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionParameters(void) +{ + if (state.connected == 1) { + + PRINTF("state.connected=1\r\n"); + scanInterval = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(conn_min_interval*1.25); + scanWindow = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(((conn_min_interval*1.25)/100)*60); // scanWin ~= 60%(scanInt) + + } else if (state.advertising == 1) { + + if (_scanningParams.getInterval() < advInterval) { + PRINTF("state.adv=1 scanInterval<advInterval\r\n"); + scanInterval = advInterval; + scanWindow = advInterval; + } else { + PRINTF("state.adv=1 scanInterval>=advInterval\r\n"); + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + } + + if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms + conn_min_interval = MAX_INT_CONN; + conn_max_interval = MAX_INT_CONN; + } else { + conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + } + + } else { + + PRINTF("state.adv = 0\r\n"); + + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) || + SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms + conn_min_interval = DEF_INT_CONN; + conn_max_interval = DEF_INT_CONN; + } else { + conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + } + } + PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval)); + PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow)); + PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25)); + PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25)); + +} + +ble_error_t BlueNRGGap::createConnection () +{ + tBleStatus ret; + + /* + Before creating connection, set parameters according + to previous or current procedure (ADV and/or SCAN) + */ + setConnectionParameters(); + + /* + Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, + Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max + */ + ret = aci_gap_create_connection(scanInterval, + scanWindow, + _peerAddrType, + (unsigned char*)_peerAddr, + addr_type, + conn_min_interval, conn_max_interval, 0, + SUPERV_TIMEOUT, CONN_L1, CONN_L1); + + //_connecting = false; + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Connection started.\n"); + _connecting = false; + return BLE_ERROR_NONE; + } +} + +ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) +{ + /* avoid compiler warnings about unused variables */ + (void)connectionParams; + + setScanParams(scanParams->getInterval(), + scanParams->getWindow(), + scanParams->getTimeout(), + scanParams->getActiveScanning() + ); + + // Save the peer address + for(int i=0; i<BDADDR_SIZE; i++) { + _peerAddr[i] = peerAddr[i]; + } + _peerAddrType = peerAddrType; + + _connecting = true; + + if(_scanning) { + stopScan(); + } else { + PRINTF("Calling createConnection from connect()\n\r"); + return createConnection(); + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the advertising policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode) +{ + advertisingPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the scanning policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode) +{ + scanningPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Get the current advertising policy filter mode. + + @returns The advertising policy filter mode. +*/ +/**************************************************************************/ +Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const +{ + return advertisingPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Get the current scanning policy filter mode. + + @returns The scanning policy filter mode. + +*/ +/**************************************************************************/ +Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const +{ + return scanningPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGap's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::reset(void) +{ + PRINTF("BlueNRGGap::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (Gap::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + AdvToFlag = false; + ScanToFlag = false; + + /* Clear derived class members */ + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + return BLE_ERROR_NONE; +} + +void BlueNRGGap::setConnectionInterval(uint16_t interval) { + conn_min_interval = interval; + conn_max_interval = interval; +} + +Gap::Role_t BlueNRGGap::getGapRole(void) +{ + return (gapRole); +} + +void BlueNRGGap::setGapRole(Gap::Role_t role) +{ + gapRole = role; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,403 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTClient + * @brief BlueNRG BLE_API GattClient Adaptation + * @{ + */ + +#include "BlueNRGGattClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +#include <new> +#include <assert.h> + +ble_error_t BlueNRGGattClient::createGattConnectionClient(Gap::Handle_t connectionHandle) +{ + if(MAX_ACTIVE_CONNECTIONS <= _numConnections) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + for(uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + + if(_connectionPool[i] == NULL) { + BlueNRGGattConnectionClient *gattConnectionClient = new(std::nothrow) BlueNRGGattConnectionClient(this, connectionHandle); + + if (gattConnectionClient == NULL) { + return BLE_ERROR_NO_MEM; + } + + _connectionPool[i] = gattConnectionClient; + _connectionPool[i]->onServiceDiscoveryTermination(terminationCallback); + _numConnections++; + + PRINTF("createGattConnectionClient: _connectionPool index=%d\r\n", i); + PRINTF("createGattConnectionClient: succesfully added new gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + break; + } + } + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattClient::removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason) +{ + + PRINTF("removeGattConnectionClient: connectionHandle=%d reason=0x%x\r\n", connectionHandle, reason); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("removeGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("removeGattConnectionClient: Found gattConnectionClient\r\n"); + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + PRINTF("removeGattConnectionClient: succesfully removed gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + + break; + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + + return BLE_ERROR_NONE; +} + +BlueNRGGattConnectionClient * BlueNRGGattClient::getGattConnectionClient(Gap::Handle_t connectionHandle) { + PRINTF("getGattConnectionClient\r\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("getGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("getGattConnectionClient: Found gattConnectionClient\r\n"); + return _connectionPool[i]; + } + } + + return NULL; +} + +void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code) { + + if(error_code != BLE_STATUS_SUCCESS) { + return; + } + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->gattProcedureCompleteCB(error_code); +} + +void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServicesCB(event_data_length, + attribute_data_length, + attribute_data_list); +} + +void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServiceCB(event_data_length, + handles_info_list); +} + +ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->findServiceChars(); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharsCB(event_data_length, + handle_value_pair_length, + handle_value_pair); +} + +void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharByUUIDCB(event_data_length, + attr_handle, + attr_value); +} + +void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->discAllCharacDescCB(event_data_length, + format, + handle_uuid_pair); +} + +void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charReadCB(event_data_length, + attribute_value); +} + +void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWritePrepareCB(event_data_length, + attribute_handle, + offset, + part_attr_value); +} + +void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWriteExecCB(event_data_length); +} + +ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattClient launchServiceDiscovery\n\r"); + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->launchServiceDiscovery(sc, cc, matchingServiceUUID, matchingCharacteristicUUIDIn); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, matchingServiceUUID); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, startHandle, endHandle); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +bool BlueNRGGattClient::isServiceDiscoveryActive(void) const +{ + bool isSDActive = false; + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + isSDActive |= _connectionPool[i]->isServiceDiscoveryActive(); + } + } + + return isSDActive; +} + +void BlueNRGGattClient::terminateServiceDiscovery(void) +{ + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + _connectionPool[i]->terminateServiceDiscovery(); + } + } +} + +void BlueNRGGattClient::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; ++i) { + if (_connectionPool[i]) { + _connectionPool[i]->onServiceDiscoveryTermination(callback); + } + } +} + +ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->read(attributeHandle, offset); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->write(cmd, attributeHandle, length, value); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(characteristic.getConnectionHandle()); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverCharacteristicDescriptors(characteristic, discoveryCallback, terminationCallback); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattClient's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattClient::reset(void) +{ + PRINTF("BlueNRGGattClient::reset\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if(_connectionPool[i] != NULL) { + _connectionPool[i]->reset(); + + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + } + } + + return BLE_ERROR_NONE; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,816 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGattConnectionClient + * @brief BlueNRG GattConnectionClient Adaptation + * @{ + */ + +#include "BlueNRGGattConnectionClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" +#include "ble_debug.h" + +// #define PRINTF printf + +static uint8_t props_mask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 + }; + +void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code) +{ + if(error_code != BLE_STATUS_SUCCESS) { + _currentState = GATT_IDLE; + return; + } + + // Service Discovery complete +/* + if(_currentState != GATT_IDLE && + _currentState != GATT_DISCOVERY_TERMINATED && + _currentState != GATT_WRITE_CHAR && + _currentState != GATT_READ_CHAR) { +*/ + if(_currentState == GATT_SERVICE_DISCOVERY) { + findServiceChars(); + return; + } + + if(_currentState == GATT_CHAR_DESC_DISCOVERY) { + _currentState = GATT_IDLE; + if(charDescTerminationCallback != NULL) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { + _characteristic, + BLE_ERROR_NONE + }; + charDescTerminationCallback(¶ms); + } + return; + } + + // Read complete + if(_currentState == GATT_READ_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processReadResponse(&readCBParams); + free((void*)(readCBParams.data)); + readCBParams.data = NULL; + return; + } + + // Write complete + if(_currentState == GATT_WRITE_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); + return; + } +} + +void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numAttr; + + numAttr = (event_data_length - 1) / attribute_data_length; + + offset = 0; + for (i=0; i<numAttr; i++) { + startHandle = attribute_data_list[offset]; + endHandle = attribute_data_list[offset+2]; + + // UUID Type + if (attribute_data_length == 6) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4]; + PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(attribute_data_list+offset+4, UUID::LSB); + +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + + } + + PRINTF("Setup serviceIndex = %d\n\r", _numServices); + discoveredService[_numServices].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += attribute_data_length; + } + + PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr); + +} + +void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numHandlePairs; + + numHandlePairs = (event_data_length - 1) / 2; + + offset = 0; + for (i=0; i<numHandlePairs; i++) { + startHandle = handles_info_list[offset]; + endHandle = handles_info_list[offset+2]; + + PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle); + + + if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle); + uuid = _matchingServiceUUID.getShortUUID(); + } else { +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02x", longUUIDBytes[i]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB); + } + + discoveredService[i].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += 4; + } +} + +void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) +{ + // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + uint8_t i, numChar, offset; + + numChar = (event_data_length - 1) / handle_value_pair_length; + + PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar); + + offset = 0; + for (i=0; i<numChar; i++) { + // UUID Type + if (handle_value_pair_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(handle_value_pair+offset+5, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & handle_value_pair[offset+2]); + p._read = (props_mask[1] & handle_value_pair[offset+2])>>1; + p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2; + p._write = (props_mask[3] & handle_value_pair[offset+2])>>3; + p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4; + p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5; + p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = handle_value_pair[offset+2]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = handle_value_pair[offset]; + valueHandle = handle_value_pair[offset+3]; + lastHandle = valueHandle+1; + PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle); + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; + + offset += handle_value_pair_length; + } +} + +void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) +{ + // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + + PRINTF("serviceCharByUUIDCB\n\r"); + + // UUID Type + if (event_data_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = attr_value[4]<<8|attr_value[3]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(attr_value+3, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & attr_value[0]); + p._read = (props_mask[1] & attr_value[0])>>1; + p._writeWoResp = (props_mask[2] & attr_value[0])>>2; + p._write = (props_mask[3] & attr_value[0])>>3; + p._notify = (props_mask[4] & attr_value[0])>>4; + p._indicate = (props_mask[5] & attr_value[0])>>5; + p._authSignedWrite = (props_mask[6] & attr_value[0])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = attr_value[0]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = attr_handle; + valueHandle = attr_value[1]; + lastHandle = valueHandle+1; + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + // update the last handle and call the characteristic discovery callback for previous char + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; +} + +ble_error_t BlueNRGGattConnectionClient::findServiceChars(void) +{ + PRINTF("findServiceChars\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + + DiscoveredService *service; + + // complete the discovery of the last characteristic of the previous service. + // Its last handle wasn't known before this point + // update the handle and call the characteristic discovery callback. + if (_servIndex != 0 && _numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle()); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars = 0; + + // We finished chars discovery for all services + if(_servIndex >= _numServices) { + PRINTF("!!!We finished chars discovery for all services!!!\n\r"); + //_currentState = GATT_CHARS_DISCOVERY_COMPLETE; + + terminateServiceDiscovery(); + + return BLE_ERROR_NONE; + } + + service = &discoveredService[_servIndex]; + /* + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID()); + } else { + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); + } + */ + + if(serviceDiscoveryCallback) { + serviceDiscoveryCallback(service); + } + + PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex); + //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle()); + + if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) { + PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r"); + ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle()); + } else { + + uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID()); + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; +#ifdef DEBUG + PRINTF("findServiceChars C UUID-"); + for(unsigned i = 0; i < 2; i++) { + PRINTF("%02X", short_uuid[i]); + } + PRINTF("\n\r"); +#endif + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID(); +#ifdef DEBUG + PRINTF("(findServiceChars) C UUID-"); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", uuid[i]); + } + PRINTF("\r\n"); +#endif + } + + ret = aci_gatt_disc_charac_by_uuid(_connectionHandle, + service->getStartHandle(), + service->getEndHandle(), + uuid_type, + uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _servIndex++; + } + + PRINTF("findServiceChars ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + unsigned j; + + if(isServiceDiscoveryActive()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if(!sc && !cc) { + // nothing to do + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r"); + return BLE_ERROR_NONE; + } + + serviceDiscoveryCallback = sc; + characteristicDiscoveryCallback = cc; + _matchingServiceUUID = matchingServiceUUID; + _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn; + + //reset services + _numServices = 0; + _numChars = 0; + _servIndex = 0; + for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) { + discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE); + } + + if(matchingServiceUUID == BLE_UUID_UNKNOWN) { + + // Wildcard: search for all services + PRINTF("Wildcard: search for all services\r\n"); + ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle); + + } else { + PRINTF("search for specific services\r\n"); + + uint8_t type = matchingServiceUUID.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID()); +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x"); + for(j = 0; j < 2; j++) { + PRINTF("%02X", short_uuid[j]); + } + PRINTF("\n\r"); +#endif + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; + + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)matchingServiceUUID.getBaseUUID(); + +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x"); + for(j = 0; j < 16; j++) { + PRINTF("%02X", uuid[j]); + } + PRINTF("\n\r"); +#endif + } + + // search for specific service by UUID + ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_SERVICE_DISCOVERY; + } + + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)matchingServiceUUID; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)startHandle; + (void)endHandle; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const +{ + if(_currentState == GATT_SERVICE_DISCOVERY) { + return true; + } + + return false; +} + +void BlueNRGGattConnectionClient::terminateServiceDiscovery(void) +{ + _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED; + + if (terminationCallback) { + terminationCallback(_connectionHandle); + } +} + +void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value) +{ + // copy the data read, they will be forwarded to the user once the procedure + // has completed + readCBParams.connHandle = _connectionHandle; + readCBParams.offset = 0; + readCBParams.len = event_data_length; + readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length)); + memcpy((void*)(readCBParams.data), attribute_value, event_data_length); +} + +ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + /* avoid compiler warnings about unused variables */ + (void)offset; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // Save the attribute_handle not provided by evt_att_read_resp + gattc->readCBParams.handle = attributeHandle; + + ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle); + + if(ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_READ_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } +} + +void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) +{ + // Update the write response params + writeCBParams.handle = attribute_handle; + writeCBParams.offset = offset; + writeCBParams.len = event_data_length-4; //(?) + writeCBParams.data = part_attr_value; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length) +{ + /* avoid compiler warnings about unused variables */ + (void)event_data_length; + + writeCBParams.connHandle = _connectionHandle; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + /* avoid compiler warnings about unused variables */ + (void)cmd; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // We save the write response params (used by the callback) because + // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE + gattc->writeCBParams.connHandle = _connectionHandle; + gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD; + gattc->writeCBParams.handle = attributeHandle; + gattc->writeCBParams.offset = 0; + gattc->writeCBParams.len = length; + gattc->writeCBParams.data = value; + + ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); + + if (ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_WRITE_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } + +} + +void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + GattAttribute::Handle_t attHandle; + UUID uuid; + uint8_t i, numCharacDesc, offset, handle_uuid_length; + + handle_uuid_length = 4; //Handle + UUID_16 + if (format == 2) + handle_uuid_length = 18; //Handle + UUID_128 + + numCharacDesc = (event_data_length - 1) / handle_uuid_length; + + offset = 0; + + PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n", + event_data_length, format); + + + for (i=0; i<numCharacDesc; i++) { + memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle)); + + // UUID Type + if (handle_uuid_length == 4) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2]; + PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB); +#ifdef DEBUG + PRINTF("D UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + } + + if(charDescDiscoveryCallback != NULL) { + CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { + _characteristic, + DiscoveredCharacteristicDescriptor( + _characteristic.getGattClient(), + _connectionHandle, + attHandle, + uuid + ) + }; + charDescDiscoveryCallback(¶ms); + } + + _numCharDesc++; + + offset += handle_uuid_length; + } +} + +ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { + + tBleStatus ret; + + if(_currentState != GATT_IDLE) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + charDescDiscoveryCallback = discoveryCallback; + charDescTerminationCallback = terminationCallback; + + GattAttribute::Handle_t valueHandle = characteristic.getValueHandle(); + GattAttribute::Handle_t lastHandle = characteristic.getLastHandle(); + + PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle); + ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle); + + if (ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_CHAR_DESC_DISCOVERY; + _characteristic = characteristic; + return BLE_ERROR_NONE; + } + switch (ret) { + case BLE_STATUS_INVALID_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattConnectionClient::reset(void) { + PRINTF("BlueNRGGattConnectionClient::reset\n"); + + /* Clear all state, including private members */ + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + _numServices = 0; + _servIndex = 0; + _numChars = 0; + _numCharDesc = 0; + + /* Clear class members */ + memset(discoveredService, 0, sizeof(discoveredService)); + memset(discoveredChar, 0, sizeof(discoveredChar)); + + // free response if allocated + if(readCBParams.data) { + free((void*)(readCBParams.data)); + } + + return BLE_ERROR_NONE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,755 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTSERVER + * @brief BlueNRG BLE_API GattServer Adaptation + * @{ + */ + +#include "BlueNRGGattServer.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/**************************************************************************/ +/*! + @brief Adds a new service to the GATT table on the peripheral + + @params[in] service + Pointer to instance of the Gatt Server to add + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::addService(GattService &service) +{ + /* ToDo: Make sure we don't overflow the array, etc. */ + /* ToDo: Make sure this service UUID doesn't already exist (?) */ + /* ToDo: Basic validation */ + + tBleStatus ret; + uint8_t type; + uint16_t short_uuid; + uint8_t primary_short_uuid[2]; + uint8_t primary_base_uuid[16]; + uint8_t char_base_uuid[16]; + const uint8_t *base_uuid; + const uint8_t *base_char_uuid; + + uint8_t charsCount = service.getCharacteristicCount(); + const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount; + + // check that there is enough characteristics left in the + // characteristic array. + if (charsCount > available_characteristics) { + PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics); + return BLE_ERROR_NO_MEM; + } + + const uint16_t maxAttrRecords = computeAttributesRecord(service); + + type = (service.getUUID()).shortOrLong(); + PRINTF("AddService(): Type:%d\n\r", type); + + /* Add the service to the BlueNRG */ + short_uuid = (service.getUUID()).getShortUUID(); + STORE_LE_16(primary_short_uuid, short_uuid); + + if(type==UUID::UUID_TYPE_LONG) { + base_uuid = (service.getUUID()).getBaseUUID(); + + COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]); + } + + ret = BLE_STATUS_SUCCESS; + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_serv(UUID_TYPE_16, + primary_short_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_serv(UUID_TYPE_128, + primary_base_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_OUT_OF_HANDLE: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case ERR_UNSPECIFIED_ERROR: + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_ERROR: + default: + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + + + service.setHandle(servHandle); + //serviceHandleVector.push_back(servHandle); + PRINTF("added servHandle handle =%u\n\r", servHandle); + uint16_t bleCharacteristic; + + //iterate to include all characteristics + for (uint8_t i = 0; i < charsCount; i++) { + GattCharacteristic *p_char = service.getCharacteristic(i); + uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); + + uint8_t int_8_uuid[2]; + STORE_LE_16(int_8_uuid, char_uuid); + + type = (p_char->getValueAttribute().getUUID()).shortOrLong(); + + if(type==UUID::UUID_TYPE_LONG) { + base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); +#ifdef DEBUG + for(uint8_t j=0; j<16; j++) { + PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]); + } + PRINTF("\n\r"); +#endif + COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]); + } + + PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); + /* + * Gatt_Evt_Mask -> HardCoded (0) + * Encryption_Key_Size -> Hardcoded (16) + * isVariable (variable length value field) -> Hardcoded (1) + */ + uint8_t Gatt_Evt_Mask = 0x0; + + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP; + } + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; + } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_16, + int_8_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_128, + char_base_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + case BLE_STATUS_CHARAC_ALREADY_EXISTS: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); + + p_characteristics[characteristicCount++] = p_char; + /* Set the characteristic value handle */ + p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE); + PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle()); + + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + ble_error_t err = write(p_char->getValueAttribute().getHandle(), + p_char->getValueAttribute().getValuePtr(), + p_char->getValueAttribute().getLength(), false /* localOnly */); + if (err) { + PRINTF("ERROR HERE !!!!\r\n"); + return err; + } + } + + // add descriptors now + uint16_t descHandle = 0; + PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); + + for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { + GattAttribute *descriptor = p_char->getDescriptor(descIndex); + uint8_t desc_uuid[16] = { 0 }; + + + uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT; + STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID()); + + if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) { + desc_uuid_type = CHAR_DESC_TYPE_128_BIT; + const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID(); + + COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]); + } + + ret = aci_gatt_add_char_desc(service.getHandle(), + bleCharacteristic, + desc_uuid_type, + desc_uuid, + descriptor->getMaxLength(), + descriptor->getLength(), + descriptor->getValuePtr(), + CHAR_DESC_SECURITY_PERMISSION, + CHAR_DESC_ACCESS_PERMISSION, + GATT_NOTIFY_ATTRIBUTE_WRITE, + MIN_ENCRY_KEY_SIZE, + CHAR_ATTRIBUTE_LEN_IS_FIXED, + &descHandle); + PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); + + switch (ret) { + case BLE_STATUS_SUCCESS: + PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); + descriptor->setHandle(descHandle); + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_INVALID_OPERATION: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + } + + serviceCount++; + + //FIXME: There is no GattService pointer array in GattServer. + // There should be one? (Only the user is aware of GattServices!) Report to forum. + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on char handle + + @param[in] attributeHandle + The handle of the GattCharacteristic to read from + @param[in] buffer + Buffer to hold the the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes read into the buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) +{ + tBleStatus ret; + uint16_t charHandle = attributeHandle; + + ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer); + + if(ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on the connection + and char handle + + @param[in] connectionHandle + The handle of the connection + @param[in] attributeHandle + The handle of the GattCharacteristic to write to + @param[in] buffer + Data to use when updating the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes in buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + uint8_t buffer[], + uint16_t *lengthP) { + + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)attributeHandle; + (void)buffer; + (void)lengthP; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t, + const uint8_t[], + uint16_t, bool localOnly) { + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)localOnly; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly) +{ + /* avoid compiler warnings about unused variables */ + (void)localOnly; + + // check that the len of the data to write are compatible with the characteristic + GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle); + if (!characteristic) { + PRINTF("characteristic not found\r\n"); + return BLE_ERROR_INVALID_PARAM; + } + + // if the attribute handle is the attribute handle of the characteristic value then + // write the value + if (attributeHandle == characteristic->getValueHandle()) { + // assert the len in input is correct for this characteristic + const GattAttribute& value_attribute = characteristic->getValueAttribute(); + + // reject write if the lenght exceed the maximum lenght of this attribute + if (value_attribute.getMaxLength() < len) { + PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + // reject write if the attribute size is fixed and the lenght in input is different than the + // length of the attribute. + if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) { + PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + tBleStatus ret; + + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + + PRINTF("updating bleCharacteristic valueHandle=%u,\ + corresponding serviceHandle=%u len=%d\n\r", + attributeHandle, bleCharHandleMap.find(charHandle)->second, len); + + /* + * If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. + */ + ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } else { + // write this handle has a descriptor handle + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + uint16_t service_handle = bleCharHandleMap.find(charHandle)->second; + + tBleStatus ret = aci_gatt_set_desc_value( + service_handle, + charHandle, + attributeHandle, + 0, + len, + buffer + ); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } +} + +/**************************************************************************/ +/*! + @brief Reads a value according to the handle provided + + @param[in] attributeHandle + The handle of the attribute to read from + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle) +{ + uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); + + GattReadCallbackParams readParams; + readParams.handle = attributeHandle; + + //PRINTF("readParams.handle = %d\n\r", readParams.handle); + HCIDataReadEvent(&readParams); + + //EXIT: + if(gapConnectionHandle != 0){ + //PRINTF("Calling aci_gatt_allow_read\n\r"); + aci_gatt_allow_read(gapConnectionHandle); + } + + return BLE_ERROR_NONE; +} + +// ask if the write request should be accepted of rejected +// return 0 in case of success or an ATT error response in +// case of faillure +uint8_t BlueNRGGattServer::Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length, + const uint8_t* data) { + + GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle); + if(!characteristic) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF; + } + + // check if the data length is in range + if (characteristic->getValueAttribute().getMaxLength() < data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + // if the length of the characteristic value is fixed + // then the data in input should be of that length + if (characteristic->getValueAttribute().hasVariableLength() == false && + characteristic->getValueAttribute().getMaxLength() != data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + GattWriteAuthCallbackParams params = { + connection_handle, + attr_handle, + /* offset */ 0, + data_length, + data, + /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED + }; + + return characteristic->authorizeWrite(¶ms) & 0xFF; +} + +/**************************************************************************/ +/*! + @brief Returns the GattCharacteristic according to the handle provided + + @param[in] attrHandle + The handle of the attribute + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) +{ + GattCharacteristic *p_char = NULL; + int i; + uint16_t handle, handle_1; + + PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle); + for(i=0; i<characteristicCount; i++) + { + handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + PRINTF("handle(%d)=%d\n\r", i, handle); + if(i==characteristicCount-1)//Last Characteristic check + { + if(attrHandle>=handle) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); + break; + } + } + else { + handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + //Testing if attribute handle is between two Characteristic Handles + if(attrHandle>=handle && attrHandle<handle_1) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); + break; + } else continue; + } + } + + return p_char; +} + +void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { + this->handleDataWrittenEvent(params); +} + +void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { + PRINTF("Called HCIDataReadEvent\n\r"); + this->handleDataReadEvent(params); +} + +void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { + this->handleEvent(type, charHandle); +} + +void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { + this->handleDataSentEvent(count); +} + + +ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { + // <TODO> + return (ble_error_t)0; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::reset(void) +{ + PRINTF("BlueNRGGattServer::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (GattServer::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + /* Clear class members */ + memset(p_characteristics, 0, sizeof(p_characteristics)); + memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles)); + serviceCount = 0; + characteristicCount = 0; + + return BLE_ERROR_NONE; +} + + +/// compute the number of attributes needed by this service. +uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) { + uint16_t attribute_records = 1; + + for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) { + // add two attributes, one for the characteristic declaration + // and the other for the characteristic value. + attribute_records += 2; + + const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index); + const uint8_t properties = characteristic->getProperties(); + // if notify or indicate are present, two attributes are + // needed + if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) || + (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { + attribute_records += 2; + } + + // if broadcast is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) { + attribute_records += 2; + } + + // if extended properties flag is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) { + attribute_records += 2; + } + + attribute_records += characteristic->getDescriptorCount(); + } + + // for some reason, if there is just a service, this value should + // be equal to 5 + if (attribute_records == 1) { + attribute_records = 5; + } + + return attribute_records; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,421 @@ +/** + ****************************************************************************** + * @file ble_hci.c + * @author AMS/HESA Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "ble_gp_timer.h" +#include "ble_debug.h" + +#include "stm32_bluenrg_ble.h" + +#if BLE_CONFIG_DBG_ENABLE +#undef PRINTF +#endif + +#define HCI_LOG_ON 0 + +#define HCI_READ_PACKET_NUM_MAX (0x40) + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tListNode hciReadPktPool; +tListNode hciReadPktRxQueue; + +// betzw - DEBUG: +//#define POOL_CNT +#ifdef POOL_CNT +#include <stdio.h> +static unsigned int nr_hciReadPktPool; +static unsigned int lowest_nr_hciReadPktPool; +#endif // POOL_CNT + +/* pool of hci read packets */ +static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; + +static volatile uint8_t hci_timer_id; +static volatile uint8_t hci_timeout; + +void hci_timeout_callback(void) +{ + hci_timeout = 1; + return; +} + +void HCI_Init(void) +{ + uint8_t index; + +#ifdef POOL_CNT + nr_hciReadPktPool = 0; +#endif // POOL_CNT + + /* Initialize list heads of ready and free hci data packet queues */ + list_init_head (&hciReadPktPool); + list_init_head (&hciReadPktRxQueue); + + /* Initialize the queue of free hci data packets */ + for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) + { + list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif // POOL_CNT + } + +#ifdef POOL_CNT + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif // POOL_CNT +} + +#define HCI_PCK_TYPE_OFFSET 0 +#define EVENT_PARAMETER_TOT_LEN_OFFSET 2 + +/** + * Verify if HCI packet is correctly formatted. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * @return 0 if HCI packet is as expected + */ +int HCI_verify(const tHciDataPacket * hciReadPacket) +{ + const uint8_t *hci_pckt = hciReadPacket->dataBuff; + + if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) + return 1; /* Incorrect type. */ + + if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) + return 2; /* Wrong length (packet truncated or too long). */ + + return 0; +} + +void HCI_Process(void) +{ + tHciDataPacket * hciReadPacket = NULL; + +#ifdef POOL_CNT + printf("betzw(%s, %d): nr_hciReadPktPool = %u (lowest = %u)\r\n", __func__, __LINE__, + nr_hciReadPktPool, lowest_nr_hciReadPktPool); +#endif // POOL_CNT + + Disable_SPI_IRQ(); + uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); + /* process any pending events read */ + while(list_empty == FALSE) + { + list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + Enable_SPI_IRQ(); + HCI_Event_CB(hciReadPacket->dataBuff); + Disable_SPI_IRQ(); + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + list_empty = list_is_empty(&hciReadPktRxQueue); + } + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG. */ + HCI_HandleSPI(); + Enable_SPI_IRQ(); +} + +BOOL HCI_Queue_Empty(void) +{ + return list_is_empty(&hciReadPktRxQueue); +} + +/** + * When an interrupt is raised by BlueNRG, + * just signal that a new event (availability of SPI data to be read) + * needs to be processed. + */ +void HCI_Isr(void) +{ + signalEventsToProcess(); +} + +/** + * Now, SPI Data are handled in user space. + * In case it has to be called in ISR, take care to + * call Disable_SPI_IRQ/Enable_SPI_IRQ in a proper way. + * The calls Disable_SPI_IRQ/Enable_SPI_IRQ have not been removed + * from this code for backward compatibility. + */ +void HCI_HandleSPI(void) +{ + tHciDataPacket * hciReadPacket = NULL; + uint8_t data_len; + + Clear_SPI_EXTI_Flag(); + while(BlueNRG_DataPresent()){ + if (list_is_empty (&hciReadPktPool) == FALSE){ + + /* enqueueing a packet for read */ + list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool--; + if(nr_hciReadPktPool < lowest_nr_hciReadPktPool) + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif + + data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); + if(data_len > 0){ + hciReadPacket->data_len = data_len; + if(HCI_verify(hciReadPacket) == 0) { + list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); + } else { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else { + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else{ + // HCI Read Packet Pool is empty, wait for a free packet. + Clear_SPI_EXTI_Flag(); + return; + } + + Clear_SPI_EXTI_Flag(); + } +} + +void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){ +#if HCI_LOG_ON + PRINTF("HCI <- "); + for(int i=0; i < n_bytes1; i++) + PRINTF("%02X ", *((uint8_t*)data1 + i)); + for(int i=0; i < n_bytes2; i++) + PRINTF("%02X ", *((uint8_t*)data2 + i)); + PRINTF("\n"); +#endif + + Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); +} + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) +{ + hci_command_hdr hc; + + hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); + hc.plen= plen; + + uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; + header[0] = HCI_COMMAND_PKT; + Osal_MemCpy(header+1, &hc, sizeof(hc)); + + hci_write(header, param, sizeof(header), plen); +} + +static void move_list(tListNode * dest_list, tListNode * src_list) +{ + pListNode tmp_node; + + while(!list_is_empty(src_list)){ + list_remove_tail(src_list, &tmp_node); + list_insert_head(dest_list, tmp_node); + } +} + + /* It ensures that we have at least half of the free buffers in the pool. */ +static void free_event_list(void) +{ + tHciDataPacket * pckt; + + Disable_SPI_IRQ(); + + while(list_get_size(&hciReadPktPool) < HCI_READ_PACKET_NUM_MAX/2){ + list_remove_head(&hciReadPktRxQueue, (tListNode **)&pckt); + list_insert_tail(&hciReadPktPool, (tListNode *)pckt); + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG */ + HCI_HandleSPI(); + } + + Enable_SPI_IRQ(); +} + +int hci_send_req(struct hci_request *r, BOOL async) +{ + uint8_t *ptr; + uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + hci_event_pckt *event_pckt; + hci_uart_pckt *hci_hdr; + int to = DEFAULT_TIMEOUT; + struct timer t; + tHciDataPacket * hciReadPacket = NULL; + tListNode hciTempQueue; + + list_init_head(&hciTempQueue); + + free_event_list(); + + hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); + + if(async){ + return 0; + } + + /* Minimum timeout is 1. */ + if(to == 0) + to = 1; + + Timer_Set(&t, to); + + while(1) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + evt_le_meta_event *me; + int len; + + while(1){ + + Disable_SPI_IRQ(); + HCI_HandleSPI(); + Enable_SPI_IRQ(); + + if(Timer_Expired(&t)){ + goto failed; + } + if(!HCI_Queue_Empty()){ + break; + } + } + + /* Extract packet from HCI event queue. */ + Disable_SPI_IRQ(); + list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + + hci_hdr = (void *)hciReadPacket->dataBuff; + + if(hci_hdr->type == HCI_EVENT_PKT){ + + event_pckt = (void *) (hci_hdr->data); + + ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); + len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); + + switch (event_pckt->evt) { + + case EVT_CMD_STATUS: + cs = (void *) ptr; + + if (cs->opcode != opcode) + goto failed; + + if (r->event != EVT_CMD_STATUS) { + if (cs->status) { + goto failed; + } + break; + } + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_CMD_COMPLETE: + cc = (void *) ptr; + + if (cc->opcode != opcode) + goto failed; + + ptr += EVT_CMD_COMPLETE_SIZE; + len -= EVT_CMD_COMPLETE_SIZE; + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_LE_META_EVENT: + me = (void *) ptr; + + if (me->subevent != r->event) + break; + + len -= 1; + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, me->data, r->rlen); + goto done; + + case EVT_HARDWARE_ERROR: + goto failed; + + default: + break; + } + } + + /* If there are no more packets to be processed, be sure there is at list one + packet in the pool to process the expected event. + If no free packets are available, discard the processed event and insert it + into the pool. */ + if(list_is_empty(&hciReadPktPool) && list_is_empty(&hciReadPktRxQueue)){ + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); + hciReadPacket=NULL; + } + else { + /* Insert the packet in a different queue. These packets will be + inserted back in the main queue just before exiting from send_req(), so that + these events can be processed by the application. + */ + list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); + hciReadPacket = NULL; + } + + HCI_HandleSPI(); + + Enable_SPI_IRQ(); + + } + +failed: + if(hciReadPacket != NULL) { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + move_list(&hciReadPktRxQueue, &hciTempQueue); + Enable_SPI_IRQ(); + return -1; + +done: + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + move_list(&hciReadPktRxQueue, &hciTempQueue); + + Enable_SPI_IRQ(); + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,837 @@ +/** + ****************************************************************************** + * @file ble_hci_le.c + * @author AMG RF Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +int hci_reset(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_RESET; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_disconnect(uint16_t handle, uint8_t reason) +{ + struct hci_request rq; + disconnect_cp cp; + uint8_t status; + + cp.handle = handle; + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) +{ + struct hci_request rq; + read_local_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + + *hci_version = resp.hci_version; + *hci_revision = btohs(resp.hci_revision); + *lmp_pal_version = resp.lmp_pal_version; + *manufacturer_name = btohs(resp.manufacturer_name); + *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); + + return 0; +} + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) +{ + struct hci_request rq; + le_read_buffer_size_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_BUFFER_SIZE; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *pkt_len = resp.pkt_len; + *max_pkt = resp.max_pkt; + + return 0; +} + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter) +{ + struct hci_request rq; + le_set_adv_parameters_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.min_interval = min_interval; + adv_cp.max_interval = max_interval; + adv_cp.advtype = advtype; + adv_cp.own_bdaddr_type = own_bdaddr_type; + adv_cp.direct_bdaddr_type = direct_bdaddr_type; + if(direct_bdaddr != NULL) + Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); + adv_cp.chan_map = chan_map; + adv_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_PARAMETERS; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_adv_data_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.length = length; + Osal_MemCpy(adv_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_DATA; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertise_enable(uint8_t enable) +{ + struct hci_request rq; + le_set_advertise_enable_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.enable = enable?1:0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter) +{ + struct hci_request rq; + le_set_scan_parameters_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.type = type; + scan_cp.interval = interval; + scan_cp.window = window; + scan_cp.own_bdaddr_type = own_bdaddr_type; + scan_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) +{ + struct hci_request rq; + le_set_scan_enable_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.enable = enable?1:0; + scan_cp.filter_dup = filter_dup; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_ENABLE; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_rand(uint8_t random_number[8]) +{ + struct hci_request rq; + le_rand_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_RAND; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + Osal_MemCpy(random_number, resp.random, 8); + + return 0; +} + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_scan_response_data_cp scan_resp_cp; + uint8_t status; + + Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); + scan_resp_cp.length = length; + Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; + rq.cparam = &scan_resp_cp; + rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) +{ + struct hci_request rq; + le_read_adv_channel_tx_power_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *tx_power_level = resp.level; + + return 0; +} + +int hci_le_set_random_address(tBDAddr bdaddr) +{ + struct hci_request rq; + le_set_random_address_cp set_rand_addr_cp; + uint8_t status; + + Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); + Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; + rq.cparam = &set_rand_addr_cp; + rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_read_bd_addr(tBDAddr bdaddr) +{ + struct hci_request rq; + read_bd_addr_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_BD_ADDR; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_BD_ADDR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); + + return 0; +} + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) +{ + struct hci_request rq; + le_create_connection_cp create_cp; + uint8_t status; + + Osal_MemSet(&create_cp, 0, sizeof(create_cp)); + create_cp.interval = interval; + create_cp.window = window; + create_cp.initiator_filter = initiator_filter; + create_cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); + create_cp.own_bdaddr_type = own_bdaddr_type; + create_cp.min_interval=min_interval; + create_cp.max_interval=max_interval; + create_cp.latency = latency; + create_cp.supervision_timeout=supervision_timeout; + create_cp.min_ce_length=min_ce_length; + create_cp.max_ce_length=max_ce_length; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN; + rq.cparam = &create_cp; + rq.clen = LE_CREATE_CONN_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_create_connection_cancel(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN_CANCEL; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) +{ + struct hci_request rq; + le_encrypt_cp params; + le_encrypt_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemCpy(params.key, key, 16); + Osal_MemCpy(params.plaintext, plaintextData, 16); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ENCRYPT; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + le_ltk_neg_reply_cp params; + le_ltk_neg_reply_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + params.handle = 1; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_LTK_NEG_REPLY; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CLEAR_WHITE_LIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0){ + return BLE_STATUS_TIMEOUT; + } + + return status; +} + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) +{ + struct hci_request rq; + le_add_device_to_white_list_cp params; + uint8_t status; + + params.bdaddr_type = bdaddr_type; + Osal_MemCpy(params.bdaddr, bdaddr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; + rq.cparam = ¶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/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1309 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB05A1 cp; + gap_init_rp resp; + + cp.role = role; + cp.privacy_enabled = privacy_enabled; + cp.device_name_char_len = device_name_char_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} +tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB04A1 cp; + gap_init_rp resp; + + cp.role = role; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + SlaveConnIntervMin = htobs(SlaveConnIntervMin); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + SlaveConnIntervMax = htobs(SlaveConnIntervMax); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB05A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.directed_adv_type = directed_adv_type; + cp.adv_interv_min = adv_interv_min; + cp.adv_interv_max = adv_interv_max; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB04A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_io_capability(uint8_t io_capability) +{ + struct hci_request rq; + uint8_t status; + gap_set_io_capability_cp cp; + + cp.io_capability = io_capability; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_IO_CAPABILITY; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode) +{ + struct hci_request rq; + gap_set_auth_requirement_cp cp; + uint8_t status; + + cp.mitm_mode = mitm_mode; + cp.oob_enable = oob_enable; + Osal_MemCpy(cp.oob_data, oob_data, 16); + cp.min_encryption_key_size = min_encryption_key_size; + cp.max_encryption_key_size = max_encryption_key_size; + cp.use_fixed_pin = use_fixed_pin; + cp.fixed_pin = htobl(fixed_pin); + cp.bonding_mode = bonding_mode; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) +{ + struct hci_request rq; + gap_set_author_requirement_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorization_enable = authorization_enable; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) +{ + struct hci_request rq; + gap_passkey_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.passkey = htobl(passkey); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_PASSKEY_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) +{ + struct hci_request rq; + gap_authorization_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorize = authorize; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB05A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + cp.own_address_type = own_address_type; + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB04A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) +{ + struct hci_request rq; + gap_set_undirected_connectable_cp cp; + uint8_t status; + + cp.own_addr_type = own_addr_type; + cp.adv_filter_policy = adv_filter_policy; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) +{ + struct hci_request rq; + gap_slave_security_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.bonding = bonding; + cp.mitm_protection = mitm_protection; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[32]; + uint8_t indx = 0; + + if (AdvLen > (sizeof(buffer)-1)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvLen; + indx++; + + Osal_MemCpy(buffer + indx, AdvData, AdvLen); + indx += AdvLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_UPDATE_ADV_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) +{ + struct hci_request rq; + gap_delete_ad_type_cp cp; + uint8_t status; + + cp.ad_type = ad_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_DELETE_AD_TYPE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required) +{ + struct hci_request rq; + gap_get_security_level_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; + rq.rparam = &resp; + rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *mitm_protection = resp.mitm_protection; + *bonding = resp.bonding; + *oob_data = resp.oob_data; + *passkey_required = resp.passkey_required; + + return resp.status; +} + +tBleStatus aci_gap_configure_whitelist(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) +{ + struct hci_request rq; + gap_terminate_cp cp; + uint8_t status; + + cp.handle = htobs(conn_handle); + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_clear_security_database(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) +{ + struct hci_request rq; + gap_allow_rebond_cp_IDB05A1 cp; + uint8_t status; + + cp.conn_handle = conn_handle; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_allow_rebond_IDB04A1(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_limited_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_general_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_name_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = use_reconn_addr; + indx++; + + Osal_MemCpy(buffer + indx, reconn_addr, 6); + indx += 6; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB05A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB04A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.use_reconn_addr = use_reconn_addr; + Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_start_selective_conn_establish_proc_cp cp; + uint8_t status; + + if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.num_whitelist_entries = num_whitelist_entries; + + Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_create_connection_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CREATE_CONNECTION; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; + rq.cparam = &procedure_code; + rq.clen = 1; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_connection_update_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) +{ + struct hci_request rq; + gap_send_pairing_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.force_rebond = force_rebond; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + gap_resolve_private_address_rp rp; + + Osal_MemCpy(cp.address, private_address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); + + return 0; +} +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + uint8_t status; + + Osal_MemCpy(cp.address, address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_set_broadcast_mode_cp cp; + uint8_t status; + uint8_t indx = 0; + uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; + + if (variable_size > sizeof(cp.var_len_data) ) + return BLE_STATUS_INVALID_PARAMS; + + cp.adv_interv_min = htobs(adv_interv_min); + cp.adv_interv_max = htobs(adv_interv_max); + cp.adv_type = adv_type; + cp.own_addr_type = own_addr_type; + + cp.var_len_data[indx] = adv_data_length; + indx++; + Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); + indx += adv_data_length; + cp.var_len_data[indx] = num_whitelist_entries; + indx ++; + Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_BROADCAST_MODE; + rq.cparam = &cp; + rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_observation_proc_cp cp; + uint8_t status; + + cp.scan_interval = scan_interval; + cp.scan_window = scan_window; + cp.scan_type = scan_type; + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_OBSERVATION_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) +{ + struct hci_request rq; + gap_is_device_bonded_cp cp; + uint8_t status; + + cp.peer_address_type = peer_address_type; + Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_IS_DEVICE_BONDED; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) +{ + struct hci_request rq; + gap_get_bonded_devices_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_BONDED_DEVICES; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (rp.status) { + return rp.status; + } + + *num_devices = rp.num_addr; + if(device_list != NULL) + Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1505 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.c +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : File with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_gatt_init(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INIT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[19]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, service_uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = service_type; + indx++; + + buffer[indx] = max_attr_records; + indx++; + + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle) +{ + struct hci_request rq; + gatt_include_serv_rp resp; + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + service_handle = htobs(service_handle); + Osal_MemCpy(buffer, &service_handle, 2); + indx += 2; + + included_start_handle = htobs(included_start_handle); + Osal_MemCpy(buffer+indx, &included_start_handle, 2); + indx += 2; + + included_end_handle = htobs(included_end_handle); + Osal_MemCpy(buffer+indx, &included_end_handle, 2); + indx += 2; + + if(included_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } else { + uuid_len = 16; + } + + buffer[indx] = included_uuid_type; + indx++; + + Osal_MemCpy(buffer + indx, included_uuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INCLUDE_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *included_handle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[25]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + buffer[indx] = charValueLen; + indx++; + + buffer[indx] = charProperties; + indx++; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *charHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle) +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = descValueMaxLen; + indx++; + + buffer[indx] = descValueLen; + indx++; + + if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + Osal_MemCpy(buffer + indx, descValue, descValueLen); + indx += descValueLen; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = accPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR_DESC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *descHandle = btohs(resp.handle); + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = charValOffset; + indx++; + + buffer[indx] = charValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charValue, charValueLen); + indx += charValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_char_cp cp; + + cp.service_handle = htobs(servHandle); + cp.char_handle = htobs(charHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_CHAR; + rq.cparam = &cp; + rq.clen = GATT_DEL_CHAR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_service(uint16_t servHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_serv_cp cp; + + cp.service_handle = htobs(servHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_inc_serv_cp cp; + + cp.service_handle = htobs(servHandle); + cp.inc_serv_handle = htobs(includeServHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_INC_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_INC_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) +{ + struct hci_request rq; + uint8_t status; + gatt_set_evt_mask_cp cp; + + cp.evt_mask = htobs(event_mask); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_EVT_MASK; + rq.cparam = &cp; + rq.clen = GATT_SET_EVT_MASK_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_exchange_config_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_EXCHANGE_CONFIG; + rq.cparam = &cp; + rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) +{ + struct hci_request rq; + uint8_t status; + att_find_info_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_INFO_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_find_by_type_value_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + Osal_MemCpy(cp.uuid, uuid, 2); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_group_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_prepare_write_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.value_offset = htobs(value_offset); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) +{ + struct hci_request rq; + uint8_t status; + att_execute_write_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.execute = execute; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_prim_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_prim_service_by_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; + rq.cparam = &cp; + rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, + uint16_t end_service_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_find_included_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_service_handle); + cp.end_handle = htobs(end_service_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_of_serv_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_attr_handle = htobs(start_attr_handle); + cp.end_attr_handle = htobs(end_attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t charUuidType, + const uint8_t* charUuid) +{ + struct hci_request rq; + uint8_t status; + + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + start_handle = htobs(start_handle); + Osal_MemCpy(buffer + indx, &start_handle, 2); + indx += 2; + + end_handle = htobs(end_handle); + Osal_MemCpy(buffer + indx, &end_handle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == 0x01){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_descriptors_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.char_val_handle = htobs(char_val_handle); + cp.char_end_handle = htobs(char_end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_read_using_charac_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; + rq.cparam = &cp; + rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles) +{ + struct hci_request rq; + uint8_t status; + gatt_read_multiple_charac_val_cp cp; + + if(num_handles*2 > sizeof(cp.set_of_handles)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.num_handles = htobs(num_handles); + Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_long_charac_val_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; + rq.cparam = &cp; + rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_signed_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_confirm_indication_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_CONFIRM_INDICATION; + rq.cparam = &cp; + rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = write_status; + indx += 1; + + buffer[indx] = err_code; + indx += 1; + + buffer[indx] = att_val_len; + indx += 1; + + Osal_MemCpy(buffer + indx, att_val, att_val_len); + indx += att_val_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(uint16_t conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ALLOW_READ; + rq.cparam = &cp; + rq.clen = GATT_ALLOW_READ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission) +{ + struct hci_request rq; + gatt_set_security_permission_cp cp; + uint8_t status; + + cp.service_handle = htobs(service_handle); + cp.attr_handle = htobs(attr_handle); + cp.security_permission = security_permission; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; + rq.cparam = &cp; + rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + charDescHandle = htobs(charDescHandle); + Osal_MemCpy(buffer + indx, &charDescHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charDescValOffset, 2); + indx += 2; + + buffer[indx] = charDescValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); + indx += charDescValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_DESC_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_cp cp; + gatt_read_handle_val_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = btohs(rp.value_len); + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_offset_cp cp; + gatt_read_handle_val_offset_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rp.value_len; + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value) +{ + struct hci_request rq; + uint8_t status; + gatt_upd_char_val_ext_cp cp; + + if(value_length > sizeof(cp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.service_handle = htobs(service_handle); + cp.char_handle = htobs(char_handle); + cp.update_type = update_type; + cp.char_length = htobs(char_length); + cp.value_offset = htobs(value_offset); + cp.value_length = value_length; + Osal_MemCpy(cp.value, value, value_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL_EXT; + rq.cparam = &cp; + rq.clen = GATT_UPD_CHAR_VAL_EXT_CP_SIZE + value_length; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,266 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number) +{ + struct hci_request rq; + hal_get_fw_build_number_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_FW_BUILD_NUMBER; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *build_number = rp.build_number; + + return 0; +} + +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((len+2) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = offset; + indx++; + + buffer[indx] = len; + indx++; + + Osal_MemCpy(buffer + indx, val, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + hal_read_config_data_cp cp; + hal_read_config_data_rp rp; + + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_READ_CONFIG_DATA; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rq.rlen-1; + + Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) +{ + struct hci_request rq; + hal_set_tx_power_level_cp cp; + uint8_t status; + + cp.en_high_power = en_high_power; + cp.pa_level = pa_level; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets) +{ + struct hci_request rq; + hal_le_tx_test_packet_number_rp resp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_LE_TX_TEST_PACKET_NUMBER; + rq.rparam = &resp; + rq.rlen = sizeof(resp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *number_of_packets = btohl(resp.number_of_packets); + + return 0; +} + +tBleStatus aci_hal_device_standby(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_DEVICE_STANDBY; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_start(uint8_t rf_channel) +{ + struct hci_request rq; + hal_tone_start_cp cp; + uint8_t status; + + cp.rf_channel = rf_channel; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_START; + rq.cparam = &cp; + rq.clen = HAL_TONE_START_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_stop(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_STOP; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]) +{ + struct hci_request rq; + hal_get_link_status_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_LINK_STATUS; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(link_status,rp.link_status,sizeof(link_status)); + for(int i = 0; i < 8; i++) + conn_handle[i] = btohs(rp.conn_handle[i]); + + return 0; +} + +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot) +{ + struct hci_request rq; + hal_get_anchor_period_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_ANCHOR_PERIOD; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *anchor_period = btohl(rp.anchor_period); + *max_free_slot = btohl(rp.max_free_slot); + + return 0; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,117 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB05A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.min_ce_length = htobs(min_ce_length); + cp.max_ce_length = htobs(max_ce_length); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB04A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,269 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_updater_aci.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_updater_reboot(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_get_updater_version(uint8_t *version) +{ + struct hci_request rq; + get_updater_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_VERSION; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) +{ + struct hci_request rq; + get_updater_bufsize_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_BUFSIZE; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_reset_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = htobl(address); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_SECTOR; + rq.cparam = &cp; + rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_program_data_block(uint32_t address, + uint16_t len, + const uint8_t *data) +{ + struct hci_request rq; + uint8_t status; + updater_prog_data_block_cp cp; + + if( len > sizeof(cp.data)) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(len); + Osal_MemCpy(cp.data, data, len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_read_data_block(uint32_t address, + uint16_t data_len, + uint8_t *data) +{ + struct hci_request rq; + updater_read_data_block_cp cp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + + if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(data_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; + rq.rparam = buffer; + rq.rlen = data_len + 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + // First byte is status + Osal_MemCpy(data, buffer+1, data_len); + + return buffer[0]; +} + +tBleStatus aci_updater_calc_crc(uint32_t address, + uint8_t num_sectors, + uint32_t *crc) +{ + struct hci_request rq; + updater_calc_crc_cp cp; + updater_calc_crc_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + cp.address = htobl(address); + cp.num_sectors = num_sectors; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_CALC_CRC; + rq.cparam = &cp; + rq.clen = UPDATER_CALC_CRC_CP_SIZE; + rq.rparam = &resp; + rq.rlen = UPDATER_CALC_CRC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *crc = btohl(resp.crc); + + return resp.status; +} + +tBleStatus aci_updater_hw_version(uint8_t *version) +{ + struct hci_request rq; + updater_hw_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_HW_VERSION; + rq.rparam = &resp; + rq.rlen = UPDATER_HW_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,423 @@ + +#include "ble_hal.h" +#include "ble_hal_types.h" +#include "ble_status.h" +#include "bluenrg_aci.h" +#include "bluenrg_utils.h" +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "ble_osal.h" +#include "string.h" +#include "stm32_bluenrg_ble.h" + +#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 +#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 + +#define BASE_ADDRESS 0x10010000 + +#define FW_OFFSET (2*1024) // 2 KB +#define FW_OFFSET_MS 0 +#define FULL_STACK_SIZE (66*1024) // 66 KB +#define BOOTLOADER_SIZE (2*1024) // 2 kB +#define SECTOR_SIZE (2*1024) // 2 KB + +// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + +// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 +#define CRC_POLY 0x04C11DB7 // the poly without the x**32 + +#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC + +#define IFR_SIZE 192 +#define IFR_BASE_ADDRESS 0x10020000 +#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data + +#if BLUENRG_MS +#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET +#else +#define IFR_WRITE_OFFSET_BEGIN 0 +#endif + + +#define BLUE_FLAG_OFFSET 0x8C0 +#define MAX_ERASE_RETRIES 2 +#define MAX_WRITE_RETRIES 2 +#define MIN_WRITE_BLOCK_SIZE 4 +#define MAX_WRITE_BLOCK_SIZE 64 // 64 bytes +#define READ_BLOCK_SIZE 64 // 64 bytes + +#define RETRY_COMMAND(func, num_ret, error) \ +{ \ + uint8_t num_retries; \ + num_retries = 0; \ + error = 0; \ + while (num_retries++ < num_ret) { \ + if (func == BLE_STATUS_SUCCESS) \ + break; \ + if (num_retries == num_ret) \ + error = BLE_UTIL_ACI_ERROR; \ + } \ +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, + they are extended with 0xFF until sector size is reached +*/ +static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) +{ + uint32_t i, j, a1; + uint32_t crc, value; + + crc = 0; + for (i = 0; i < SECTOR_SIZE; i += 4) { + uint8_t *dataw = (uint8_t *) &value; + + dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; + dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; + dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; + dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; + + crc = crc ^ value; + for (j = 0; j < 32; j ++) { + a1 = (crc >> 31) & 0x1; + crc = (crc << 1) ^ (a1 * CRC_POLY); + } + } + + return crc; +} + +int program_device(const uint8_t *fw_image, uint32_t fw_size) +{ + uint8_t version, num_erase_retries, status, write_block_size; + uint32_t address; + uint32_t crc, crc2, crc_size; + uint32_t fw_offset = FW_OFFSET; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + if(aci_updater_hw_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version==0x31){ + // It does not contain bootloader inside first sector. It may contain code. + fw_offset = FW_OFFSET_MS; + } + + if (fw_size != FULL_STACK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + if (fw_size % MIN_WRITE_BLOCK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + + /*********************************************************************** + * Erase BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + /*********************************************************************** + * Erase and Program sectors + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE) { + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(BASE_ADDRESS + i); + for (int j=i; ((j<i+SECTOR_SIZE)&&(j<fw_size)); j += write_block_size) { + + write_block_size = MIN(fw_size-j, MAX_WRITE_BLOCK_SIZE); + + RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, write_block_size, fw_image+j), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + break; + } + if (status == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + } + + /*********************************************************************** + * Verify firmware + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE){ + address = BASE_ADDRESS + i; + if(aci_updater_calc_crc(address, 1, &crc)) + return BLE_UTIL_ACI_ERROR; + + crc_size = MIN(fw_size-i,SECTOR_SIZE); + + crc2 = updater_calc_crc(fw_image+i,crc_size); + if(crc!=crc2) + return BLE_UTIL_CRC_ERROR; + } + + /*********************************************************************** + * Write BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +int read_IFR(uint8_t *data) +{ + uint8_t version, offset; + tBleStatus ret; + + offset = 0; + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + /*********************************************************************** + * Reading last 3 IFR 64-byte blocks + ************************************************************************/ + for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(BASE_ADDRESS+i, READ_BLOCK_SIZE, (data+offset)); + offset += READ_BLOCK_SIZE; + if(ret) return BLE_UTIL_ACI_ERROR; + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; + +} + +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) +{ + IFR_config->stack_mode = data[0]; + IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); + IFR_config->master_sca = data[30]; + IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); + IFR_config->year = BCD_TO_INT(data[41]); + IFR_config->month = BCD_TO_INT(data[42]); + IFR_config->day = BCD_TO_INT(data[43]); +} + +int IFR_validate(IFR_config2_TypeDef *IFR_config) +{ +#if BLUENRG_MS + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) +#else + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) +#endif + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode + if(IFR_config->master_sca > 7) + return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->day > 31 || IFR_config->day < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + + return BLE_STATUS_SUCCESS; +} + +/* TODO: Function to generate data from given options. */ + +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) +{ + data[0] = IFR_config->stack_mode; + HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); + data[30] = IFR_config->master_sca; + HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); + data[41] = INT_TO_BCD(IFR_config->year); + data[42] = INT_TO_BCD(IFR_config->month); + data[43] = INT_TO_BCD(IFR_config->day); +} + + +int program_IFR(const IFR_config_TypeDef *ifr_image) +{ + uint8_t version, num_erase_retries; + tBleStatus ret; +#if BLUENRG_MS + const uint8_t *ifr_data = (uint8_t *)ifr_image; +#else + uint8_t ifr_data[SECTOR_SIZE]; +#endif + uint8_t hwVersion; + uint16_t fwVersion; + + if(getBlueNRGVersion(&hwVersion, &fwVersion)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + +#ifndef BLUENRG_MS + /*********************************************************************** + * READ IFR data + ************************************************************************/ + for(int i = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_data+i); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + } +#endif + + /*********************************************************************** + * Erase & Flashing IFR sectors + ************************************************************************/ +#ifndef BLUENRG_MS + Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); +#endif + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(IFR_BASE_ADDRESS); + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += MAX_WRITE_BLOCK_SIZE, j += MAX_WRITE_BLOCK_SIZE) { + RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, MAX_WRITE_BLOCK_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); + if (ret != BLE_STATUS_SUCCESS) + break; + } + if (ret == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + + /*********************************************************************** + * Verify IFR + ************************************************************************/ + { + uint8_t ifr_updated[READ_BLOCK_SIZE]; + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE, j += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ifr_data+j, READ_BLOCK_SIZE) != 0) + return BLE_UTIL_WRONG_VERIFY; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) +{ + uint8_t ifr_updated[READ_BLOCK_SIZE]; + uint8_t version, ret = BLE_STATUS_SUCCESS; + + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + for(int i = 0; i < IFR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, READ_BLOCK_SIZE) != 0) + { + ret = BLE_UTIL_WRONG_VERIFY; + break; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return ret; +} + +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) +{ + uint8_t status; + uint8_t hci_version, lmp_pal_version; + uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; + + status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, + &manufacturer_name, &lmp_pal_subversion); + + if (status == BLE_STATUS_SUCCESS) { + *hwVersion = hci_revision >> 8; + *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number + *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number + *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number + } + + return status; +} + +uint8_t getBlueNRGUpdaterVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(version)) + return BLE_UTIL_ACI_ERROR; + + if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_updater_hw_version(version)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t isHWBootloader_Patched(void) +{ + uint8_t status, version; + uint32_t crc, address = 0x10010000; + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); + if (status != BLE_STATUS_SUCCESS) + return 0; + + if (crc == BOOTLOADER_CRC_NOT_PATCHED) + return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +#include "ble_gp_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function sets a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * @param[in] t A pointer to the timer + * @param[in] interval The interval before the timer expires. + * + */ +void +Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +Timer_Expired(struct timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + tClockTime diff = (Clock_Time() - t->start) + 1; + return t->interval < diff; + +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +tClockTime +Timer_Remaining(struct timer *t) +{ + return t->start + t->interval - Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +#ifdef __DMA_LP__ + +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID) +{ + TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, + (pf_TIMER_TimerCallBack_t) timercb); + TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); + + return (BLE_STATUS_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) +{ + TIMER_Delete(timerID); + + return (BLE_STATUS_SUCCESS); +} + +#endif /* __DMA_LP__ */ +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,119 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Circular Linked List Implementation. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/****************************************************************************** + * Include Files +******************************************************************************/ +#include <ble_hal_types.h> +#include "ble_list.h" + +/****************************************************************************** + * Function Definitions +******************************************************************************/ +void list_init_head (tListNode * listHead) +{ + listHead->next = listHead; + listHead->prev = listHead; +} + +uint8_t list_is_empty (tListNode * listHead) +{ + return ((listHead->next == listHead)? TRUE:FALSE); +} + +void list_insert_head (tListNode * listHead, tListNode * node) +{ + node->next = listHead->next; + node->prev = listHead; + listHead->next = node; + (node->next)->prev = node; +} + + +void list_insert_tail (tListNode * listHead, tListNode * node) +{ + node->next = listHead; + node->prev = listHead->prev; + listHead->prev = node; + (node->prev)->next = node; +} + + +void list_remove_node (tListNode * node) +{ + (node->prev)->next = node->next; + (node->next)->prev = node->prev; +} + + +void list_remove_head (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->next; + list_remove_node (listHead->next); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_remove_tail (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->prev; + list_remove_node (listHead->prev); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_insert_node_after (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node->next; + node->prev = ref_node; + ref_node->next = node; + (node->next)->prev = node; +} + + +void list_insert_node_before (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node; + node->prev = ref_node->prev; + ref_node->prev = node; + (node->prev)->next = node; +} + + +int list_get_size (tListNode * listHead) +{ + int size = 0; + tListNode * temp = listHead->next; + while (temp != listHead) + { + size++; + temp = temp->next; + } + return (size); +} + +void list_get_next_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->next; +} + + +void list_get_prev_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->prev; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,72 @@ +/** +****************************************************************************** +* @file ble_osal.c +* @author AMS - HEA&RF BU / CL +* @version V1.0.0 +* @date 04-July-2014 +* @brief Implementation of OS abstraction layer functions used by the +* library. +****************************************************************************** +* @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> +#include <ble_osal.h> + + /** + * @brief Osal_MemCpy + * @param dest: Pointer to the destination buffer + * @param src : Pointer to the source buffer + * @param size: Number of bytes to copy from the source to the destination + * buffer + * @retval Pointer to the destination buffer + */ +void* Osal_MemCpy(void *dest, const void *src, unsigned int size) +{ + return(memcpy(dest,src,size)); +} + +/** + * @brief Osal_MemSet + * @param ptr : Pointer to block of memory to fill + * @param value: Value to assign to each byte of the memory block + * @param size : Number of bytes to be set to "value" + * @retval Pointer to the filled block of memory + */ +void* Osal_MemSet(void *ptr, int value, unsigned int size) +{ + return(memset(ptr,value,size)); +} + +/****************************************************************************** + * local Functions + *****************************************************************************/ + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ + +#include "ble_clock.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/wait_api.h" + #include "mbed-drivers/rtc_time.h" +#else + #include "wait_api.h" + #include "rtc_time.h" +#endif + +const uint32_t CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + //Not Used +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return clock(); +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,715 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file btle.cpp + * @author STMicroelectronics + * @brief Implementation BlueNRG Init and helper functions. + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + + +#include "btle.h" +#include "ble/Gap.h" +#include "ble/GapEvents.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" + +#include "bluenrg_targets.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* C File Includes ------------------------------------------------------------------*/ +#include <stdio.h> +#include <string.h> +#include "ble_hci.h" +#include "ble_hci_const.h" +#include "bluenrg_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" +#include "bluenrg_utils.h" + +#include "ble_hal_types.h" +#include "ble_hal.h" +#include "ble_gp_timer.h" +#include "ble_osal.h" +#include "ble_sm.h" +#include "ble_debug.h" + +#ifdef __cplusplus +} +#endif + +#define IDB04A1 0 +#define IDB05A1 1 + +/* See file 'bluenrg_targets.h' for details regarding the BLUENRG_STACK_MODE */ +#define STACK_MODE BLUENRG_STACK_MODE + +void HCI_Input(tHciDataPacket * hciReadPacket); + +uint16_t g_gap_service_handle = 0; +uint16_t g_appearance_char_handle = 0; +uint16_t g_device_name_char_handle = 0; +uint16_t g_preferred_connection_parameters_char_handle = 0; + +/* Private variables ---------------------------------------------------------*/ +volatile uint8_t set_connectable = 1; + +static char versionString[32]; +uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ + +/**************************************************************************/ +/*! + @brief Init the BTLE stack with the specified role + @returns void +*/ +/**************************************************************************/ +void btleInit(void) +{ + PRINTF("btleInit>>\n\r"); + + int ret; + uint8_t hwVersion; + uint16_t fwVersion; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* get the BlueNRG HW and FW versions */ + getBlueNRGVersion(&hwVersion, &fwVersion); + + /* + * Reset BlueNRG again otherwise we won't + * be able to change its MAC address. + * aci_hal_write_config_data() must be the first + * command after reset otherwise it will fail. + */ + BlueNRG_RST(); + + if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ + bnrg_expansion_board = IDB05A1; + } + + /* set BLE version string */ + setVersionString(hwVersion, fwVersion); + + if (bnrg_expansion_board == IDB05A1) { + uint8_t stackMode = STACK_MODE; + ret = aci_hal_write_config_data(CONFIG_DATA_MODE_OFFSET, + CONFIG_DATA_MODE_LEN, + &stackMode); + } + + ret = aci_gatt_init(); + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GATT_Init failed.\n"); + } + if (bnrg_expansion_board == IDB05A1) { + ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1, + 0, + 0x18, + &service_handle, + &dev_name_char_handle, + &appearance_char_handle); + } else { + // IDB04A1 is configured as peripheral by default + ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + } + + // read the default static address and inject it into the GAP object + { + Gap::Address_t BLE_address_BE = { 0 }; + uint8_t data_len_out; + aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS, BDADDR_SIZE, &data_len_out, BLE_address_BE); + // FIXME error handling of this function + BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE); + } + + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GAP_Init failed.\n"); + } + + //FIXME: Security and passkey set by default + ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, + OOB_AUTH_DATA_ABSENT, + NULL, + 7, + 16, + USE_FIXED_PIN_FOR_PAIRING, + 123456, + BONDING); + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Auth Req set failed.\n"); + } + + aci_hal_set_tx_power_level(1,4); + + g_gap_service_handle = service_handle; + g_appearance_char_handle = appearance_char_handle; + g_device_name_char_handle = dev_name_char_handle; + //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API + /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, + strlen(name), (tHalUint8 *)name);*/ + + signalEventsToProcess(); + // update the peripheral preferred conenction parameters handle + // This value is hardcoded at the moment. + g_preferred_connection_parameters_char_handle = 10; + + return; +} + +/**************************************************************************/ +/*! + @brief mbedOS + + @param[in] void + + @returns +*/ +/**************************************************************************/ +int btle_handler_pending = 0; + +void btle_handler(void) +{ + btle_handler_pending = 0; + BlueNRGGap::getInstance().Process(); + HCI_HandleSPI(); + HCI_Process(); +} + +/* set BLE Version string */ +void setVersionString(uint8_t hwVersion, uint16_t fwVersion) +{ + if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) { + snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u", + hwVersion>>4, (hwVersion&0x0F), + fwVersion>>8, (fwVersion&0x00F0)>>4); + } else { + snprintf(versionString, sizeof(versionString), "ST (unknown spec)"); + } +} + +/* get BLE Version string */ +const char* getVersionString(void) +{ + return versionString; +} + +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type) +{ + tBleStatus ret; + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + if(bnrg_expansion_board == IDB05A1) { + PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window); + PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type); + ret = aci_gap_start_observation_procedure(scan_interval, + scan_window, + scan_type, + own_address_type, + 0); // 1 to filter duplicates + } else { + ret = BLE_STATUS_INVALID_CID; + } + + return ret; + +} + +/*! + @brief Not Used + + @param[in] void + + @returns +*/ +void SPI_Poll(void) +{ + //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); + return; +} + +void Attribute_Modified_CB(evt_blue_aci *blue_evt) +{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t *att_data; + uint8_t offset; + + if (bnrg_expansion_board == IDB05A1) { + evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = evt->offset; + } else { + evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = 0; + } + + //Extract the GattCharacteristic from p_characteristics[] and find the properties mask + GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle); + if(p_char!=NULL) { + GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE; + PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]); + PRINTF("getProperties 0x%x\n\r",p_char->getProperties()); + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; + } + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; + } + PRINTF("currentHandle %d\n\r", currentHandle); + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && + currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { + + GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1; + + PRINTF("*****NOTIFICATION CASE\n\r"); + //Now Check if data written in Enable or Disable + if((uint16_t)att_data[0]==1) { + //PRINTF("Notify ENABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle); + } else { + //PRINTF("Notify DISABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle); + } + return; + } + + //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) && + currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) { + + PRINTF("*****WRITE CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = p_char->getValueAttribute().getHandle(); + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle); + //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + BlueNRGGattServer::getInstance().write( + p_char->getValueAttribute().getHandle(), + (uint8_t*)att_data, + data_length, + false + ); + } + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } else { + PRINTF("*****WRITE DESCRIPTOR CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = attr_handle; + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } + } + +} + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************************/ + /*! + @brief Handle HCI Stack Event + + @param[in] pckt + Event Packet sent by the stack to be decoded + + @returns + */ + /**************************************************************************/ + extern void HCI_Event_CB(void *pckt) { + hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; + hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; + + if(hci_pckt->type != HCI_EVENT_PKT) + return; + + switch(event_pckt->evt){ + + case EVT_DISCONN_COMPLETE: + { + PRINTF("EVT_DISCONN_COMPLETE\n"); + + evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data; + + if(BlueNRGGap::getInstance().getGapRole() == Gap::CENTRAL) { + BlueNRGGattClient::getInstance().removeGattConnectionClient(evt->handle, evt->reason); + } + + BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason); + } + break; + + case EVT_LE_META_EVENT: + { + PRINTF("EVT_LE_META_EVENT\n"); + + evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; + + switch(evt->subevent){ + + case EVT_LE_CONN_COMPLETE: + { + PRINTF("EVT_LE_CONN_COMPLETE\n"); + Gap::Address_t ownAddr; + Gap::AddressType_t ownAddrType; + BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr); + + Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + Gap::Role_t role; + + evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; + + BlueNRGGap::getInstance().setConnectionHandle(cc->handle); + BlueNRGGap::ConnectionParams_t connectionParams = { + /* minConnectionInterval = */ cc->interval, + /* maxConnectionInterval = */ cc->interval, + /* slaveLatency = */ cc->latency, + /* connectionSupervisionTimeout = */ cc->supervision_timeout + }; + + BlueNRGGap::getInstance().setConnectionInterval(cc->interval); + + switch (cc->peer_bdaddr_type) { + case PUBLIC_ADDR: + peerAddrType = BLEProtocol::AddressType::PUBLIC; + break; + case STATIC_RANDOM_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + break; + case RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE; + break; + case NON_RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE; + break; + } + //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role); + switch (cc->role) { + case 0: //master + role = Gap::CENTRAL; + BlueNRGGattClient::getInstance().createGattConnectionClient(cc->handle); + break; + case 1: + role = Gap::PERIPHERAL; + break; + default: + role = Gap::PERIPHERAL; + break; + } + + BlueNRGGap::getInstance().setGapRole(role); + + BlueNRGGap::getInstance().processConnectionEvent(cc->handle, + role, + peerAddrType, + cc->peer_bdaddr, + ownAddrType, + ownAddr, + &connectionParams); + } + break; + + case EVT_LE_ADVERTISING_REPORT: + PRINTF("EVT_LE_ADVERTISING_REPORT\n\r"); + /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */ + // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT) + // Formally the structure related to both events are identical except that for the ADV REPORT + // there is one more field (number of reports) which is not forwarded to upper layer. + // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT. + le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1); + PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + break; + } + } + break; + + case EVT_VENDOR: + { + evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; + //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode); + + switch(blue_evt->ecode){ + + case EVT_BLUE_GATT_WRITE_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_WRITE_PERMIT_REQ\r\n"); + evt_gatt_write_permit_req* write_req = (evt_gatt_write_permit_req*)blue_evt->data; + + // ask the local server if the write operation is authorized + uint8_t err_code = BlueNRGGattServer::getInstance().Write_Request_CB( + write_req->conn_handle, + write_req->attr_handle, + write_req->data_length, + write_req->data + ); + uint8_t write_status = err_code == 0 ? 0 : 1; + + // reply to the shield + aci_gatt_write_response( + write_req->conn_handle, + write_req->attr_handle, + write_status, + err_code, + write_req->data_length, + write_req->data + ); + } + break; + + case EVT_BLUE_GATT_READ_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r"); + evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle); + BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle); + } + break; + + case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: + { + PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r"); + /* this callback is invoked when a GATT attribute is modified + extract callback data and pass to suitable handler function */ + Attribute_Modified_CB(blue_evt); + } + break; + + //Any cases for Data Sent Notifications? + case EVT_BLUE_GATT_NOTIFICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_NOTIFICATION"); + break; + case EVT_BLUE_GATT_INDICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_INDICATION"); + break; + + case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r"); + evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_data_length, + pr->attribute_data_list); + } + break; + case EVT_BLUE_ATT_READ_BY_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r"); + evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle, + pr->event_data_length, + pr->handle_value_pair_length, + pr->handle_value_pair); + } + break; + case EVT_BLUE_ATT_READ_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_RESP\n\r"); + evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_value); + } + break; + case EVT_BLUE_ATT_EXEC_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle, + pr->event_data_length); + } + break; + case EVT_BLUE_ATT_PREPARE_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_handle, + pr->offset, + pr->part_attr_value); + } + break; + case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP: + { + PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r"); + evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle, + pr->event_data_length, + pr->attr_handle, + pr->attr_value); + } + break; + case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r"); + evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle, + pr->event_data_length, + pr->handles_info_list); + } + break; + case EVT_BLUE_ATT_FIND_INFORMATION_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r"); + evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle, + pr->event_data_length, + pr->format, + pr->handle_uuid_pair); + } + break; + case EVT_BLUE_GATT_PROCEDURE_COMPLETE: + { + evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code); + BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code); + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_REQ: + { + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_REQ\r\n"); + evt_l2cap_conn_upd_req *evt = (evt_l2cap_conn_upd_req*)blue_evt->data; + if(bnrg_expansion_board == IDB05A1) { + // we assume the application accepts the request from the slave + aci_l2cap_connection_parameter_update_response_IDB05A1(evt->conn_handle, + evt->interval_min, + evt->interval_max, + evt->slave_latency, + evt->timeout_mult, + CONN_L1, CONN_L2, + evt->identifier, + 0x0000); + } + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_RESP: + { + evt_l2cap_conn_upd_resp *evt = (evt_l2cap_conn_upd_resp*)blue_evt->data; + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_RESP code=0x%x, result=0x%x\r\n", evt->code, evt->result); + } + break; + + case EVT_LE_CONN_UPDATE_COMPLETE: + { + evt_le_connection_update_complete *evt = (evt_le_connection_update_complete*)blue_evt->data; + PRINTF("EVT_LE_CONN_UPDATE_COMPLETE status=0x%x\r\n", evt->status); + } + break; + + case EVT_BLUE_GAP_DEVICE_FOUND: + { + evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data; + PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + } + break; + + case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + { + evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data; + //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code); + + switch(pr->procedure_code) { + case GAP_OBSERVATION_PROC_IDB05A1: + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL); + break; + } + } + break; + } + } + break; + } + return ; + } + + +#ifdef __cplusplus +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,217 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.cpp + * @author CL + * @version V1.0.0 + * @date 15-June-2015 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRGGap.h" +#include "BlueNRGDevice.h" +#include "btle.h" + +// FIXME: find a better way to get the instance of the BlueNRG device +extern BlueNRGDevice bluenrgDeviceInstance; + + +//////////////////////////////////////// +// Start of C function wrappers +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32_bluenrg_ble.h" +#include "ble_debug.h" + + +void BlueNRG_RST(void) +{ + bluenrgDeviceInstance.reset(); +} + +uint8_t BlueNRG_DataPresent(void) +{ + return (bluenrgDeviceInstance.dataPresent()); +} + + +/** + * @brief This function is a utility to print the log time +* in the format HH:MM:SS:MSS (DK GUI time format) + * @param None + * @retval None + */ +void print_csv_time(void){ +#ifdef PRINT_CSV_FORMAT + uint32_t ms = 0;//ms_counter; + PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000); +#endif +} + +/** + * @brief Writes data to a serial interface. + * @param data1 : 1st buffer + * @param data2 : 2nd buffer + * @param n_bytes1: number of bytes in 1st buffer + * @param n_bytes2: number of bytes in 2nd buffer + * @retval None + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, + int32_t n_bytes2) +{ + struct timer t; + + Timer_Set(&t, CLOCK_SECOND/10); + +#ifdef PRINT_CSV_FORMAT + print_csv_time(); + for (int i=0; i<n_bytes1; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data1)[i]); + } + for (int i=0; i<n_bytes2; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data2)[i]); + } + PRINT_CSV("\n"); +#endif + + while(1){ + if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; + if(Timer_Expired(&t)){ + break; + } + } +} + + +/** + * @brief Activate internal bootloader using pin. + * @param None + * @retval None + */ +void BlueNRG_HW_Bootloader(void) +{ + // Reset BlueNRG SPI interface + BlueNRG_RST(); + + // Send an ACI command to reboot BlueNRG in bootloader mode + // The safest way to get in bootloader mode is keeping high + // the interrupt pin during reset, but this would require many + // changes to the current mbed driver + aci_updater_start(); +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size) +{ + int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size); + + return ret; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2); + + return ret; +} + +/** + * @brief Enable SPI IRQ. + * @param None + * @retval None + */ +void Enable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.enable_irq(); +} + +void signalEventsToProcess(void) { + if(btle_handler_pending == 0) { + btle_handler_pending = 1; + bluenrgDeviceInstance.signalEventsToProcess(BLE::DEFAULT_INSTANCE); + } +} + +/** + * @brief Disable SPI IRQ. + * @param None + * @retval None + */ +void Disable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.disable_irq(); +} + +/** + * @brief Clear Pending SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_IRQ(void) +{ +} + +/** + * @brief Clear EXTI (External Interrupt) line for SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_EXTI_Flag(void) +{ +} + + + + +#ifdef __cplusplus +} +#endif +// End of C function wrappers +//////////////////////////////////////// + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <ble_payload.h> + +Payload::Payload() { + stringLength = 0; + payloadUnitCount = 0; + payload = NULL; +} + +Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + stringLength = string_ength; + payloadUnitCount = 0; + payload = NULL; + + int index = 0; + while( index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + UnitPayload *obj = new UnitPayload[payloadUnitCount]; + int i=0; + int c=0; + int j,k; + + while(i<payloadUnitCount) + { + obj[i].length=tokenString[c]; + obj[i].id=tokenString[c+1]; + + obj[i].data = new uint8_t[obj[i].length]; + for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) + { + obj[i].data[k]=tokenString[j]; + + } + + c=c+obj[i].length+1; + i++; + + } + payload = obj; +} + +uint8_t Payload::getPayloadUnitCount() { + return payloadUnitCount; +} + +uint8_t Payload::getIDAtIndex(int index) { + return payload[index].get_id(); +} + +uint8_t Payload::getLengthAtIndex(int index) { + return payload[index].get_length(); +} + +uint8_t* Payload::getDataAtIndex(int index) { + return payload[index].get_data(); +} + +int8_t Payload::getInt8AtIndex(int index) { + uint8_t* str = payload[index].get_data(); + int8_t value = (int8_t)str[0]; + return value; +} + +uint16_t Payload::getUint16AtIndex(int index) { + uint16_t* str = (uint16_t*)payload[index].get_data(); + uint16_t value = str[0]; + return value; +} + +uint8_t* Payload::getSerializedAdDataAtIndex(int index) { + uint8_t length = payload[index].get_length(); + uint8_t* data = payload[index].get_data(); + uint8_t id = payload[index].get_id(); + uint8_t *serializedAdData = new uint8_t[length]; + + serializedAdData[0] = id; + for(int i=0; i<length-1; i++) { + serializedAdData[i+1] = data[i]; + } + return serializedAdData; +} + +Payload::~Payload() { + int i = 0; + + if(payload) { + while(i<payloadUnitCount) { + if(payload->data) { + delete[] payload->data; + payload->data = NULL; + } + } + delete[] payload; + payload = NULL; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,93 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ble_utils.h" + +/**************************************************************************/ +/*! + @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power + +*/ +/**************************************************************************/ +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(dBMLevel==-18) { + EN_HIGH_POWER = 0; + PA_LEVEL = 0; + } + else if(dBMLevel==-15) { + EN_HIGH_POWER = 0; + PA_LEVEL = 1; + } + else if(dBMLevel==-14) { + EN_HIGH_POWER = 1; + PA_LEVEL = 0; + } + else if(dBMLevel==-12) { + EN_HIGH_POWER = 0; + PA_LEVEL = 2; + } + else if(dBMLevel==-11) { + EN_HIGH_POWER = 1; + PA_LEVEL = 1; + } + else if(dBMLevel==-9) { + EN_HIGH_POWER = 0; + PA_LEVEL = 3; + } + else if(dBMLevel==-8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 2; + } + else if(dBMLevel==-6) { + EN_HIGH_POWER = 0; + PA_LEVEL = 4; + } + else if(dBMLevel==-5) { + EN_HIGH_POWER = 1; + PA_LEVEL = 3; + } + else if(dBMLevel==-2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 4; + } + else if(dBMLevel==0) { + EN_HIGH_POWER = 0; + PA_LEVEL = 6; + } + else if(dBMLevel==2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 5; + } + else if(dBMLevel==4) { + EN_HIGH_POWER = 1; + PA_LEVEL = 6; + } + else if(dBMLevel==5) { + EN_HIGH_POWER = 0; + PA_LEVEL = 7; + } + else if(dBMLevel==8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + else { + ret = ERR_INVALID_HCI_CMD_PARAMS; + } + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/source/LEDService.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,43 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLE_LED_SERVICE_H__ +#define __BLE_LED_SERVICE_H__ + +class LEDService { +public: + const static uint16_t LED_SERVICE_UUID = 0xA000; + const static uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xA001; + + LEDService(BLEDevice &_ble, bool initialValueForLEDCharacteristic) : + ble(_ble), ledState(LED_STATE_CHARACTERISTIC_UUID, &initialValueForLEDCharacteristic) + { + GattCharacteristic *charTable[] = {&ledState}; + GattService ledService(LED_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + ble.addService(ledService); + } + + GattAttribute::Handle_t getValueHandle() const + { + return ledState.getValueHandle(); + } + +private: + BLEDevice &ble; + ReadWriteGattCharacteristic<bool> ledState; +}; + +#endif /* #ifndef __BLE_LED_SERVICE_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LED/source/main.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,128 @@ +/* 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 <events/mbed_events.h> +#include <mbed.h> +#include "ble/BLE.h" +#include "LEDService.h" + +DigitalOut alivenessLED(LED1, 0); +DigitalOut actuatedLED(LED2, 0); + +const static char DEVICE_NAME[] = "LED"; +static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID}; + +static EventQueue eventQueue(/* event count */ 10 * EVENTS_EVENT_SIZE); + +LEDService *ledServicePtr; + +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) +{ + (void) params; + BLE::Instance().gap().startAdvertising(); +} + +void blinkCallback(void) +{ + alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */ +} + +/** + * This callback allows the LEDService to receive updates to the ledState Characteristic. + * + * @param[in] params + * Information about the characterisitc being updated. + */ +void onDataWrittenCallback(const GattWriteCallbackParams *params) { + if ((params->handle == ledServicePtr->getValueHandle()) && (params->len == 1)) { + actuatedLED = *(params->data); + } +} + +/** + * This function is called when the ble initialization process has failled + */ +void onBleInitError(BLE &ble, ble_error_t error) +{ + /* Initialization error handling should go here */ +} + +void printMacAddress() +{ + /* Print out device MAC address to the console*/ + Gap::AddressType_t addr_type; + Gap::Address_t address; + BLE::Instance().gap().getAddress(&addr_type, address); + printf("DEVICE MAC ADDRESS: "); + for (int i = 5; i >= 1; i--){ + printf("%02x:", address[i]); + } + printf("%02x\r\n", address[0]); +} + +/** + * Callback triggered when the ble initialization process has finished + */ +void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) +{ + BLE& ble = params->ble; + ble_error_t error = params->error; + + if (error != BLE_ERROR_NONE) { + /* In case of error, forward the error handling to onBleInitError */ + onBleInitError(ble, error); + return; + } + + /* Ensure that it is the default instance of BLE */ + if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { + return; + } + + ble.gap().onDisconnection(disconnectionCallback); + ble.gattServer().onDataWritten(onDataWrittenCallback); + + bool initialValueForLEDCharacteristic = false; + ledServicePtr = new LEDService(ble, initialValueForLEDCharacteristic); + + /* setup advertising */ + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.gap().setAdvertisingInterval(1000); /* 1000ms. */ + ble.gap().startAdvertising(); + + printMacAddress(); +} + +void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { + BLE &ble = BLE::Instance(); + eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); +} + +int main() +{ + eventQueue.call_every(500, blinkCallback); + + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(scheduleBleEventsProcessing); + ble.init(bleInitComplete); + + eventQueue.dispatch_forever(); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/.mbed Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +ROOT=.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/mbed-os.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/mbed_app.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "target_overrides": { + "K64F": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "NUCLEO_F401RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "DISCO_L475VG_IOT01A": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,15 @@ +{ + "name": "ble-ledblinker", + "version": "0.0.1", + "description": "An initial demo showcasing the GattClient APIs. Drives an LED service exported by a BLE_LED peripheral. Shows scanning, connections, service-discovery, and reads/writes.", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "dependencies": { + "ble": "^2.0.0" + }, + "bin": "./source" +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/readme.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,54 @@ +# BLE LED Blinker + +This example demonstrates using the ``GattClient`` API to control BLE client devices. + +The example uses two applications running on two different devices: + +1. The first device - the central - runs the application ``BLE_LEDBlinker`` from this repository. This application sends an on/off toggle over BLE. + +1. The second device - the peripheral - runs the application [``BLE_LED``](https://github.com/ARMmbed/mbed-os-example-ble/tree/master/BLE_LED) to respond to the toggle. + + The toggle simply turns the LED on the peripheral device on and off. + +# Running the application + +## Requirements + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +This example requires *two* devices. + +## Building instructions + +You will need to build both applications and flash each one to a different board. + +Please note: The application ``BLE_LEDBlinker`` in this repository initiate a connection to all ble devices which advertise "LED" as complete local name. By default, the application `BLE_LED` advertise "LED" as complete local name. If you change the local name advertised by the application `BLE_LED` you should reflect your change in this application by changing the value of the constant `PEER_NAME` in `main.cpp`. + +**Tip:** You may notice that the application also checks the LED characteristic's UUID; you don't need to change this parameter's value, because it already matches the UUID provided by the second application, ``BLE_LED``. + +Building instructions for all mbed OS samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Checking for success + +1. Build both applications and install one on each device, as explained in the building instructions. + +1. The LED number two of the device running ``BLE_LED`` should blink. + + +## Monitoring the application through a serial port + +You can run ``BLE_LEDBlinker`` and see that it works properly by monitoring its serial output. + +You need a terminal program to listen to the output through a serial port. You can download one, for example: + +* Tera Term for Windows. +* CoolTerm for Mac OS X. +* GNU Screen for Linux. + +To see the application's output: + +1. Check which serial port your device is connected to. +1. Run a terminal program with the correct serial port and set the baud rate to 9600. For example, to use GNU Screen, run: ``screen /dev/tty.usbmodem1412 9600``. +1. The application should start printing the toggle's value to the terminal. + +**Note:** ``BLE_LEDBlinker`` will not run properly if the ``BLE_LED`` application is not running on a second device. The terminal will show a few print statements, but you will not be able to see the application in full operation.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/#b630517008bbe47592927cc8e5dfcd2e5b9de968
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/.gitignore Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,9 @@ +# vim temporary files +*.sw* + +# yotta files +build +yotta_modules +yotta_targets +.yotta.json +upload.tar.gz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,34 @@ +# BLE-X-NUCLEO-IDB0XA1 + +BLE_API wrapper Library for X-NUCLEO-IDB05A1 BlueNRG (Bluetooth Low Energy) Expansion Board + +## Introduction + +This firmware package implements the port of BLE_API to STMicroelectronics' [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) Bluetooth Low Energy Nucleo Expansion Board. + +### Arduino Connector Compatibility Warning + +X-NUCLEO-IDB05A1 is Arduino compatible with an exception: instead of using pin **D13** for the SPI clock, pin **D3** is used. +The default configuration for this library is having the SPI clock on pin **D3**. + +To be fully Arduino compatible, X-NUCLEO-IDB05A1 needs a small HW patch. + +For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor **R4** and instead soldering zero resistor **R6**. + +In case you patch your board, then you also have to configure this library to use pin **D13** to drive the SPI clock. To this aim you need to compile this driver with macro `BLUENRG_PIN_SPI_SCK=D13` defined. + +If you use pin **D13** for the SPI clock, please be aware that on STM32 Nucleo boards you may **not** drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin **D13**. + +Referring to the current list of tested platforms (see [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) page), the patch is required by [ST-Nucleo-F103RB](https://developer.mbed.org/platforms/ST-Nucleo-F103RB/); [ST-Nucleo-F302R8](https://developer.mbed.org/platforms/ST-Nucleo-F302R8/); [ST-Nucleo-F411RE](https://developer.mbed.org/platforms/ST-Nucleo-F411RE/); [ST-Nucleo-F446RE](https://developer.mbed.org/platforms/ST-Nucleo-F446RE/); and [FRDM-K64F](https://developer.mbed.org/platforms/FRDM-K64F/). + +### Firmware update + +For better performance and compatibility with latest mbed API, you should update firmware of X-NUCLEO-IDB05A1 component by using this simple [application](https://developer.mbed.org/teams/ST/code/BlueNRG-MS-Stack-Updater). + +### Driver configuration + +In order to use the BlueNRG-MS module together with other targets, you need to set the macros defined in file [bluenrg_targets.h](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/bluenrg/bluenrg_targets.h). Please, update the [mbed_lib.json](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/mbed_lib.json) to include the list of extra macros that configure the driver for your target. + +## Example Applications + +To run BLE example applications using X-NUCLEO-IDB05A1 Expansion Board based on mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli), please refer to section [Using ST shield on other targets](https://github.com/ARMmbed/mbed-os-example-ble#using-st-nucleo-shield-on-other-targets) in the official [mbed-os-example-ble](https://github.com/ARMmbed/mbed-os-example-ble) page.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.h + * @author STMicroelectronics + * @brief Header file for BLEDeviceInstanceBase based BlueNRGDevice + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_DEVICE_H__ +#define __BLUENRG_DEVICE_H__ + +#define BLUENRG +#define DEBUG_BLUENRG_USER + +#include "btle.h" + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "ble/BLEInstanceBase.h" +#include "ble/BLE.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" + + +class BlueNRGDevice : public BLEInstanceBase +{ + +public: + BlueNRGDevice(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, PinName irq); + virtual ~BlueNRGDevice(void); + + virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback); + virtual ble_error_t shutdown(void); + virtual const char *getVersion(void); + virtual Gap& getGap(); + virtual const Gap& getGap() const; + virtual GattServer& getGattServer(); + virtual const GattServer& getGattServer() const; + virtual void waitForEvent(void); + + virtual GattClient& getGattClient() { + return BlueNRGGattClient::getInstance(); + } + + virtual SecurityManager& getSecurityManager() { + return *sm; + } + + virtual const SecurityManager& getSecurityManager() const { + return *sm; + } + void reset(void); + virtual bool hasInitialized(void) const { + return isInitialized; + } + + uint8_t getUpdaterHardwareVersion(uint8_t *hw_version); + int updateFirmware(const uint8_t *fw_image, uint32_t fw_size); + bool dataPresent(); + int32_t spiRead(uint8_t *buffer, uint8_t buff_size); + int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2); + void disable_irq(); + void enable_irq(); + + virtual void processEvents(); + +private: + bool isInitialized; + + SPI spi_; + DigitalOut nCS_; + DigitalOut rst_; + InterruptIn irq_; + + //FIXME: TBI (by now just placeholders to let build + /*** betzw: placeholders ***/ + SecurityManager *sm; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ +#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ + +#include "ble/DiscoveredCharacteristic.h" + +class BlueNRGGattClient; /* forward declaration */ + +class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic { +public: + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + + void setLastHandle(GattAttribute::Handle_t lastHandleIn); +}; + +#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGGap.h + * @author STMicroelectronics + * @brief Header file for BlueNRG BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GAP_H__ +#define __BLUENRG_GAP_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/Gap.h" + +#define BLE_CONN_HANDLE_INVALID 0x0 +#define BDADDR_SIZE 6 + +#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020) +#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000) +#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0) + +// Scanning and Connection Params used by Central for creating connection +#define GAP_OBSERVATION_PROC (0x80) + +#define SCAN_P (0x0010) +#define SCAN_L (0x0010) +#define SUPERV_TIMEOUT (0xC80) +#define CONN_P(x) ((int)((x)/1.25f)) +#define CONN_L(x) ((int)((x)/0.625f)) +#define CONN_P1 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_P2 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_L1 (0x0008) +#define CONN_L2 (0x0008) +#define GUARD_INT 5 //msec +#define MIN_INT_CONN 0x0006 //=>7.5msec +#define MAX_INT_CONN 0x0C80 //=>4000msec +#define DEF_INT_CONN 0x0140 //=>400msec (default value for connection interval) + +/**************************************************************************/ +/*! + \brief + +*/ +/**************************************************************************/ +class BlueNRGGap : public Gap +{ +public: + static BlueNRGGap &getInstance() { + static BlueNRGGap m_instance; + return m_instance; + } + + enum Reason_t { + DEVICE_FOUND, + DISCOVERY_COMPLETE + }; + + /* Functions that must be implemented from Gap */ + virtual ble_error_t setAddress(addr_type_t type, const BLEProtocol::AddressBytes_t address); + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address); + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &); + virtual ble_error_t startAdvertising(const GapAdvertisingParams &); + virtual ble_error_t stopAdvertising(void); + virtual ble_error_t stopScan(); + virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);} + virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);} + virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);} + virtual ble_error_t disconnect(DisconnectionReason_t reason); + virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason); + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params); + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); + + virtual ble_error_t setDeviceName(const uint8_t *deviceName); + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); + virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance); + virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP); + + virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode); + virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode); + virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const; + virtual ScanningPolicyMode_t getScanningPolicyMode(void) const; + + virtual ble_error_t setTxPower(int8_t txPower); + virtual void getPermittedTxPowerValues(const int8_t **, size_t *); + + virtual ble_error_t connect(const Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams); + + virtual ble_error_t reset(void); + + void Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI); + ble_error_t createConnection(void); + + void setConnectionHandle(uint16_t con_handle); + uint16_t getConnectionHandle(void); + + bool getIsSetAddress(); + + // ADV timeout handling + Timeout& getAdvTimeout(void) { + return advTimeout; + } + uint8_t getAdvToFlag(void) { + return AdvToFlag; + } + void setAdvToFlag(void); + + // SCAN timeout handling + Timeout& getScanTimeout(void) { + return scanTimeout; + } + uint8_t getScanToFlag(void) { + return ScanToFlag; + } + void setScanToFlag(void); + + void Process(void); + + GapScanningParams* getScanningParams(void); + + virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams); + + void setConnectionInterval(uint16_t interval); + Gap::Role_t getGapRole(void); + void setGapRole(Gap::Role_t role); + +private: + uint16_t m_connectionHandle; + Role_t gapRole; + AddressType_t addr_type; + Address_t _peerAddr; + AddressType_t _peerAddrType; + uint8_t bdaddr[BDADDR_SIZE]; + bool _scanning; + bool _connecting; + bool isSetAddress; + uint8_t deviceAppearance[2]; + + // ADV timeout handling + Timeout advTimeout; + bool AdvToFlag; + + // SCAN timeout handling + Timeout scanTimeout; + bool ScanToFlag; + + static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) { + return (duration * 625) / 1000; + } + + uint16_t scanInterval; + uint16_t scanWindow; + uint16_t advInterval; + uint16_t slaveConnIntervMin; + uint16_t slaveConnIntervMax; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + void setAdvParameters(void); + void setConnectionParameters(void); + + Gap::AdvertisingPolicyMode_t advertisingPolicyMode; + Gap::ScanningPolicyMode_t scanningPolicyMode; + + Whitelist_t whitelistAddresses; + + ble_error_t updateAdvertisingData(void); + + BlueNRGGap() : AdvToFlag(false), ScanToFlag(false) { + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + addr_type = BLEProtocol::AddressType::RANDOM_STATIC; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + isSetAddress = false; + memset(deviceAppearance, 0, sizeof(deviceAppearance)); + } + + BlueNRGGap(BlueNRGGap const &); + void operator=(BlueNRGGap const &); + + GapAdvertisingData _advData; + GapAdvertisingData _scanResponse; +}; + +#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,157 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattClient.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CLIENT_H__ +#define __BLUENRG_GATT_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattConnectionClient.h" + +using namespace std; + +#define MAX_ACTIVE_CONNECTIONS 7 + +class BlueNRGGattClient : public GattClient +{ +public: + static BlueNRGGattClient &getInstance() { + static BlueNRGGattClient m_instance; + return m_instance; + } + + ble_error_t createGattConnectionClient(Gap::Handle_t connectionHandle); + ble_error_t removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason); + + /* Functions that must be implemented from GattClient */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + virtual bool isServiceDiscoveryActive(void) const; + virtual void terminateServiceDiscovery(void); + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback); + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + virtual ble_error_t write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + virtual ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + virtual ble_error_t reset(void); + + void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code); + + void primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(Gap::Handle_t connectionHandle); + + void serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length); + + +protected: + + BlueNRGGattClient(): _connectionPool() {}; + + ServiceDiscovery::TerminationCallback_t terminationCallback; + +private: + + BlueNRGGattClient(BlueNRGGattClient const &); + void operator=(BlueNRGGattClient const &); + + BlueNRGGattConnectionClient *_connectionPool[MAX_ACTIVE_CONNECTIONS]; + uint8_t _numConnections; + + BlueNRGGattConnectionClient * getGattConnectionClient(Gap::Handle_t connectionHandle); + +}; + +#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,185 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattConnectionClient.cpp + * @author STMicroelectronics + * @brief Header file for BlueNRGGattConnectionClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CONNECTION_CLIENT_H__ +#define __BLUENRG_GATT_CONNECTION_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" + +using namespace std; + +#define BLE_TOTAL_DISCOVERED_SERVICES 10 +#define BLE_TOTAL_DISCOVERED_CHARS 10 + +class BlueNRGGattConnectionClient +{ +public: + + enum { + GATT_IDLE, + GATT_SERVICE_DISCOVERY, + GATT_CHAR_DESC_DISCOVERY, + //GATT_CHARS_DISCOVERY_COMPLETE, + //GATT_DISCOVERY_TERMINATED, + GATT_READ_CHAR, + GATT_WRITE_CHAR + }; + + /* Functions that must be implemented from GattClient */ + ble_error_t launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + bool isServiceDiscoveryActive(void) const; + void terminateServiceDiscovery(void); + void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + } + ble_error_t read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + ble_error_t write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + ble_error_t reset(void); + + void gattProcedureCompleteCB(uint8_t error_code); + + void primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(void); + + void serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(uint8_t event_data_length); + +protected: + + BlueNRGGattConnectionClient(BlueNRGGattClient *gattClient, Gap::Handle_t connectionHandle): + discoveredService(), + discoveredChar(), + readCBParams(), + writeCBParams(), + _characteristic() { + + //PRINTF("BlueNRGGattConnectionClient construtor: connHandle=%d\n\r", connectionHandle); + + _gattClient = gattClient; + _connectionHandle = connectionHandle; + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + } + + ServiceDiscovery::ServiceCallback_t serviceDiscoveryCallback; + ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback; + ServiceDiscovery::TerminationCallback_t terminationCallback; + CharacteristicDescriptorDiscovery::DiscoveryCallback_t charDescDiscoveryCallback; + CharacteristicDescriptorDiscovery::TerminationCallback_t charDescTerminationCallback; + +private: + + BlueNRGGattConnectionClient(BlueNRGGattConnectionClient const &); + void operator=(BlueNRGGattConnectionClient const &); + ~BlueNRGGattConnectionClient() {}; + + BlueNRGGattClient *_gattClient; + + Gap::Handle_t _connectionHandle; + DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES]; + BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS]; + + GattReadCallbackParams readCBParams; + GattWriteCallbackParams writeCBParams; + + // The char for which the descriptor discovery has been launched + DiscoveredCharacteristic _characteristic; + + UUID _matchingServiceUUID; + UUID _matchingCharacteristicUUIDIn; + uint8_t _currentState; + uint8_t _numServices, _servIndex; + uint8_t _numChars; + uint8_t _numCharDesc; + + friend class BlueNRGGattClient; +}; + +#endif /* __BLUENRG_GATT_CONNECTION_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_SERVER_H__ +#define __BLUENRG_GATT_SERVER_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattService.h" +#include "ble/GattServer.h" +#include <vector> +#include <map> + +#define BLE_TOTAL_CHARACTERISTICS 10 + +using namespace std; + +class BlueNRGGattServer : public GattServer +{ +public: + static BlueNRGGattServer &getInstance() { + static BlueNRGGattServer m_instance; + return m_instance; + } + + enum HandleEnum_t { + CHAR_HANDLE = 0, + CHAR_VALUE_HANDLE, + CHAR_DESC_HANDLE + }; + + /* Functions that must be implemented from GattServer */ + virtual ble_error_t addService(GattService &); + virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t initializeGATTDatabase(void); + + virtual bool isOnDataReadAvailable() const { + return true; + } + + virtual ble_error_t reset(void); + + /* BlueNRG Functions */ + void eventCallback(void); + //void hwCallback(void *pckt); + ble_error_t Read_Request_CB(uint16_t attributeHandle); + uint8_t Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, + uint8_t data_length, const uint8_t* data + ); + GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle); + void HCIDataWrittenEvent(const GattWriteCallbackParams *params); + void HCIDataReadEvent(const GattReadCallbackParams *params); + void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle); + void HCIDataSentEvent(unsigned count); + +private: + + // compute the number of attribute record needed by a service + static uint16_t computeAttributesRecord(GattService& service); + + + static const int MAX_SERVICE_COUNT = 10; + uint8_t serviceCount; + uint8_t characteristicCount; + uint16_t servHandle, charHandle; + + std::map<uint16_t, uint16_t> bleCharHandleMap; // 1st argument is characteristic, 2nd argument is service + GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS]; + uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS]; + + BlueNRGGattServer() { + serviceCount = 0; + characteristicCount = 0; + }; + + BlueNRGGattServer(BlueNRGGattServer const &); + void operator=(BlueNRGGattServer const &); + + static const int CHAR_DESC_TYPE_16_BIT=0x01; + static const int CHAR_DESC_TYPE_128_BIT=0x02; + static const int CHAR_DESC_SECURITY_PERMISSION=0x00; + static const int CHAR_DESC_ACCESS_PERMISSION=0x03; + static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_CLOCK_H__ +#define __BLE_CLOCK_H__ + +#include <ble_hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __BLE_CLOCK_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file ble_debug.h + * @author CL + * @version V1.0.0 + * @date 04-July-2014 + * @brief This file defines print functions for debug purposes. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLE_DEBUG_H +#define __BLE_DEBUG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> + +/* Exported macro ------------------------------------------------------------*/ +//#define DEBUG +#ifdef DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Print the data travelling over the SPI in the .csv format for the GUI*/ +//#define PRINT_CSV_FORMAT +#ifdef PRINT_CSV_FORMAT +#include <stdio.h> +#define PRINT_CSV(...) printf(__VA_ARGS__) +#else +#define PRINT_CSV(...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __BLE_DEBUG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_gp_timer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : General purpose timer library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_GP_TIMER_H__ +#define __BLE_GP_TIMER_H__ + +#include "ble_clock.h" +#include "ble_status.h" +#ifdef __DMA_LP__ +#include "stm32xx_timerserver.h" +#endif /* __DMA_LP__ */ + +/** + * timer + * + * A structure that represents a timer. Use Timer_Set() to set the timer. + * + */ +struct timer { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + tClockTime start; + tClockTime interval; + +#endif +}; + +typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); + +/** + * Timer_Set + * + * @param[in] t Pointer to a timer structure + * @param[in] interval timeout value + * + * This function sets the timeout value of a timer. + * + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * Timer_Reset + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the time it previously expired. + * + */ +void Timer_Reset(struct timer *t); + +/** + * Timer_Restart + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the current time. + * + */ +void Timer_Restart(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns TRUE if timer is expired, FALSE otherwise. + * + */ +int Timer_Expired(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns the time needed for expiration. + * + * @return Time before timer's expiration. + */ +tClockTime Timer_Remaining(struct timer *t); + +#ifdef __DMA_LP__ +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID); + +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); +#endif /* __DMA_LP__ */ + +#endif /* __BLE_GP_TIMER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,108 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_H__ +#define __BLE_HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void signalEventsToProcess(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __BLE_HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_TYPES_H__ +#define __BLE_HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __BLE_HAL_TYPES_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,126 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.0, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_H_ +#define __BLE_HCI_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ble_hal_types.h" +#include "ble_link_layer.h" +#include <ble_list.h> + +#define HCI_READ_PACKET_SIZE 128 //71 + +/** + * Maximum payload of HCI commands that can be sent. Change this value if needed. + * This value can be up to 255. + */ +#define HCI_MAX_PAYLOAD_SIZE 128 + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_READ_PACKET_SIZE]; + uint8_t data_len; +} tHciDataPacket; + +struct hci_request { + uint16_t ogf; + uint16_t ocf; + int event; + void *cparam; + int clen; + void *rparam; + int rlen; +}; + +typedef enum +{ + BUSY, + AVAILABLE +} HCI_CMD_STATUS_t; + + +/** + * This function must be used to pass the packet received from the HCI + * interface to the BLE Stack HCI state machine. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * + */ +void HCI_Input(tHciDataPacket *hciReadPacket); + +/** + * Initialization function. Must be done before any data can be received from + * BLE controller. + */ +void HCI_Init(void); + +/** + * Callback used to pass events to application. + * + * @param[in] pckt The event. + * + */ +extern void HCI_Event_CB(void *pckt); + +/** + * Processing function that must be called after an event is received from + * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if + * necessary. +*/ +void HCI_Process(void); + +/** + * @brief Check if queue of HCI event is empty or not. + * @note This funtion can be used to check if the event queue from BlueNRG is empty. This + * is useful when checking if it is safe to go to sleep. + * @return TRUE if event queue is empty. FALSE otherwhise. + */ +BOOL HCI_Queue_Empty(void); +/** + * Iterrupt service routine that must be called when the BlueNRG + * reports a packet received or an event to the host through the + * BlueNRG interrupt line. + */ +#ifdef __DMA_LP__ +void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); +void HCI_Process_Notification_Request(void); +void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); +void HCI_Wait_For_Response(void); +#else +void HCI_Isr(void); +void HCI_HandleSPI(void); + +int hci_send_req(struct hci_request *r, BOOL async); +#endif /* __DMA_LP__ */ + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#ifdef __cplusplus +} +#endif + + +#endif /* __BLE_HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,548 @@ +/****************************************************************************** +* +* File Description +* --------------------- +* This file defines constants and functions for HCI layer. +* See Bluetooth Core v 4.0, Vol. 2, Part E. +* +*******************************************************************************/ + +#ifndef __HCI_INTERNAL_H_ +#define __HCI_INTERNAL_H_ + +#include "ble_compiler.h" +#include "ble_hal_types.h" +#include "ble_clock.h" +#include "ble_link_layer.h" +#include "ble_hci.h" + +#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) + + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +typedef __packed struct _hci_uart_pckt{ + uint8_t type; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef __packed struct _hci_command_hdr{ + uint16_t opcode; /* OCF & OGF */ + uint8_t plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef __packed struct _hci_event_pckt{ + uint8_t evt; + uint8_t plen; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef __packed struct _hci_acl_hdr{ + uint16_t handle; /* Handle & Flags(PB, BC) */ + uint16_t dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef __packed struct _disconnect_cp{ + uint16_t handle; + uint8_t reason; +} PACKED disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 + +#define OCF_SET_EVENT_MASK 0x0001 +#define OCF_RESET 0x0003 + +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D +typedef __packed struct _read_transmit_power_level_cp{ + uint16_t handle; + uint8_t type; +} PACKED read_transmit_power_level_cp; +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 +typedef __packed struct _read_transmit_power_level_rp{ + uint8_t status; + uint16_t handle; + int8_t level; +} PACKED read_transmit_power_level_rp; +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 + +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 +#define OCF_HOST_BUFFER_SIZE 0x0033 +#define OCF_HOST_NUM_COMP_PKTS 0x0035 + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef __packed struct _read_local_version_rp{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t manufacturer_name; + uint16_t lmp_pal_subversion; +} PACKED read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_COMMANDS 0x0002 +#define OCF_READ_LOCAL_FEATURES 0x0003 + +#define OCF_READ_BD_ADDR 0x0009 +typedef __packed struct _read_bd_addr_rp{ + uint8_t status; + tBDAddr bdaddr; +} PACKED read_bd_addr_rp; +#define READ_BD_ADDR_RP_SIZE 7 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +#define OCF_READ_RSSI 0x0005 +typedef __packed struct _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef __packed struct _read_rssi_rp{ + uint8_t status; + uint16_t handle; + int8_t rssi; +} PACKED read_rssi_rp; +#define READ_RSSI_RP_SIZE 4 + + +/* LE commands */ +#define OGF_LE_CTL 0x08 + +#define OCF_LE_SET_EVENT_MASK 0x0001 +typedef __packed struct _le_set_event_mask_cp{ + uint8_t mask[8]; +} PACKED le_set_event_mask_cp; +#define LE_SET_EVENT_MASK_CP_SIZE 8 + +#define OCF_LE_READ_BUFFER_SIZE 0x0002 +typedef __packed struct _le_read_buffer_size_rp{ + uint8_t status; + uint16_t pkt_len; + uint8_t max_pkt; +} PACKED le_read_buffer_size_rp; +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 + +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 +typedef __packed struct _le_read_local_supported_features_rp{ + uint8_t status; + uint8_t features[8]; +} PACKED le_read_local_supported_features_rp; +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 + +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 +typedef __packed struct _le_set_random_address_cp{ + tBDAddr bdaddr; +} PACKED le_set_random_address_cp; +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 + +#define OCF_LE_SET_ADV_PARAMETERS 0x0006 +typedef __packed struct _le_set_adv_parameters_cp{ + uint16_t min_interval; + uint16_t max_interval; + uint8_t advtype; + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint8_t chan_map; + uint8_t filter; +} PACKED le_set_adv_parameters_cp; +#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 + +#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 +typedef __packed struct _le_read_adv_channel_tx_power_rp{ + uint8_t status; + int8_t level; +} PACKED le_read_adv_channel_tx_power_rp; +#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 + +#define OCF_LE_SET_ADV_DATA 0x0008 +typedef __packed struct _le_set_adv_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_adv_data_cp; +#define LE_SET_ADV_DATA_CP_SIZE 32 + +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 +typedef __packed struct _le_set_scan_response_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_scan_response_data_cp; +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 + +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A +typedef __packed struct _le_set_advertise_enable_cp{ + uint8_t enable; +} PACKED le_set_advertise_enable_cp; +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 + +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B +typedef __packed struct _le_set_scan_parameters_cp{ + uint8_t type; + uint16_t interval; + uint16_t window; + uint8_t own_bdaddr_type; + uint8_t filter; +} PACKED le_set_scan_parameters_cp; +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 + +#define OCF_LE_SET_SCAN_ENABLE 0x000C +typedef __packed struct _le_set_scan_enable_cp{ + uint8_t enable; + uint8_t filter_dup; +} PACKED le_set_scan_enable_cp; +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 + +#define OCF_LE_CREATE_CONN 0x000D +typedef __packed struct _le_create_connection_cp{ + uint16_t interval; + uint16_t window; + uint8_t initiator_filter; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_create_connection_cp; +#define LE_CREATE_CONN_CP_SIZE 25 + +#define OCF_LE_CREATE_CONN_CANCEL 0x000E + +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F +typedef __packed struct _le_read_white_list_size_rp{ + uint8_t status; + uint8_t size; +} PACKED le_read_white_list_size_rp; +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 + +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 +typedef __packed struct _le_add_device_to_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_add_device_to_white_list_cp; +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 +typedef __packed struct _le_remove_device_from_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_remove_device_from_white_list_cp; +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_CONN_UPDATE 0x0013 +typedef __packed struct _le_connection_update_cp{ + uint16_t handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_connection_update_cp; +#define LE_CONN_UPDATE_CP_SIZE 14 + +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 +typedef __packed struct _le_set_host_channel_classification_cp{ + uint8_t map[5]; +} PACKED le_set_host_channel_classification_cp; +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 + +#define OCF_LE_READ_CHANNEL_MAP 0x0015 +typedef __packed struct _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef __packed struct _le_read_channel_map_rp{ + uint8_t status; + uint16_t handle; + uint8_t map[5]; +} PACKED le_read_channel_map_rp; +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 + +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 +typedef __packed struct _le_read_remote_used_features_cp{ + uint16_t handle; +} PACKED le_read_remote_used_features_cp; +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 + +#define OCF_LE_ENCRYPT 0x0017 +typedef __packed struct _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef __packed struct _le_encrypt_rp{ + uint8_t status; + uint8_t encdata[16]; +} PACKED le_encrypt_rp; +#define LE_ENCRYPT_RP_SIZE 17 + +#define OCF_LE_RAND 0x0018 +typedef __packed struct _le_rand_rp{ + uint8_t status; + uint8_t random[8]; +} PACKED le_rand_rp; +#define LE_RAND_RP_SIZE 9 + +#define OCF_LE_START_ENCRYPTION 0x0019 +typedef __packed struct _le_start_encryption_cp{ + uint16_t handle; + uint8_t random[8]; + uint16_t diversifier; + uint8_t key[16]; +} PACKED le_start_encryption_cp; +#define LE_START_ENCRYPTION_CP_SIZE 28 + +#define OCF_LE_LTK_REPLY 0x001A +typedef __packed struct _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef __packed struct _le_ltk_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_reply_rp; +#define LE_LTK_REPLY_RP_SIZE 3 + +#define OCF_LE_LTK_NEG_REPLY 0x001B +typedef __packed struct _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef __packed struct _le_ltk_neg_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_neg_reply_rp; +#define LE_LTK_NEG_REPLY_RP_SIZE 3 + +#define OCF_LE_READ_SUPPORTED_STATES 0x001C +typedef __packed struct _le_read_supported_states_rp{ + uint8_t status; + uint8_t states[8]; +} PACKED le_read_supported_states_rp; +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 + +#define OCF_LE_RECEIVER_TEST 0x001D +typedef __packed struct _le_receiver_test_cp{ + uint8_t frequency; +} PACKED le_receiver_test_cp; +#define LE_RECEIVER_TEST_CP_SIZE 1 + +#define OCF_LE_TRANSMITTER_TEST 0x001E +typedef __packed struct _le_transmitter_test_cp{ + uint8_t frequency; + uint8_t length; + uint8_t payload; +} PACKED le_transmitter_test_cp; +#define LE_TRANSMITTER_TEST_CP_SIZE 3 + +#define OCF_LE_TEST_END 0x001F +typedef __packed struct _le_test_end_rp{ + uint8_t status; + uint16_t num_pkts; +} PACKED le_test_end_rp; +#define LE_TEST_END_RP_SIZE 3 + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3f + + +/*------------- Events -------------*/ +#define EVT_CONN_COMPLETE 0x03 +typedef __packed struct _evt_conn_complete{ + uint8_t status; + uint16_t handle; + tBDAddr bdaddr; + uint8_t link_type; + uint8_t encr_mode; +} PACKED evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef __packed struct _evt_disconn_complete{ + uint8_t status; + uint16_t handle; + uint8_t reason; +} PACKED evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef __packed struct _evt_encrypt_change{ + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} PACKED evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C + +#define EVT_CMD_COMPLETE 0x0E +typedef __packed struct _evt_cmd_complete{ + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef __packed struct _evt_cmd_status{ + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef __packed struct _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef __packed struct _evt_num_comp_pkts{ + uint8_t num_hndl; + /* variable length part */ +} PACKED evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +/* variable length part of evt_num_comp_pkts. */ +typedef __packed struct _evt_num_comp_pkts_param{ + uint16_t hndl; + uint16_t num_comp_pkts; +} PACKED evt_num_comp_pkts_param; +#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 + +#define EVT_DATA_BUFFER_OVERFLOW 0x1A +typedef __packed struct _evt_data_buffer_overflow{ + uint8_t link_type; +} PACKED evt_data_buffer_overflow; +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 + +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef __packed struct _evt_encryption_key_refresh_complete{ + uint8_t status; + uint16_t handle; +} PACKED evt_encryption_key_refresh_complete; +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 + +#define EVT_LE_META_EVENT 0x3E +typedef __packed struct _evt_le_meta_event{ + uint8_t subevent; + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef __packed struct _evt_le_connection_complete{ + uint8_t status; + uint16_t handle; + uint8_t role; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; +} PACKED evt_le_connection_complete; +#define EVT_LE_CONN_COMPLETE_SIZE 18 + +#define EVT_LE_ADVERTISING_REPORT 0x02 +typedef __packed struct _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t data_length; + uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef __packed struct _evt_le_connection_update_complete{ + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; +} PACKED evt_le_connection_update_complete; +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 + +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +typedef __packed struct _evt_le_read_remote_used_features_complete{ + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} PACKED evt_le_read_remote_used_features_complete; +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 + +#define EVT_LE_LTK_REQUEST 0x05 +typedef __packed struct _evt_le_long_term_key_request{ + uint16_t handle; + uint8_t random[8]; + uint16_t ediv; +} PACKED evt_le_long_term_key_request; +#define EVT_LE_LTK_REQUEST_SIZE 12 + +/** +* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, +* application can use @ref evt_blue_aci structure to parse the packet. +*/ +#define EVT_VENDOR 0xFF + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + + + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); + +typedef enum { + WAITING_TYPE, + WAITING_OPCODE1, + WAITING_OPCODE2, + WAITING_EVENT_CODE, + WAITING_HANDLE, + WAITING_HANDLE_FLAG, + WAITING_PARAM_LEN, + WAITING_DATA_LEN1, + WAITING_DATA_LEN2, + WAITING_PAYLOAD +}hci_state; + +typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); + +/* HCI library functions. */ + +int hci_send_req(struct hci_request *r, BOOL async); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,170 @@ +/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +* File Name : ble_hci_le.h +* Author : AMG RF FW team +* Version : V1.1.0 +* Date : 18-July-2016 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.1, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_LE_H_ +#define __BLE_HCI_LE_H_ + +#include "ble_hal_types.h" +#include "ble_link_layer.h" + +/** + * @defgroup HCI_Error_codes HCI Error codes + * @{ + */ +#define HCI_UNKNOWN_COMMAND 0x01 +#define HCI_NO_CONNECTION 0x02 +#define HCI_HARDWARE_FAILURE 0x03 +#define HCI_PAGE_TIMEOUT 0x04 +#define HCI_AUTHENTICATION_FAILURE 0x05 +#define HCI_PIN_OR_KEY_MISSING 0x06 +#define HCI_MEMORY_FULL 0x07 +#define HCI_CONNECTION_TIMEOUT 0x08 +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a +#define HCI_ACL_CONNECTION_EXISTS 0x0b +#define HCI_COMMAND_DISALLOWED 0x0c +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d +#define HCI_REJECTED_SECURITY 0x0e +#define HCI_REJECTED_PERSONAL 0x0f +#define HCI_HOST_TIMEOUT 0x10 +#define HCI_UNSUPPORTED_FEATURE 0x11 +#define HCI_INVALID_PARAMETERS 0x12 +#define HCI_OE_USER_ENDED_CONNECTION 0x13 +#define HCI_OE_LOW_RESOURCES 0x14 +#define HCI_OE_POWER_OFF 0x15 +#define HCI_CONNECTION_TERMINATED 0x16 +#define HCI_REPEATED_ATTEMPTS 0x17 +#define HCI_PAIRING_NOT_ALLOWED 0x18 +#define HCI_UNKNOWN_LMP_PDU 0x19 +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a +#define HCI_SCO_OFFSET_REJECTED 0x1b +#define HCI_SCO_INTERVAL_REJECTED 0x1c +#define HCI_AIR_MODE_REJECTED 0x1d +#define HCI_INVALID_LMP_PARAMETERS 0x1e +#define HCI_UNSPECIFIED_ERROR 0x1f +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 +#define HCI_UNIT_LINK_KEY_USED 0x26 +#define HCI_QOS_NOT_SUPPORTED 0x27 +#define HCI_INSTANT_PASSED 0x28 +#define HCI_PAIRING_NOT_SUPPORTED 0x29 +#define HCI_TRANSACTION_COLLISION 0x2a +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c +#define HCI_QOS_REJECTED 0x2d +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e +#define HCI_INSUFFICIENT_SECURITY 0x2f +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 +#define HCI_ROLE_SWITCH_PENDING 0x32 +#define HCI_SLOT_VIOLATION 0x34 +#define HCI_ROLE_SWITCH_FAILED 0x35 +#define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 +#define HCI_CONN_REJ_NO_CH_FOUND 0x39 +#define HCI_CONTROLLER_BUSY 0x3A +#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B +#define HCI_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_CONN_TERM_MIC_FAIL 0x3D +#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E +#define HCI_MAC_CONN_FAILED 0x3F +/** + * @} + */ + + +/* + * HCI library functions. + * Each function returns 0 in case of success, otherwise one of the error codes. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(uint8_t enable); + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter); + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter); + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); + +int hci_le_rand(uint8_t random_number[8]); + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); + +int hci_acl_data(const uint8_t * data, uint16_t len); + +int hci_le_set_random_address(tBDAddr bdaddr); + +int hci_read_bd_addr(tBDAddr bdaddr); + +int hci_le_read_white_list_size(uint8_t *size); + +int hci_le_clear_white_list(); + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); + +int hci_le_ltk_request_reply(uint8_t key[16]); + +int hci_le_ltk_request_neg_reply(); + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); + +int hci_le_create_connection_cancel(void); + +int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level); + +int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi); + +int hci_le_read_local_supported_features(uint8_t *features); + +int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); + +int hci_le_read_supported_states(uint8_t states[8]); + +int hci_le_receiver_test(uint8_t frequency); + +int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); + +int hci_le_test_end(uint16_t *num_pkts); + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion); + + + +#endif /* __BLE_HCI_LE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,161 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_link_layer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's link layer. It contains +* definition of functions for link layer, most of which are +* mapped to HCI commands. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef _BLE_LINK_LAYER_H +#define _BLE_LINK_LAYER_H + +#include <ble_status.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + *@name Advertising filter + *Advertising policy for filtering (white list related) + *@{ + */ +#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ +#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ +/** + * @} + */ + + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef uint8_t tBDAddr[6]; + + +/** + *@name Bluetooth address types + * Bluetooth address types + *@{ + */ +#define PUBLIC_ADDR (0) +#define RANDOM_ADDR (1) +#define STATIC_RANDOM_ADDR (1) +#define RESOLVABLE_PRIVATE_ADDR (2) +#define NON_RESOLVABLE_PRIVATE_ADDR (3) +/** + * @} + */ + +/** + *@name Directed advertising types + * Type of advertising during directed advertising + *@{ + */ +#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) +#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) +/** + * @} + */ + +/** + * @name Advertising type + * @{ + */ + +/** + * undirected scannable and connectable + */ +#define ADV_IND (0x00) + +/** + * directed non scannable + */ +#define ADV_DIRECT_IND (0x01) + +/** + * scannable non connectable + */ +#define ADV_SCAN_IND (0x02) + +/** + * non-connectable and no scan response + */ +#define ADV_NONCONN_IND (0x03) + +/** + * scan response + */ +#define SCAN_RSP (0x04) + +/** + * @} + */ + +/* 0X05-0XFF RESERVED */ + +/** + * @name Advertising ranges + * @{ + */ + +/** + * lowest allowed interval value for connectable types(20ms)..multiple of 625us + */ +#define ADV_INTERVAL_LOWEST_CONN (0X0020) + +/** + * highest allowed interval value (10.24s)..multiple of 625us. + */ +#define ADV_INTERVAL_HIGHEST (0X4000) + +/** + * lowest allowed interval value for non connectable types + * (100ms)..multiple of 625us. + */ +#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) + +/** + * @} + */ + +/** + * @name Advertising channels + * @{ + */ +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 +/** + * @} + */ + +/** + * @name Scan_types Scan types + * @{ + */ +#define PASSIVE_SCAN 0 +#define ACTIVE_SCAN 1 +/** + * @} + */ + +/** + * @} + */ + + +#endif /* _BLE_LINK_LAYER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,47 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for linked list library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef _BLE_LIST_H_ +#define _BLE_LIST_H_ + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +uint8_t list_is_empty (tListNode * listHead); + +void list_insert_head (tListNode * listHead, tListNode * node); + +void list_insert_tail (tListNode * listHead, tListNode * node); + +void list_remove_node (tListNode * node); + +void list_remove_head (tListNode * listHead, tListNode ** node ); + +void list_remove_tail (tListNode * listHead, tListNode ** node ); + +void list_insert_node_after (tListNode * node, tListNode * ref_node); + +void list_insert_node_before (tListNode * node, tListNode * ref_node); + +int list_get_size (tListNode * listHead); + +void list_get_next_node (tListNode * ref_node, tListNode ** node); + +void list_get_prev_node (tListNode * ref_node, tListNode ** node); + +#endif /* _BLE_LIST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_OSAL_H__ +#define __BLE_OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __BLE_OSAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,158 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_sm.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's security manager. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_SM_H__ +#define __BLE_SM_H__ + +/****************************************************************************** +* Macros +*****************************************************************************/ + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/* IO capabilities */ +/** + * @anchor IO_capabilities + * @name IO capabilities + * @{ + */ +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define IO_CAP_KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) +/** + * @} + */ + +/** + * @anchor Auth_req + * @name Authentication requirements + * @{ + */ +#define BONDING (0x01) +#define NO_BONDING (0x00) +/** + * @} + */ + +/** + * @anchor MITM_req + * @name MITM protection requirements + * @{ + */ +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor OOB_Data + * @name Out-Of-Band data + * @{ + */ +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) +/** + * @} + */ + +/** + * @anchor Author_req + * @name Authorization requirements + * @{ + */ +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor Conn_authorization + * @name Connection authorization + * @{ + */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) +/** + * @} + */ + +/** + * @anchor Use_fixed_pin + * @name Use fixed pin + * @{ + */ +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +/** + * @} + */ + +/** + * @anchor link_security_status + * @name Link security status + * @{ + */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) +/** + * @} + */ + +/** + * @anchor SMP_pairing_failed_codes + * @name SMP pairing failed reason codes + * @{ + */ +#define PASSKEY_ENTRY_FAILED (0x01) +#define OOB_NOT_AVAILABLE (0x02) +#define AUTH_REQ_CANNOT_BE_MET (0x03) +#define CONFIRM_VALUE_FAILED (0x04) +#define PAIRING_NOT_SUPPORTED (0x05) +#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) +#define CMD_NOT_SUPPORTED (0x07) +#define UNSPECIFIED_REASON (0x08) +#define VERY_EARLY_NEXT_ATTEMPT (0x09) +#define SM_INVALID_PARAMS (0x0A) +/** + * @} + */ + +/** + * @anchor pairing_failed_codes + * @name Pairing failed error codes + * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event + * @{ + */ +#define SM_PAIRING_SUCCESS (0x00) +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,188 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_status.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file with BLE Stack status codes. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_STATUS_H__ +#define __BLE_STATUS_H__ + +#include <ble_hal_types.h> + +/** @addtogroup Middlewares + * @{ + */ + +/** @defgroup ST + * @{ + */ + +/** @defgroup SimpleBlueNRG_HCI + * @{ + */ + +/** @defgroup ble_status Bluetooth Status/Error Codes + * @{ + */ + +typedef uint8_t tBleStatus; + +/* Error Codes as specified by the specification + * according to the spec the error codes range + * from 0x00 to 0x3F + */ +/** + * @name Standard error codes + * @brief Standard error codes. See Core v 4.1, Vol. 2, part D. + * @{ + */ +#define ERR_CMD_SUCCESS (0x00) +#define BLE_STATUS_SUCCESS (0x00) +#define ERR_UNKNOWN_HCI_COMMAND (0x01) +#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) + +#define ERR_AUTH_FAILURE (0x05) +#define ERR_PIN_OR_KEY_MISSING (0x06) +#define ERR_MEM_CAPACITY_EXCEEDED (0x07) +#define ERR_CONNECTION_TIMEOUT (0x08) + +#define ERR_COMMAND_DISALLOWED (0x0C) + +#define ERR_UNSUPPORTED_FEATURE (0x11) +#define ERR_INVALID_HCI_CMD_PARAMS (0x12) +#define ERR_RMT_USR_TERM_CONN (0x13) +#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) +#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) +#define ERR_LOCAL_HOST_TERM_CONN (0x16) + +#define ERR_UNSUPP_RMT_FEATURE (0x1A) + +#define ERR_INVALID_LMP_PARAM (0x1E) +#define ERR_UNSPECIFIED_ERROR (0x1F) + +#define ERR_LL_RESP_TIMEOUT (0x22) +#define ERR_LMP_PDU_NOT_ALLOWED (0x24) + +#define ERR_INSTANT_PASSED (0x28) + +#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) +#define ERR_CONTROLLER_BUSY (0x3A) + +#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) + +#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) + +#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) + + +/** + * @} + */ +/** + * @name Vendor-specific error codes + * @brief Error codes defined by ST related to BlueNRG stack + * @{ + */ +/** + * The command cannot be executed due to the current state of the device. + */ +#define BLE_STATUS_FAILED (0x41) +/** + * Some parameters are invalid. + */ +#define BLE_STATUS_INVALID_PARAMS (0x42) +/** + * It is not allowed to start the procedure (e.g. another the procedure is ongoing + * or cannot be started on the given handle). + */ +#define BLE_STATUS_NOT_ALLOWED (0x46) +/** + * Unexpected error. + */ +#define BLE_STATUS_ERROR (0x47) +#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) + +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +#define BLE_STATUS_INVALID_CID (0x50) + +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) +#define BLE_STATUS_IRK_NOT_FOUND (0x5B) +#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) +#define BLE_STATUS_SEC_DB_FULL (0x5D) +#define BLE_STATUS_DEV_NOT_BONDED (0x5E) +#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) + +#define BLE_STATUS_INVALID_HANDLE (0x60) +#define BLE_STATUS_INVALID_PARAMETER (0x61) +#define BLE_STATUS_OUT_OF_HANDLE (0x62) +#define BLE_STATUS_INVALID_OPERATION (0x63) +#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) +#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) +#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) + +/** + * Returned when no valid slots are available (e.g. when there are no available state machines). + */ +#define BLE_STATUS_NO_VALID_SLOT (0x82) + +/** + * Returned when a scan window shorter than minimum allowed value has been requested (i.e. 2ms) + */ + +#define BLE_STATUS_SCAN_WINDOW_SHORT (0x83) +/** + * Returned when the maximum requested interval to be allocated is shorter then the current + * anchor period and a there is no submultiple for the current anchor period that is between + * the minimum and the maximum requested intervals. + */ + +#define BLE_STATUS_NEW_INTERVAL_FAILED (0x84) +/** + * Returned when the maximum requested interval to be allocated is greater than the current anchor + * period and there is no multiple of the anchor period that is between the minimum and the maximum + * requested intervals. + */ + +#define BLE_STATUS_INTERVAL_TOO_LARGE (0x85) +/** + * Returned when the current anchor period or a new one can be found that is compatible to the + * interval range requested by the new slot but the maximum available length that can be allocated is + * less than the minimum requested slot length. + */ + +#define BLE_STATUS_LENGTH_FAILED (0x86) +/** + * @} + */ + +/** + * @name Library Error Codes + * @brief Error codes defined by ST related to MCU library. + * @{ + */ +#define BLE_STATUS_TIMEOUT (0xFF) +#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) +#define BLE_STATUS_NULL_PARAM (0xF1) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,813 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci_const.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with ACI definitions for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_CONST_H_ +#define __BLUENRG_ACI_CONST_H_ + +#include "ble_compiler.h" +#include "ble_link_layer.h" +#include "ble_hci_const.h" +#include "bluenrg_gatt_server.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define OCF_HAL_GET_FW_BUILD_NUMBER 0x0000 +typedef __packed struct _hal_get_fw_build_number_rp{ + uint8_t status; + uint16_t build_number; +} PACKED hal_get_fw_build_number_rp; +#define HAL_GET_FW_BUILD_NUMBER_RP_SIZE 3 +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +#define OCF_HAL_READ_CONFIG_DATA 0x000D +typedef __packed struct _hal_read_config_data_cp{ + uint8_t offset; +} PACKED hal_read_config_data_cp; +#define HAL_READ_CONFIG_DATA_RP_SIZE 1 +typedef __packed struct _hal_read_config_data_rp{ + uint8_t status; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE]; +} PACKED hal_read_config_data_rp; + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef __packed struct _hal_set_tx_power_level_cp{ + uint8_t en_high_power; + uint8_t pa_level; +} PACKED hal_set_tx_power_level_cp; +#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 + +#define OCF_HAL_DEVICE_STANDBY 0x0013 + +#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014 +typedef __packed struct _hal_le_tx_test_packet_number_rp{ + uint8_t status; + uint32_t number_of_packets; +} PACKED hal_le_tx_test_packet_number_rp; + +#define OCF_HAL_TONE_START 0x0015 +typedef __packed struct _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_HAL_TONE_STOP 0x0016 +#define OCF_HAL_GET_LINK_STATUS 0x0017 +typedef __packed struct _hal_get_link_status_rp{ + uint8_t status; + uint8_t link_status[8]; + uint16_t conn_handle[8]; +} PACKED hal_get_link_status_rp; + +#define OCF_HAL_GET_ANCHOR_PERIOD 0x0019 +typedef __packed struct _hal_get_anchor_period_rp{ + uint8_t status; + uint32_t anchor_period; + uint32_t max_free_slot; +} PACKED hal_get_anchor_period_rp; + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef __packed struct _get_updater_version_rp{ + uint8_t status; + uint8_t version; +} PACKED get_updater_version_rp; +#define GET_UPDATER_VERSION_RP_SIZE 2 + +#define OCF_GET_UPDATER_BUFSIZE 0x0023 +typedef __packed struct _get_updater_bufsize_rp{ + uint8_t status; + uint8_t buffer_size; +} PACKED get_updater_bufsize_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 + +#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 + +#define OCF_UPDATER_ERASE_SECTOR 0x0026 +typedef __packed struct _updater_erase_sector_cp{ + uint32_t address; +} PACKED updater_erase_sector_cp; +#define UPDATER_ERASE_SECTOR_CP_SIZE 4 + +#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 +#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_prog_data_block_cp{ + uint32_t address; + uint16_t data_len; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; +} PACKED updater_prog_data_block_cp; + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef __packed struct _updater_read_data_block_cp{ + uint32_t address; + uint16_t data_len; +} PACKED updater_read_data_block_cp; +#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[VARIABLE_SIZE]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef __packed struct _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef __packed struct _updater_calc_crc_rp{ + uint8_t status; + uint32_t crc; +} PACKED updater_calc_crc_rp; +#define UPDATER_CALC_CRC_RP_SIZE 5 + +#define OCF_UPDATER_HW_VERSION 0x002A +typedef __packed struct _updater_hw_version_rp{ + uint8_t status; + uint8_t version; +} PACKED updater_hw_version_rp; +#define UPDATER_HW_VERSION_RP_SIZE 2 + +#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 + +#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 + +#define OCF_GAP_SET_DISCOVERABLE 0x0083 + +#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 +typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ + uint8_t own_bdaddr_type; + uint8_t directed_adv_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint16_t adv_interv_min; + uint16_t adv_interv_max; +} PACKED gap_set_direct_conectable_cp_IDB05A1; + +typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB04A1; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef __packed struct _gap_set_io_capability_cp{ + uint8_t io_capability; +} PACKED gap_set_io_capability_cp; +#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 + +#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 +typedef __packed struct _gap_set_auth_requirement_cp{ + uint8_t mitm_mode; + uint8_t oob_enable; + uint8_t oob_data[16]; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t bonding_mode; +} PACKED gap_set_auth_requirement_cp; +#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 + +#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 +typedef __packed struct _gap_set_author_requirement_cp{ + uint16_t conn_handle; + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef __packed struct _gap_passkey_response_cp{ + uint16_t conn_handle; + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef __packed struct _gap_authorization_response_cp{ + uint16_t conn_handle; + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 + +#define OCF_GAP_INIT 0x008A +typedef __packed struct _gap_init_cp_IDB05A1{ + uint8_t role; + uint8_t privacy_enabled; + uint8_t device_name_char_len; +} PACKED gap_init_cp_IDB05A1; +#define GAP_INIT_CP_SIZE_IDB05A1 3 + +typedef __packed struct _gap_init_cp_IDB04A1{ + uint8_t role; +} PACKED gap_init_cp_IDB04A1; +#define GAP_INIT_CP_SIZE_IDB04A1 1 +typedef __packed struct _gap_init_rp{ + uint8_t status; + uint16_t service_handle; + uint16_t dev_name_char_handle; + uint16_t appearance_char_handle; +} PACKED gap_init_rp; +#define GAP_INIT_RP_SIZE 7 + +#define OCF_GAP_SET_NON_CONNECTABLE 0x008B +typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ + uint8_t advertising_event_type; + uint8_t own_address_type; +#endif +} PACKED gap_set_non_connectable_cp_IDB05A1; + +typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp_IDB04A1; + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef __packed struct _gap_set_undirected_connectable_cp{ + uint8_t adv_filter_policy; + uint8_t own_addr_type; +} PACKED gap_set_undirected_connectable_cp; +#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 + +#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D +typedef __packed struct _gap_slave_security_request_cp{ + uint16_t conn_handle; + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef __packed struct _gap_delete_ad_type_cp{ + uint8_t ad_type; +} PACKED gap_delete_ad_type_cp; +#define GAP_DELETE_AD_TYPE_CP_SIZE 1 + +#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 +typedef __packed struct _gap_get_security_level_rp{ + uint8_t status; + uint8_t mitm_protection; + uint8_t bonding; + uint8_t oob_data; + uint8_t passkey_required; +} PACKED gap_get_security_level_rp; +#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 + +#define OCF_GAP_SET_EVT_MASK 0x0091 +typedef __packed struct _gap_set_evt_mask_cp{ + uint16_t evt_mask; +} PACKED gap_set_evt_mask_cp; +#define GAP_SET_EVT_MASK_CP_SIZE 2 + +#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 + +#define OCF_GAP_TERMINATE 0x0093 +typedef __packed struct _gap_terminate_cp{ + uint16_t handle; + uint8_t reason; +} PACKED gap_terminate_cp; +#define GAP_TERMINATE_CP_SIZE 3 + +#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 + +#define OCF_GAP_ALLOW_REBOND_DB 0x0095 + +typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ + uint16_t conn_handle; +} PACKED gap_allow_rebond_cp_IDB05A1; + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef __packed struct _gap_start_limited_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_limited_discovery_proc_cp; +#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 +typedef __packed struct _gap_start_general_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_general_discovery_proc_cp; +#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 +typedef __packed struct _gap_start_name_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_name_discovery_proc_cp; +#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 + +#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 + +#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; + +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t use_reconn_addr; + tBDAddr reconn_addr; +} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; + +#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B +#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 +typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t num_whitelist_entries; + uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; +} PACKED gap_start_selective_conn_establish_proc_cp; + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef __packed struct _gap_create_connection_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_create_connection_cp; +#define GAP_CREATE_CONNECTION_CP_SIZE 24 + +#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D + +#define OCF_GAP_START_CONNECTION_UPDATE 0x009E +typedef __packed struct _gap_start_connection_update_cp{ + uint16_t conn_handle; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_connection_update_cp; +#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 + +#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F +typedef __packed struct _gap_send_pairing_request_cp{ + uint16_t conn_handle; + uint8_t force_rebond; +} PACKED gap_send_pairing_request_cp; +#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 + +#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 +typedef __packed struct _gap_resolve_private_address_cp{ + tBDAddr address; +} PACKED gap_resolve_private_address_cp; +#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 +typedef __packed struct _gap_resolve_private_address_rp{ + uint8_t status; + tBDAddr address; +} PACKED gap_resolve_private_address_rp; + +#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 +#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 +typedef __packed struct _gap_set_broadcast_mode_cp{ + uint16_t adv_interv_min; + uint16_t adv_interv_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; +} PACKED gap_set_broadcast_mode_cp; + +#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 +typedef __packed struct _gap_start_observation_proc_cp{ + uint16_t scan_interval; + uint16_t scan_window; + uint8_t scan_type; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_observation_proc_cp; + +#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 +typedef __packed struct _gap_get_bonded_devices_rp{ + uint8_t status; + uint8_t num_addr; + uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; +} PACKED gap_get_bonded_devices_rp; + +#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 +typedef __packed struct _gap_is_device_bonded_cp{ + uint8_t peer_address_type; + tBDAddr peer_address; +} PACKED gap_is_device_bonded_cp; + + +#define OCF_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef __packed struct _gatt_add_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_serv_rp; +#define GATT_ADD_SERV_RP_SIZE 3 + +#define OCF_GATT_INCLUDE_SERV 0x0103 +typedef __packed struct _gatt_include_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_include_serv_rp; +#define GATT_INCLUDE_SERV_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR 0x0104 +typedef __packed struct _gatt_add_char_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_rp; +#define GATT_ADD_CHAR_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR_DESC 0x0105 +typedef __packed struct _gatt_add_char_desc_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_desc_rp; +#define GATT_ADD_CHAR_DESC_RP_SIZE 3 + +#define OCF_GATT_UPD_CHAR_VAL 0x0106 + +#define OCF_GATT_DEL_CHAR 0x0107 +typedef __packed struct _gatt_del_char_cp{ + uint16_t service_handle; + uint16_t char_handle; +} PACKED gatt_del_char_cp; +#define GATT_DEL_CHAR_CP_SIZE 4 + +#define OCF_GATT_DEL_SERV 0x0108 +typedef __packed struct _gatt_del_serv_cp{ + uint16_t service_handle; +} PACKED gatt_del_serv_cp; +#define GATT_DEL_SERV_CP_SIZE 2 + +#define OCF_GATT_DEL_INC_SERV 0x0109 +typedef __packed struct _gatt_del_inc_serv_cp{ + uint16_t service_handle; + uint16_t inc_serv_handle; +} PACKED gatt_del_inc_serv_cp; +#define GATT_DEL_INC_SERV_CP_SIZE 4 + +#define OCF_GATT_SET_EVT_MASK 0x010A +typedef __packed struct _gatt_set_evt_mask_cp{ + uint32_t evt_mask; +} PACKED gatt_set_evt_mask_cp; +#define GATT_SET_EVT_MASK_CP_SIZE 4 + +#define OCF_GATT_EXCHANGE_CONFIG 0x010B +typedef __packed struct _gatt_exchange_config_cp{ + uint16_t conn_handle; +} PACKED gatt_exchange_config_cp; +#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 + +#define OCF_ATT_FIND_INFO_REQ 0x010C +typedef __packed struct _att_find_info_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED att_find_info_req_cp; +#define ATT_FIND_INFO_REQ_CP_SIZE 6 + +#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D +#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 +typedef __packed struct _att_find_by_type_value_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[2]; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU - 7]; +} PACKED att_find_by_type_value_req_cp; + +#define OCF_ATT_READ_BY_TYPE_REQ 0x010E +#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_type_req_cp; + +#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F +#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_group_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_group_type_req_cp; + +#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 +#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val +typedef __packed struct _att_prepare_write_req_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t value_offset; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU-5]; +} PACKED att_prepare_write_req_cp; + +#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 +typedef __packed struct _att_execute_write_req_cp{ + uint16_t conn_handle; + uint8_t execute; +} PACKED att_execute_write_req_cp; +#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 + +#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 +typedef __packed struct _gatt_disc_all_prim_serivces_cp{ + uint16_t conn_handle; +} PACKED gatt_disc_all_prim_services_cp; +#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 + +#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 +typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ + uint16_t conn_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_disc_prim_service_by_uuid_cp; +#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid + +#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 +typedef __packed struct _gatt_disc_find_included_services_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED gatt_find_included_services_cp; +#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 + +#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 +typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ + uint16_t conn_handle; + uint16_t start_attr_handle; + uint16_t end_attr_handle; +} PACKED gatt_disc_all_charac_of_serv_cp; +#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 + +#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 + +#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ + uint16_t conn_handle; + uint16_t char_val_handle; + uint16_t char_end_handle; +} PACKED gatt_disc_all_charac_descriptors_cp; +#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 + +#define OCF_GATT_READ_CHARAC_VAL 0x0118 +typedef __packed struct _gatt_read_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_val_cp; +#define GATT_READ_CHARAC_VAL_CP_SIZE 4 + +#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 +typedef __packed struct _gatt_read_using_charac_uuid_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_read_using_charac_uuid_cp; +#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID + +#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A +typedef __packed struct _gatt_read_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_val_cp; +#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 + +#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B +#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles +typedef __packed struct _gatt_read_multiple_charac_val_cp{ + uint16_t conn_handle; + uint8_t num_handles; + uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_read_multiple_charac_val_cp; + +#define OCF_GATT_WRITE_CHAR_VALUE 0x011C + +#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D +#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_write_long_charac_val_cp; + +#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E +#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_charac_reliable_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; +} PACKED gatt_write_charac_reliable_cp; + +#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F +#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; +} PACKED gatt_write_long_charac_desc_cp; + +#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 +typedef __packed struct _gatt_read_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_desc_cp; +#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 + +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 +typedef __packed struct _gatt_read_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_desc_cp; +#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 +#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 3]; +} PACKED gatt_write_without_resp_cp; + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 +#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_signed_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 13]; +} PACKED gatt_signed_write_without_resp_cp; + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 +typedef __packed struct _gatt_confirm_indication_cp{ + uint16_t conn_handle; +} PACKED gatt_confirm_indication_cp; +#define GATT_CONFIRM_INDICATION_CP_SIZE 2 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef __packed struct _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 +typedef __packed struct _gatt_set_security_permission_cp{ + uint16_t service_handle; + uint16_t attr_handle; + uint8_t security_permission; +} PACKED gatt_set_security_permission_cp; +#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_GATT_READ_HANDLE_VALUE 0x012A +typedef __packed struct _gatt_read_handle_val_cp{ + uint16_t attr_handle; +} PACKED gatt_read_handle_val_cp; +#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 +typedef __packed struct _gatt_read_handle_val_rp{ + uint8_t status; + uint16_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; +} PACKED gatt_read_handle_val_rp; + +#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B +typedef __packed struct _gatt_read_handle_val_offset_cp{ + uint16_t attr_handle; + uint8_t offset; +} PACKED gatt_read_handle_val_offset_cp; +#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 +typedef __packed struct _gatt_read_handle_val_offset_rp{ + uint8_t status; + uint8_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; +} PACKED gatt_read_handle_val_offset_rp; + +#define OCF_GATT_UPD_CHAR_VAL_EXT 0x012C +#define GATT_UPD_CHAR_VAL_EXT_CP_SIZE 10 // without value +typedef __packed struct _gatt_upd_char_val_ext_cp{ + uint16_t service_handle; + uint16_t char_handle; + uint8_t update_type; + uint16_t char_length; + uint16_t value_offset; + uint8_t value_length; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_UPD_CHAR_VAL_EXT_CP_SIZE]; +} PACKED gatt_upd_char_val_ext_cp; + +#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 +typedef __packed struct _l2cap_conn_param_update_req_cp{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_update_req_cp; +#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 + +#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint16_t min_ce_length; + uint16_t max_ce_length; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; + +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; + +/** + * @defgroup BlueNRG_Events BlueNRG events (vendor specific) + * @{ + */ + +/** + * Vendor specific event for BlueNRG. + */ +typedef __packed struct _evt_blue_aci{ + uint16_t ecode; /**< One of the BlueNRG event codes. */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_blue_aci; + + +/** + * @} + */ + +#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gap.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GAP layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BNRG_GAP_H__ +#define __BNRG_GAP_H__ + +#include <ble_link_layer.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + * @name GAP UUIDs + * @{ + */ +#define GAP_SERVICE_UUID (0x1800) +#define DEVICE_NAME_UUID (0x2A00) +#define APPEARANCE_UUID (0x2A01) +#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) +#define RECONNECTION_ADDR_UUID (0x2A03) +#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) +/** + * @} + */ + +/** + * @name Characteristic value lengths + * @{ + */ +#define DEVICE_NAME_CHARACTERISTIC_LEN (8) +#define APPEARANCE_CHARACTERISTIC_LEN (2) +#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) +#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) +#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) +/** + * @} + */ + +/*------------- AD types for adv data and scan response data ----------------*/ + +/** + * @defgroup AD_Types AD Types + * @brief AD Types + * @{ + */ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +/** + * @anchor Flags_AD_Type_bits + * @name Flags AD Type bits + * @brief Bits in Flags AD Type + * @{ + */ +#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) +#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) +#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) +#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) +#define FLAG_BIT_LE_BR_EDR_HOST (0x10) +/** + * @} + */ + +/** + * @name Service UUID AD types + * @{ + */ +#define AD_TYPE_16_BIT_SERV_UUID (0x02) +#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) +#define AD_TYPE_32_BIT_SERV_UUID (0x04) +#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) +#define AD_TYPE_128_BIT_SERV_UUID (0x06) +#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) +/** + * @} + */ + +/* LOCAL NAME AD types */ +/** + * @name Local name AD types + * @{ + */ +#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) +#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) +/** + * @} + */ + +/* TX power level AD type*/ +#define AD_TYPE_TX_POWER_LEVEL (0x0A) + +/* Class of device */ +#define AD_TYPE_CLASS_OF_DEVICE (0x0D) + +/* security manager TK value AD type */ +#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) + +/* security manager OOB flags */ +#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) + +/* slave connection interval AD type */ +#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) + +/* service solicitation UUID list Ad types*/ +/** + * @name Service solicitation UUID list AD types + * @{ + */ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) +#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) +/** + * @} + */ + +/* service data AD type */ +#define AD_TYPE_SERVICE_DATA (0x16) + +/* manufaturer specific data AD type */ +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/* appearance AD type */ +#define AD_TYPE_APPEARANCE (0x19) + +/* advertising interval AD type */ +#define AD_TYPE_ADVERTISING_INTERVAL (0x1A) + +/** + * @} + */ + +#define MAX_ADV_DATA_LEN (31) + +#define DEVICE_NAME_LEN (7) +#define BD_ADDR_SIZE (6) + +/** + * @name Privacy flag values + * @{ + */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) +/** + * @} + */ + +/** + * @name Intervals + * Intervals in terms of 625 micro sec + * @{ + */ +#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ +#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ +#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ +#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ +#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ +#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ +#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ +#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ +/** + * @} + */ + +/** + * @name Timeout values + * @{ + */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ +/** + * @} + */ + +/** + * @anchor gap_roles + * @name GAP Roles + * @{ +*/ +#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) +#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) + +#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) +#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) +/** + * @} + */ + +/** + * @anchor gap_procedure_codes + * @name GAP procedure codes + * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event + * and aci_gap_terminate_gap_procedure() command. + * @{ + */ +#define GAP_LIMITED_DISCOVERY_PROC (0x01) +#define GAP_GENERAL_DISCOVERY_PROC (0x02) +#define GAP_NAME_DISCOVERY_PROC (0x04) +#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) +#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) +#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) +#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) +#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1231 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gap_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GAP_ACI_H__ +#define __BLUENRG_GAP_ACI_H__ + +/** + *@addtogroup GAP GAP + *@brief GAP layer. + *@{ + */ + +/** + *@defgroup GAP_Functions GAP functions + *@brief API for GAP layer. + *@{ + */ + +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". + * @param privacy_enabled Enable (1) or disable (0) privacy. + * @param device_name_char_len Length of the device name characteristic + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, + uint8_t device_name_char_len, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Privacy Flag (peripheral role only) + * @li Reconnection Address (peripheral role only) + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB04A1(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); + +/** + * @brief Set the Device in non-discoverable mode. + * @note This command will disable the LL advertising. + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_discoverable(void); + +/** + * @brief Put the device in limited discoverable mode + * (as defined in GAP specification volume 3, section 9.2.3). + * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. + * The advertising can be disabled at any time by issuing + * aci_gap_set_non_discoverable() command. + * The AdvIntervMin and AdvIntervMax parameters are optional. If both + * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). + * Host can set the Local Name, a Service UUID list and the Slave Connection + * Minimum and Maximum. If provided, these data will be inserted into the + * advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() + * separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following + * standard AD types: + * @li AD Flags + * @li TX Power Level + * + * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates + * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. + * + * Example: + * @code + * + * #define ADV_INTERVAL_MIN_MS 100 + * #define ADV_INTERVAL_MAX_MS 200 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, + * (ADV_INTERVAL_MAX_MS*1000)/0.625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * sizeof(serviceUUIDList), serviceUUIDList, + * 0, 0); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 250 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 500 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg NO_WHITE_LIST_USE + * @arg WHITE_LIST_FOR_ONLY_SCAN + * @arg WHITE_LIST_FOR_ONLY_CONN + * @arg WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +/** + * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4). + * @note The device will be discoverable until the Host issue Aci_Gap_Set_Non_Discoverable command. + * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses + * the default values for advertising intervals (1.28 s and 2.56 s respectively for IDB04A1). + * When using connectable undirected advertising events:\n + * @li Adv_Interval_Min = 30 ms + * @li Adv_Interval_Max = 60 ms + * \nWhen using non-connectable advertising events or scannable undirected advertising events:\n + * @li Adv_Interval_Min = 100 ms + * @li Adv_Interval_Max = 150 ms + * Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided, + * these data will be inserted into the advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following standard AD types: + * @li AD Flags + * @li TX Power Level + * + * Usage example: + * + * @code + * + * #define ADV_INTERVAL_MIN_MS 800 + * #define ADV_INTERVAL_MAX_MS 900 + * #define CONN_INTERVAL_MIN_MS 100 + * #define CONN_INTERVAL_MAX_MS 300 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625, + * (ADV_INTERVAL_MAX_MS*1000)/625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * 0, NULL, + * (CONN_INTERVAL_MIN_MS*1000)/1250, + * (CONN_INTERVAL_MAX_MS*1000)/1250); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 1.28 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 2.56 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ONLY_SCAN + * @arg @ref WHITE_LIST_FOR_ONLY_CONN + * @arg @ref WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); + +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @param adv_interv_min Minimum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @param adv_interv_max Maximum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max); +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); + +/** + * @brief Set the IO capabilities of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param io_capability One of the allowed codes for IO Capability: + * @arg @ref IO_CAP_DISPLAY_ONLY + * @arg @ref IO_CAP_DISPLAY_YES_NO + * @arg @ref IO_CAP_KEYBOARD_ONLY + * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT + * @arg @ref IO_CAP_KEYBOARD_DISPLAY + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_io_capability(uint8_t io_capability); + +/** + * @brief Set the authentication requirements for the device. + * @note If the oob_enable is set to 0, oob_data will be ignored. + * This command has to be given only when the device is not in a connected state. + * @param mitm_mode MITM mode: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @param oob_enable If OOB data are present or not: + * @arg @ref OOB_AUTH_DATA_ABSENT + * @arg @ref OOB_AUTH_DATA_PRESENT + * @param oob_data Out-Of-Band data + * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process + * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process + * @param use_fixed_pin If application wants to use a fixed pin or not: + * @arg @ref USE_FIXED_PIN_FOR_PAIRING + * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING + * If a fixed pin is not used, it has to be provided by the application with + * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will + * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is + * accepted. + * @param bonding_mode One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode); + /** + * @brief Set the authorization requirements of the device. + * @note This command has to be given when connected to a device if authorization is required to access services + * which require authorization. + * @param conn_handle Handle of the connection. + * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required + * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables + * the authorization requirement in the device and when a remote device + * tries to read/write a characeristic with authorization requirements, the stack will + * send back an error response with "Insufficient authorization" error code. + * After pairing is complete a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event + * will be sent to the Host. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); + +/** + * @brief Provide the pass key that will be used during pairing. + * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param conn_handle Connection handle + * @param passkey Pass key that will be used during the pairing process. Must be a number between + * 0 and 999999. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); + +/** + * @brief Authorize a device to access attributes. + * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. + * + * @param conn_handle Connection handle + * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) + * @arg @ref CONNECTION_REJECTED : Reject (reject connection) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); + +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @param own_address_type If Privacy is disabled, then the peripheral address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the peripheral address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); + +/** + * @brief Put the device into undirected connectable mode. + * @note If privacy is enabled in the device, a resolvable private address is generated and used + * as the advertiser's address. If not, the address of the type specified in own_addr_type + * is used for advertising. + * @param own_addr_type Type of our address used during advertising: + * if BLUENRG (IDB04A1) + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * else if BLUENRG_MS (IDB05A1) + * If Privacy is disabled: + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled: + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_filter_policy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ALL + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); + +/** + * @brief Send a slave security request to the master. + * @note This command has to be issued to notify the master of the security requirements of the slave. + * The master may encrypt the link, initiate the pairing procedure, or reject the request. + * @param conn_handle Connection handle + * @param bonding One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @param mitm_protection If MITM protection is required or not: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); + +/** + * @brief Update advertising data. + * @note This command can be used to update the advertising data for a particular AD type. + * If the AD type specified does not exist, then it is added to the advertising data. + * If the overall advertising data length is more than 31 octets after the update, then + * the command is rejected and the old data is retained. + * @param AdvLen Length of AdvData array + * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification + * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. + * Example + * @code + * tBleStatus ret; + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; + * + * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * 8, local_name, 3, serviceUUIDList, 0, 0); + * ret = aci_gap_update_adv_data(5, manuf_data); + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); + +/** + * @brief Delete an AD Type + * @note This command can be used to delete the specified AD type from the advertisement data if + * present. + * @param ad_type One of the allowed AD types (see @ref AD_Types) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); + +/** + * @brief Get the current security settings + * @note This command can be used to get the current security settings of the device. + * @param mitm_protection @arg 0: Not required + * @arg 1: Required + * @param bonding @arg 0: No bonding mode + * @arg 1: Bonding mode + * @param oob_data @arg 0: Data absent + * @arg 1: Data present + * @param passkey_required @arg 0: Not required + * @arg 1: Fixed pin is present which is being used + * @arg 2: Passkey required for pairing. An event will be generated + * when required. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required); + +/** + * @brief Add addresses of bonded devices into the controller's whitelist. + * @note The command will return an error if there are no devices in the database or if it was unable + * to add the device into the whitelist. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_configure_whitelist(void); + +/** + * @brief Terminate a connection. + * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. + * @param conn_handle Connection handle + * @param reason Reason for requesting disconnection. The error code can be any of ones as specified + * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); + +/** + * @brief Clear the security database. + * @note All the devices in the security database will be removed. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_clear_security_database(void); + +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @param conn_handle + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB04A1(void); + +/** + * @brief Start the limited discovery procedure. + * @note The controller is commanded to start active scanning. When this procedure is started, + * only the devices in limited discoverable mode are returned to the upper layers. + * The procedure is terminated when either the upper layers issue a command to terminate the + * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code + * set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated + * due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC. + * The device found when the procedure is ongoing is returned to the upper layers through the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the general discovery procedure. + * @note The controller is commanded to start active scanning. The procedure is terminated when + * either the upper layers issue a command to terminate the procedure by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC + * or a timeout happens. When the procedure is terminated due to any of the above reasons, + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to + * @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to + * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the name discovery procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. Once a connection is established, GATT procedure is started to read the + * device name characteristic. When the read is completed (successfully or unsuccessfully), + * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also + * contains the name of the device if the device name was read successfully. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Start the auto connection establishment procedure. + * @note The devices specified are added to the white list of the controller and a LE_Create_Connection + * call will be made to the controller by GAP with the initiator filter policy set to + * use whitelist to determine which advertiser to connect to. When a command is issued to + * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the + * controller by GAP. + * The procedure is terminated when either a connection is successfully established with one of + * the specified devices in the white list or the procedure is explicitly terminated by issuing + * the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start a general connection establishment procedure. + * @note The host enables scanning in the controller with the scanner filter policy set + * to accept all advertising packets and from the scanning results all the devices + * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * The upper layer then has to select one of the devices to which it wants to connect + * by issuing the command aci_gap_create_connection(). The procedure is terminated + * when a connection is established or the upper layer terminates the procedure by + * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates); +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); + +/** + * @brief Start a selective connection establishment procedure. + * @note The GAP adds the specified device addresses into white list and enables scanning in + * the controller with the scanner filter policy set to accept packets only from + * devices in whitelist. All the devices found are sent to the upper layer by the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the + * devices to which it wants to connect by issuing the command aci_gap_create_connection(). + * On completion of the procedure a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated + * with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * The procedure is terminated when a connection is established or the upper layer terminates + * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure + * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start the direct connection establishment procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. The procedure can be terminated explicitly by the upper layer by issuing + * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the + * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller + * by GAP. + * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can + * be explicitly terminated by the upper layer by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is + * returned with the procedure code set to the corresponding procedure. + * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes"). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); + +/** + * @brief Start the connection parameter update procedure. + * @note Allowed by the Central to update the connection parameter of the specified connection. + * A Link Layer Connection Update procedure is started on the controller. + * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to + * the upper layer. + * @param conn_handle Handle of the connection for which the update procedure has to be started. + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Send a pairing request. + * @note Send the SM pairing request to start a pairing process from a Central. The authentication + * requirements and IO capabilities should be set before issuing this command using + * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). + * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. + * @param conn_handle Handle of the connection for which the pairing request has to be sent. + * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded + * @arg 0x01: Pairing request will be sent even if the device was previously bonded + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param[in] address Address to be resolved. + * @param[out] actual_address The public or static random address of the peer device, distributed during pairing phase. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); + +/** + * @brief This command gets the list of bonded devices. + * @note It returns the number of addresses and the corresponding address types and values. + * Example: + * @code + * tBleStatus ret; + * uint8_t num_devices = 0; + * uint8_t device_list[12*7]; + * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); + * for(int i = 0; i < num_devices; i+=7){ + * uint8_t addr_type = device_list[i]; + * uint8_t addr = device_list[i+1]; + * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); + * } + * @endcode + * + * @param[out] num_devices The number of bonded devices. + * @param[out] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address + * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. + * @param device_list_size Maximum size of the device_list buffer used to return the device list. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); + +/** + * @brief Puts the device into broadcast mode + * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address + * as specified in the own_addr_type parameter of the command. + * @param adv_interv_min Minimum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_interv_max Maximum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param own_addr_type If Privacy is disabled, the broadcaster address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the broadcaster address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_data_length Length of the advertising data in the advertising packet + * @param adv_data Advertising data used by the device while advertising + * @param num_whitelist_entries Number of devices to be added to whitelist + * @param addr_array It will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Starts an observation procedure, when the device is in Observer role. + * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer + * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth + * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. + * The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. + * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param own_address_type If Privacy is disabled, then the scanner address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the scanner address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates); + +/** + * @brief The command finds whether a device is bonded. + * @note If the device is using a resolvable private address and it has been bonded, then the command will return + * BLE_STATUS_SUCCESS. + * @param peer_address_type The address type of the peer device + * @arg @ref PUBLIC_ADDR. + * @arg @ref RANDOM_ADDR. + * @param peer_address Address used by the peer device while advertising. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address); + + +/** + * @} + */ + +/** + * @defgroup GAP_Events GAP events + * @{ + */ + +/** + * This event is generated by the controller when the limited discoverable + * mode ends due to timeout (180 seconds). No parameters in the event. + */ +#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) + + +/** + * This event is generated when the pairing process has completed successfully + * or a pairing procedure timeout has occurred or the pairing has failed. + * This is to notify the application that we have paired with a remote device + * so that it can take further actions or to notify that a timeout has occurred + * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. + */ +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +typedef __packed struct _evt_gap_pairing_cmplt{ + uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ + /** + * 0x00: Pairing Success. Pairing with a remote device was successful\n + * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n + * 0x02: Pairing Failed. The pairing failed with the remote device. + */ + uint8_t status; +} PACKED evt_gap_pairing_cmplt; + + +/** + * This event is generated by the Security manager to the application when a pass key is required for pairing. + * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. + * See @ref _evt_gap_pass_key_req. + */ +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +typedef __packed struct _evt_gap_pass_key_req{ + uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ +} PACKED evt_gap_pass_key_req; + + +/** + * This event is generated by the Security manager to the application when the application + * has set that authorization is required for reading/writing of attributes. This event will + * be generated as soon as the pairing is complete. When this event is received, + * aci_gap_authorization_response() command should be used by the application. + * See @ref _evt_gap_author_req. + */ +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +typedef __packed struct _evt_gap_author_req{ + uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ +} PACKED evt_gap_author_req; + +/** + * This event is generated when the slave security request is successfully sent to the master. + * No parameters for this event. + */ +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) + +/** + * This event is generated on the slave when a aci_gap_slave_security_request() is called to reestablish the bond + * with a master but the master has lost the bond. When this event is received, the upper layer has to issue the + * command aci_gap_allow_rebond() in order to allow the slave to continue the pairing process with the master. + * On the master this event is raised when aci_gap_send_pairing_request() is called to reestablish a bond with a slave + * but the slave has lost the bond. In order to create a new bond the master has to launch aci_gap_send_pairing_request() + * with force_rebond set to 1. + * No parameters for this event + */ +#define EVT_BLUE_GAP_BOND_LOST (0X0405) + +/** + * The event is given by the GAP layer to the upper layers when a device is discovered during scanning + * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. + */ +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef __packed struct _evt_gap_device_found{ + uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ + uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ + tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ + uint8_t data_length; /**< Length of advertising or scan response data. */ + uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ +} PACKED evt_gap_device_found; + +/** + * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated + * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. + */ +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef __packed struct _evt_gap_procedure_complete{ + uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ + /** + * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed + * due to authentication requirements). + */ + uint8_t status; + /** + * Procedure specific data.\n + * @li For Name Discovery Procedure:\n + * the name of the peer device if the procedure completed successfully. + * @li For General Connection Establishment Procedure:\n + * The reconnection address written to the peripheral device if the peripheral is privacy enabled + */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_gap_procedure_complete; + +/** + * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral + * is not able to resolve the private address of the peer device after connecting to it. + */ +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) +typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ + uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ +} PACKED evt_gap_addr_not_resolved_IDB05A1; +/** + * This event is raised when the reconnection address is generated during the general connection + * establishment procedure. The same address is set into the peer device also as a part of the general + * connection establishment procedure. In order to make use of the reconnection address the next time + * while connecting to the bonded peripheral, the application needs to use this reconnection address + * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() + * and aci_gap_start_auto_conn_establish_proc(). + */ +#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) +typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ + uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ +} PACKED evt_gap_reconnection_addr_IDB04A1; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1128 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GATT_ACI_H__ +#define __BLUENRG_GATT_ACI_H__ + +#include "bluenrg_gatt_server.h" + +/** + *@addtogroup GATT GATT + *@brief GATT layer. + *@{ + */ + +/** + *@defgroup GATT_Functions GATT functions + *@brief API for GATT layer. + *@{ + */ + +/** + * @brief Initialize the GATT layer for server and client roles. + * @note It adds also the GATT service with Service Changed Characteristic. + * Until this command is issued the GATT channel will not process any commands + * even if the connection is opened. This command has to be given + * before using any of the GAP features. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_init(void); + +/** + * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs + * to reserve the handle ranges for this service using max_attr_records parameter. This + * parameter specifies the maximum number of attribute records that can be added to this + * service (including the service attribute, include attribute, characteristic attribute, + * characteristic value attribute and characteristic descriptor attribute). Handle of the + * created service is returned. + * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors + * are allocated from the attribute pool. + * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field + * @param service_type Primary or secondary service. See @ref Service_type "Service Type". + * @param max_attr_records Maximum number of attribute records that can be added to this service + * (including the service declaration itself) + * @param[out] serviceHandle Handle of the Service. When this service is added to the service, + * a handle is allocated by the server to this service. Server also + * allocates a range of handles for this service from serviceHandle to + * <serviceHandle + max_attr_records>. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, + const uint8_t* service_uuid, + uint8_t service_type, + uint8_t max_attr_records, + uint16_t *serviceHandle); + +/** + * @brief Include a service given by included_start_handle and included_end_handle to another service + * given by service_handle. Attribute server creates an INCLUDE definition attribute and return + * the handle of this attribute in included_handle. + * @param service_handle Handle of the service to which another service has to be included + * @param included_start_handle Start Handle of the service which has to be included in service + * @param included_end_handle End Handle of the service which has to be included in service + * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". + * @param[in] included_uuid 16-bit or 128-bit UUID. + * @param[out] included_handle Handle of the include declaration. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle); + +/** + * @brief Add a characteristic to a service. + * @param serviceHandle Handle of the service to which the characteristic has to be added. + * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param charUuid 16-bit or 128-bit UUID. + * @param charValueLen Maximum length of the characteristic value. + * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, + * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". + * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @arg GATT_DONT_NOTIFY_EVENTS + * @arg GATT_NOTIFY_ATTRIBUTE_WRITE + * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP + * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. + * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client + * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE + * properties. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle); + +/** + * Add a characteristic descriptor to a service. + * @param serviceHandle Handle of the service to which the characteristic belongs + * @param charHandle Handle of the characteristic to which description has to be added. + * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG + * (Well_known_UUIDs) or a user-defined one. + * @param descValueMaxLen The maximum length of the descriptor value + * @param descValueLen Current Length of the characteristic descriptor value + * @param[in] descValue Value of the characteristic description + * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". + * @arg ATTR_NO_ACCESS + * @arg ATTR_ACCESS_READ_ONLY + * @arg ATTR_ACCESS_WRITE_REQ_ONLY + * @arg ATTR_ACCESS_READ_WRITE + * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE + * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param[out] descHandle Handle of the Characteristic Descriptor. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle); + +/** + * @brief Update a characteristic value in a service. + * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. The command is queued into the + * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, + * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or + * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate + * than what is allowed by the link. Throughput on BLE link depends on connection interval and + * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() + * for more info on how to suggest new connection parameters from a slave). If the application does not + * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function + * returns @ref BLE_STATUS_SUCCESS or any other error code.\n + * Example:\n + * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some + * notifications will be lost. + * @code + * tBleStatus Free_Fall_Notify(void) + * { + * uint8_t val; + * tBleStatus ret; + * + * val = 0x01; + * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); + * + * if (ret != BLE_STATUS_SUCCESS){ + * PRINTF("Error while updating FFall characteristic.\n") ; + * return BLE_STATUS_ERROR ; + * } + * return BLE_STATUS_SUCCESS; + * } + * @endcode + * Here if BlueNRG buffer become full, the application try again to send the notification. + * @code + * struct timer t; + * Timer_Set(&t, CLOCK_SECOND*10); + * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ + * // Radio is busy (buffer full). + * if(Timer_Expired(&t)) + * break; + * } + * @endcode + * + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic + * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, + * and the attribute value is of variable length, then the length of the attribute will + * be set to the charValueLen. If the charValOffset is set to a value greater than 0, + * then the length of the attribute will be set to the maximum length as specified for + * the attribute while adding the characteristic. + * @param charValueLen Length of the characteristic value in octets + * @param[in] charValue Characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue); +/** + * @brief Delete the specified characteristic from the service. + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); + +/** + * @brief Delete the specified service from the GATT server database. + * @param servHandle Handle of the service to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_service(uint16_t servHandle); + +/** + * @brief Delete the Include definition from the service. + * @param servHandle Handle of the service to which Include definition belongs + * @param includeServHandle Handle of the Included definition to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); + +/** + * @brief Perform an ATT MTU exchange procedure. + * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP + * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated + * to indicate the end of the procedure. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); + +/** + * @brief Send a @a Find @a Information @a Request. + * @note This command is used to obtain the mapping of attribute handles with their associated + * types. The responses of the procedure are given through the + * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by + * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range of attributes to be discovered on the server + * @param end_handle Ending handle of the range of attributes to be discovered on the server + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send a @a Find @a By @a Type @a Value @a Request + * @note The Find By Type Value Request is used to obtain the handles of attributes that + * have a given 16-bit UUID attribute type and a given attribute value. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid 2 octet UUID to find (little-endian) + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). + * @param attr_val Attribute value to find + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send a @a Read @a By @a Type @a Request + * @note The Read By Type Request is used to obtain the values of attributes where the attribute type + * is known but the handle is not known. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Read @a By @a Group @a Type @a Request + * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute + * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping + * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Prepare @a Write @a Request + * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param attr_handle The handle of the attribute to be written + * @param value_offset The offset of the first octet to be written + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). + * @param attr_val The value of the attribute to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send an @a Execute @a Write @a Request + * @note The Execute Write Request is used to request the server to write or cancel the write of all the + * prepared values currently held in the prepare queue from this client. + * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param execute @arg 0x00 Cancel all prepared writes + * @arg 0x01 Immediately write all pending prepared values. + * @return Value indicating success or error code. + */ +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); + +/** + * @brief This command will start the GATT client procedure to discover all primary services on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +/** + * @brief Start the procedure to discover the primary services of the specified UUID on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to find all included services. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle Start handle of the service + * @param end_handle End handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Start the procedure to discover all the characteristics of a given service. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_attr_handle Start attribute handle of the service + * @param end_attr_handle End attribute handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +/** + * @brief Start the procedure to discover all the characteristics specified by a UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Start attribute handle of the service + * @param end_handle End attribute handle of the service + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); + +/** + * @brief Start the procedure to discover all characteristic descriptors on the server. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. + * @param conn_handle Connection handle for which the command is given. + * @param char_val_handle Starting handle of the characteristic + * @param char_end_handle End handle of the characteristic + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +/** + * @brief Start the procedure to read the attribute value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to read all the characteristics specified by the UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range to be searched + * @param end_handle End handle of the range to be searched + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start a procedure to read multiple characteristic values from a server. + * @note This sub-procedure is used to read multiple Characteristic Values from a server when the + * client knows the Characteristic Value Handles. + * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param num_handles The number of handles for which the value has to be read + * @param set_of_handles The handles for which the attribute value has to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles); + +/** + * @brief Start the procedure to write a characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to write a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start the procedure to write a characteristic reliably. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to write a long characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP + * event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic descriptor + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start the procedure to write a characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to read the descriptor specified. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the descriptor to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to write a characteristic value without waiting for any response from the server. + * @note No events are generated after this command is executed. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 3) + * @param[in] attr_val Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start a signed write without response from the server. + * @note The procedure i used to write a characteristic value with an authentication signature without waiting + * for any response from the server. It cannot be used when the link is encrypted. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 13). + * @param attr_val Value to be written + * @return Value indicating success or error code + */ +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Confirm an indication + * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); + +/** + * @brief Allow or reject a write request from a client. + * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, + * then the status has to be set to 1 and the error code has to be set to the error code that has to be + * passed to the client. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n + * 0x01: The value cannot be written to the attribute specified by the attr_handle. + * @param err_code The error code that has to be passed to the client in case the write has to be rejected. + * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val); + +/** + * @brief Allow the GATT server to send a response to a read request from a client. + * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ + * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response + * can be sent to the client. So if the application wishes to update any of the attributes before + * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value + * and then give this command. The application should perform the required operations within 30 seconds, + * otherwise the GATT procedure will go to timeout. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_allow_read(uint16_t conn_handle); + +/** + * @brief Set the security permission for the attribute handle specified. + * @note Currently the setting of security permission is allowed only for client configuration descriptor. + * @param service_handle Handle of the service which contains the attribute whose security + * permission has to be modified. + * @param attr_handle Handle of the attribute whose security permission has to be modified. + * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission); + +/** + * @brief This command sets the value of the descriptor specified by charDescHandle. + * @param servHandle Handle of the service which contains the descriptor. + * @param charHandle Handle of the characteristic which contains the descriptor. + * @param charDescHandle Handle of the descriptor whose value has to be set. + * @param charDescValOffset Offset from which the descriptor value has to be updated. + * @param charDescValueLen Length of the descriptor value + * @param[in] charDescValue descriptor value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue); + +/** + * @brief Reads the value of the attribute handle specified from the local GATT database. + * @param attr_handle Handle of the attribute to read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + + /** + * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. + * @param attr_handle Handle of the attribute to read + * @param offset Offset from which the value needs to be read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); +/** + * @brief Update the value of a characteristic and sends notifications or indications. + * @note This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute + * up to 512 bytes and indicate selectively the generation of indications and notifications. + * @param service_handle Handle of the service to which the characteristic belongs. + * @param char_handle Handle of the characteristic + * @param update_type Bitmask that controls generation of notifications and indications. It can be a combination + * @arg @ref NOTIFICATION (0x01): send notification, if enabled. + * @arg @ref INDICATION (0x02): send indication, if enabled. + * If set to 0 no notifications or indications are sent. + * @param char_length Total length of the characteristic value. In case of a variable size characteristic, + * this field specifies the new length of the characteristic value after the update; + * in case of fixed length characteristic this field is ignored. + * @param value_offset The offset from which the attribute value has to be updated + * @param value_length Length of the value to be updated + * @param[out] value Updated characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value); + +/** + * @} + */ + + +/** + * @defgroup GATT_Events GATT events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** + * This event (if enabled, see @ref Gatt_Event_Mask "Gatt Event Mask") is raised to the application + * by the GATT server when a client modifies any attribute on the server, as consequence of one of + * the following GATT procedures: + * @li write without response + * @li signed write without response + * @li write characteristic value + * @li write long characteristic value + * @li reliable write. + * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. + */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint16_t offset; /**< Offset from which the write has been performed by the peer device */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB05A1; + +typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB04A1; + +/** + * This event is generated by the client/server to the application on a GATT timeout (30 seconds). + * See @ref _evt_gatt_procedure_timeout. + */ +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +typedef __packed struct _evt_gatt_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ +} PACKED evt_gatt_procedure_timeout; + +/** + * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). + * See @ref _evt_att_exchange_mtu_resp. + */ +#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) +typedef __packed struct _evt_att_exchange_mtu_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data (always 1). */ + uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ +} PACKED evt_att_exchange_mtu_resp; + +/** + * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and + * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. + */ +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef __packed struct _evt_att_find_information_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ + /** + * A sequence of handle-uuid pairs.\n + * @li if format=1, each pair is:\n + * [2 octets for handle, 2 octets for UUIDs] \n + * @li if format=2, each pair is:\n + * [2 octets for handle, 16 octets for UUIDs] + */ + uint8_t handle_uuid_pair[VARIABLE_SIZE]; +} PACKED evt_att_find_information_resp; + +/** + * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See + * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. + */ +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +typedef __packed struct _evt_att_find_by_type_val_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + /** + * Handles Information List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] + */ + uint8_t handles_info_list[VARIABLE_SIZE]; +} PACKED evt_att_find_by_type_val_resp; + +/** + * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and + * aci_gatt_disc_all_charac_of_serv(). + * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. + */ +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef __packed struct _evt_att_read_by_type_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ + /** + * Attribute Data List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] + */ + uint8_t handle_value_pair[VARIABLE_SIZE]; +} PACKED evt_att_read_by_type_resp; + +/** + * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). + * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. + */ +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +typedef __packed struct _evt_att_read_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ +} PACKED evt_att_read_resp; + +/** + * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). + * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. + */ +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +typedef __packed struct _evt_att_read_blob_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ +} PACKED evt_att_read_blob_resp; + +/** + * This event is generated in response to a @a Read @a Multiple @a Request. + * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. + */ +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +typedef __packed struct _evt_att_read_mult_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ +} PACKED evt_att_read_mult_resp; + +/** + * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). + * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. + */ +#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) +typedef __packed struct _evt_att_read_by_group_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_data_length; /**< The size of each Attribute Data. */ + /** + * A list of Attribute Data where the attribute data is composed by: + * @li 2 octets for Attribute Handle + * @li 2 octets for End Group Handle + * @li (attribute_data_length - 4) octets for Attribute Value + */ + uint8_t attribute_data_list[VARIABLE_SIZE]; +} PACKED evt_att_read_by_group_resp; + +/** + * This event is generated in response to a @a Prepare @a Write @a Request. + * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. + */ +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +typedef __packed struct _evt_att_prepare_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attribute_handle; /**< The handle of the attribute to be written. */ + uint16_t offset; /**< The offset of the first octet to be written. */ + uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ +} PACKED evt_att_prepare_write_resp; + +/** + * This event is generated in response to an @a Execute @a Write @a Request. + * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. + */ +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +typedef __packed struct _evt_att_exec_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Always 0. */ +} PACKED evt_att_exec_write_resp; + +/** + * This event is generated when an indication is received from the server. + * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. + */ +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +typedef __packed struct _evt_gatt_indication{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_indication; + +/** + * This event is generated when a notification is received from the server. + * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. + */ +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef __packed struct _evt_gatt_notification{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_attr_notification; + +/** + * This event is generated when a GATT client procedure completes either with error or successfully. + * See @ref _evt_gatt_procedure_complete. + */ +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef __packed struct _evt_gatt_procedure_complete{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ + uint8_t data_length; /**< Length of error_code field (always 1). */ + /** + * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). + */ + uint8_t error_code; +} PACKED evt_gatt_procedure_complete; + +/** + * This event is generated when an Error Response is received from the server. The error response can be given + * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended + * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. + */ +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +typedef __packed struct _evt_gatt_error_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t req_opcode; /**< The request that generated this error response. */ + uint16_t attr_handle; /**< The attribute handle that generated this error response. */ + uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ +} PACKED evt_gatt_error_resp; + +/** + * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using + * Characteristic UUID" procedure. + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. + */ +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + /** + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. + */ + uint8_t attr_value[VARIABLE_SIZE]; +} PACKED evt_gatt_disc_read_char_by_uuid_resp; + +/** + * This event is given to the application when a write request, write command or signed write command + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * If the write is rejected by the application, then the value of the attribute will not be modified. + * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. + * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef __packed struct _evt_gatt_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_write_permit_req; + +/** + * This event is given to the application when a read request or read blob request is received by the server + * from the client. This event will be given to the application only if the event bit for this event generation + * is set when the characteristic was added. + * On receiving this event, the application can update the value of the handle if it desires and when done + * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef __packed struct _evt_gatt_read_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ + uint8_t data_length; /**< Length of offset field. */ + uint16_t offset; /**< Contains the offset from which the read has been requested */ +} PACKED evt_gatt_read_permit_req; + +/** + * This event is given to the application when a read multiple request or read by type request is received + * by the server from the client. This event will be given to the application only if the event bit for this + * event generation is set when the characteristic was added. + * On receiving this event, the application can update the values of the handles if it desires and when done + * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_multi_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) +typedef __packed struct _evt_gatt_read_multi_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ +} PACKED evt_gatt_read_multi_permit_req; + +/** + * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2). + * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES. + * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value(). + * See @ref evt_gatt_tx_pool_vailable. + * + */ +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE (0x0C16) +typedef __packed struct _evt_gatt_tx_pool_available{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t available_buffers; /**< Length of data field. */ +} PACKED evt_gatt_tx_pool_available; + +/** + * This event is raised on the server when the client confirms the reception of an indication. + */ +#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT (0x0C17) +typedef __packed struct _evt_gatt_server_confirmation{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ +} PACKED evt_gatt_server_confirmation; +/** + * This event is given to the application when a prepare write request + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * Based on the response from the application, the attribute value will be modified by the stack. + * If the write is rejected by the application, then the value of the attribute will not be modified + * and an error response will be sent to the client, with the error code as specified by the application. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ (0x0C18) +typedef __packed struct _evt_gatt_prepare_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint16_t offset; /**< The offset from which the prepare write has been requested */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_prepare_write_permit_req; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,229 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gatt_server.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GATT server layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BNRG_GATT_SERVER_H__ +#define __BNRG_GATT_SERVER_H__ + +#include "ble_compiler.h" +#include "ble_status.h" + +/** + *@addtogroup GATT GATT + *@{ + */ + +/** + * @anchor Well-Known_UUIDs + * @name Well-Known UUIDs + * @{ + */ +#define PRIMARY_SERVICE_UUID (0x2800) +#define SECONDARY_SERVICE_UUID (0x2801) +#define INCLUDE_SERVICE_UUID (0x2802) +#define CHARACTERISTIC_UUID (0x2803) +#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) +#define CHAR_USER_DESC_UUID (0x2901) +#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) +#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) +#define CHAR_FORMAT_DESC_UUID (0x2904) +#define CHAR_AGGR_FMT_DESC_UUID (0x2905) +#define GATT_SERVICE_UUID (0x1801) +#define GAP_SERVICE_UUID (0x1800) +#define SERVICE_CHANGED_UUID (0x2A05) +/** + * @} + */ + +/** + * @anchor Access_permissions + * @name Access permissions + * Access permissions for an attribute + * @{ + */ +#define ATTR_NO_ACCESS (0x00) +#define ATTR_ACCESS_READ_ONLY (0x01) +#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) +#define ATTR_ACCESS_READ_WRITE (0x03) +#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) +#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) +/** + * Allows all write procedures + */ +#define ATTR_ACCESS_WRITE_ANY (0x0E) +/** + * @} + */ + +/** + * @anchor Char_properties + * @name Characteristic properties. + * @{ + */ +#define CHAR_PROP_BROADCAST (0x01) +#define CHAR_PROP_READ (0x02) +#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) +#define CHAR_PROP_WRITE (0x08) +#define CHAR_PROP_NOTIFY (0x10) +#define CHAR_PROP_INDICATE (0x20) +#define CHAR_PROP_SIGNED_WRITE (0x40) +#define CHAR_PROP_EXT (0x80) +/** + * @} + */ + + +/** + * @anchor Security_permissions + * @name Security permissions for an attribute. + * @{ + */ +#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ +#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ +#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ +#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ +/** + * @} + */ + +/** + * @anchor UUID_Types + * @name Type of UUID (16 bit or 128 bit). + * @{ + */ +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) +/** + * @} + */ + +/** + * @anchor Service_type + * @name Type of service (primary or secondary) + * @{ + */ +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) +/** + * @} + */ + +/** + * @anchor Gatt_Event_Mask + * @name Gatt Event Mask + * Type of event generated by GATT server + * @{ + */ +#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ +#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. + An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ +#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd + or a signed write cmd are received by the server for this attribute. + An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ +#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is + received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ +/** + * @} + */ + +/** + * @name Type of characteristic length + * See aci_gatt_add_char() + * @{ + */ +#define CHAR_VALUE_LEN_CONSTANT (0x00) +#define CHAR_VALUE_LEN_VARIABLE (0x01) +/** + * @} + */ + + +/** + * @name Encryption key size + * @{ + */ +/** + * Minimum encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Maximum encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) +/** + * @} + */ + +/** + * @name Characteristic Presentation Format + * @{ + */ +typedef __packed struct _charactFormat { + uint8_t format; + int8_t exp; + uint16_t unit; + uint8_t name_space; + uint16_t desc; +} PACKED charactFormat; + +/** + * @} + */ + +/** + * @name Format + * @{ + */ +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F +/** + * @} + */ + +/** + * @name Unit + * @{ + */ +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 +/** + * @} + */ + + +/** + * ATT MTU size + */ +#define ATT_MTU (23) + +/** + * @} + */ + + /** + * @name Update type of aci_gatt_upd_char_val_ext(). + * @{ + */ + +#define NOTIFICATION 1 +#define INDICATION 2 + +#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,385 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hal_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with HCI commands for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_HAL_ACI_H__ +#define __BLUENRG_HAL_ACI_H__ + +/** + *@addtogroup HAL HAL + *@brief Hardware Abstraction Layer. + *@{ + */ + +/** + * @defgroup HAL_Functions HAL functions + * @brief API for BlueNRG HAL layer. + * @{ + */ + +/** + * @brief This command retrieves the buid number of the firmware. + * @param[out] build_number Build number identifying the firmware release. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number); + +/** + * @brief This command writes a value to a low level configure data structure. + * @note It is useful to setup directly some low level parameters for the system at runtime. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * + * @param len Length of data to be written + * @param[out] val Data to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val); + +/** + * @brief This command requests the value in the low level configure data structure. + * The number of read bytes changes for different Offset. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * @param data_len Length of the data buffer + * @param[out] data_len_out_p length of the data returned by the read. + * @param[out] data Read data + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data); + +/** + * @brief This command sets the TX power level of the BlueNRG. + * @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines + * the output power level (dBm). + * When the system starts up or reboots, the default TX power level will be used, which is + * the maximum value of 8dBm. Once this command is given, the output power will be changed + * instantly, regardless if there is Bluetooth communication going on or not. For example, + * for debugging purpose, the BlueNRG can be set to advertise all the time and use this + * command to observe the signal strength changing. The system will keep the last received + * TX power level from the command, i.e. the 2nd command overwrites the previous TX power + * level. The new TX power level remains until another Set TX Power command, or the system + * reboots.\n + * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the + * right value, depending on the selected hardware configuration for the RF network: + * normal mode or high power mode. + * @param pa_level Can be from 0 to 7. Set the PA level value. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +/** + * @brief This command returns the number of packets sent in Direct Test Mode. + * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets + * have been transmitted. This command can be used to check how many packets have been sent + * during the Direct TX test.\n + * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again. + * The counter is not cleared until the next Direct TX test starts. + * @param[out] number_of_packets Number of packets sent during the last Direct TX test. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets); + +/** + * @brief Put the device in standby mode. + * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the + * device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode, + * the device can still wake up itself with the internal timer. But in standby mode, this timer is + * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command + * sent via SPI bus. + * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code + * ERR_COMMAND_DISALLOWED will be returned. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_device_standby(void); + +/** + * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. + * @note The frequency sine wave at the specific channel may be used for test purpose only. + * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. + * This command shouldn't be used when normal Bluetooth activities are ongoing. + * The tone should be stopped by aci_hal_tone_stop() command. + * + * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the + * channel central frequency minus 250 kHz. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +/** + * This command is used to stop the previously started aci_hal_tone_start() command. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_stop(void); + +/** + * @brief This command returns the status of all the connections. + * @note This command returns the status of the 8 Bluetooth low energy links managed by the device. + * @param[out] link_status Array of link status (8 links). See @ref Link_Status. + * @param[out] conn_handle Array of connection handles for each link. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]); + +/** + * @brief This command returns the anchor period and the largest available slot. + * @note This command returns information about the anchor period to help application in selecting + * slot timings when operating in multi-link scenarios. + * @param anchor_period Current anchor period (multiple of 0.625 ms). + * @param max_free_slot Maximum available time (multiple of 0.625 ms) that can be allocated for a new slot. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot); + +/** + * @} + */ + +/** + * @defgroup HAL_Events HAL events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_HAL_INITIALIZED (0x0001) +typedef __packed struct _evt_hal_initialized{ + uint8_t reason_code; /**< Reset reason. See @ref Reset_Reasons */ +} PACKED evt_hal_initialized; + +/** + * This event is generated when an overflow occurs in the event queue read by the external microcontroller. + * This is normally caused when the external microcontroller does not read pending events. + * The returned bitmap indicates which event has been lost. Please note that one bit set to 1 indicates one or + * more occurrences of the particular events. The event EVT_BLUE_HAL_EVENTS_LOST cannot be lost and it will + * be inserted in the event queue as soon as a position is freed in the event queue. This event should not + * happen under normal operating condition where external microcontroller promptly reads events signaled by + * IRQ pin. It is provided to detected unexpected behavior of the external microcontroller or to allow + * application to recover situations where critical events are lost. + */ +#define EVT_BLUE_HAL_EVENTS_LOST_IDB05A1 (0x0002) +typedef __packed struct _evt_hal_events_lost{ + uint8_t lost_events[8]; /**< Bitmap of lost events. Each bit indicates one or more occurrences of the specific event. See @ref Lost_Events */ +} PACKED evt_hal_events_lost_IDB05A1; + + +/** + * This event is given to the application after the @ref ACI_BLUE_INITIALIZED_EVENT + * when a system crash is detected. This events returns system crash information for debugging purposes. + * Information reported are useful to understand the root cause of the crash. + */ +#define EVT_BLUE_HAL_CRASH_INFO_IDB05A1 (0x0003) +typedef __packed struct _evt_hal_crash_info{ + uint8_t crash_type; /**< Type of crash: Assert failed (0), NMI Fault (1), Hard Fault (2) */ + uint32_t sp; /**< SP register */ + uint32_t r0; /**< R0 register */ + uint32_t r1; /**< R1 register */ + uint32_t r2; /**< R2 register */ + uint32_t r3; /**< R3 register */ + uint32_t r12; /**< R12 register */ + uint32_t lr; /**< LR register */ + uint32_t pc; /**< PC register */ + uint32_t xpsr; /**< xPSR register */ + uint8_t debug_data_len; /**< length of debug_data field */ + uint8_t debug_data[VARIABLE_SIZE]; /**< Debug data */ +} PACKED evt_hal_crash_info_IDB05A1; + + +/** + * @} + */ + + +/** + * @anchor Reset_Reasons + * @name Reset Reasons + * See @ref EVT_BLUE_HAL_INITIALIZED. + * @{ + */ +#define RESET_NORMAL 1 /**< Normal startup. */ +#define RESET_UPDATER_ACI 2 /**< Updater mode entered with ACI command */ +#define RESET_UPDATER_BAD_FLAG 3 /**< Updater mode entered due to a bad BLUE flag */ +#define RESET_UPDATER_PIN 4 /**< Updater mode entered with IRQ pin */ +#define RESET_WATCHDOG 5 /**< Reset caused by watchdog */ +#define RESET_LOCKUP 6 /**< Reset due to lockup */ +#define RESET_BROWNOUT 7 /**< Brownout reset */ +#define RESET_CRASH 8 /**< Reset caused by a crash (NMI or Hard Fault) */ +#define RESET_ECC_ERR 9 /**< Reset caused by an ECC error */ +/** + * @} + */ + + +/** + * @defgroup Config_vals Offsets and lengths for configuration values. + * @brief Offsets and lengths for configuration values. + * See aci_hal_write_config_data(). + * @{ + */ + +/** + * @name Configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ +#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ +#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ +#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ +#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. + It can be written only if aci_hal_write_config_data() is the first command after reset. */ +#define CONFIG_DATA_RANDOM_ADDRESS (0x80) /**< Stored static random address. Read-only. */ + +/** + * Select the BlueNRG mode configurations.\n + * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) + * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) + * @li Mode 3: master/slave, 8 connections, RAM1 and RAM2. + * @li Mode 4: master/slave, 4 connections, RAM1 and RAM2 simultaneous scanning and advertising. + */ +#define CONFIG_DATA_MODE_OFFSET (0x2D) + +#define CONFIG_DATA_WATCHDOG_DISABLE (0x2F) /**< Set to 1 to disable watchdog. It is enabled by default. */ +/** + * @} + */ + +/** + * @name Length for configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_LEN (6) +#define CONFIG_DATA_DIV_LEN (2) +#define CONFIG_DATA_ER_LEN (16) +#define CONFIG_DATA_IR_LEN (16) +#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) +#define CONFIG_DATA_MODE_LEN (1) +#define CONFIG_DATA_WATCHDOG_DISABLE_LEN (1) +/** + * @} + */ + +/** + * @anchor Link_Status + * @name Status of the link + * See @ref aci_hal_get_link_status(). + * @{ + */ +#define STATUS_IDLE 0 +#define STATUS_ADVERTISING 1 +#define STATUS_CONNECTED_AS_SLAVE 2 +#define STATUS_SCANNING 3 +#define STATUS_CONNECTED_AS_MASTER 5 +#define STATUS_TX_TEST 6 +#define STATUS_RX_TEST 7 +/** + * @} + */ + +/** + * @} + */ + + /** + * @anchor Lost_Events + * @name Lost events bitmap + * See @ref EVT_BLUE_HAL_EVENTS_LOST. + * @{ + */ +#define EVT_DISCONN_COMPLETE_BIT 0 +#define EVT_ENCRYPT_CHANGE_BIT 1 +#define EVT_READ_REMOTE_VERSION_COMPLETE_BIT 2 +#define EVT_CMD_COMPLETE_BIT 3 +#define EVT_CMD_STATUS_BIT 4 +#define EVT_HARDWARE_ERROR_BIT 5 +#define EVT_NUM_COMP_PKTS_BIT 6 +#define EVT_ENCRYPTION_KEY_REFRESH_BIT 7 +#define EVT_BLUE_HAL_INITIALIZED_BIT 8 +#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE_BIT 9 +#define EVT_BLUE_GAP_PAIRING_CMPLT_BIT 10 +#define EVT_BLUE_GAP_PASS_KEY_REQUEST_BIT 11 +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST_BIT 12 +#define EVT_BLUE_GAP_SECURITY_REQ_INITIATED_BIT 13 +#define EVT_BLUE_GAP_BOND_LOST_BIT 14 +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE_BIT 15 +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_BIT 16 +#define EVT_BLUE_L2CAP_CONN_UPDATE_RESP_BIT 17 +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT_BIT 18 +#define EVT_BLUE_L2CAP_CONN_UPDATE_REQ_BIT 19 +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_BIT 20 +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT_BIT 21 +#define EVT_BLUE_EXCHANGE_MTU_RESP_BIT 22 +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP_BIT 23 +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP_BIT 24 +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP_BIT 25 +#define EVT_BLUE_ATT_READ_RESP_BIT 26 +#define EVT_BLUE_ATT_READ_BLOB_RESP_BIT 27 +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP_BIT 28 +#define EVT_BLUE_ATT_READ_BY_GROUP_RESP_BIT 29 +#define EVT_BLUE_ATT_WRITE_RESP_BIT 30 +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP_BIT 31 +#define EVT_BLUE_ATT_EXEC_WRITE_RESP_BIT 32 +#define EVT_BLUE_GATT_INDICATION_BIT 33 +#define EVT_BLUE_GATT_NOTIFICATION_BIT 34 +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE_BIT 35 +#define EVT_BLUE_GATT_ERROR_RESP_BIT 36 +#define EVT_BLUE_GATT_DISC_READ_CHARAC_BY_UUID_RESP_BIT 37 +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ_BIT 38 +#define EVT_BLUE_GATT_READ_PERMIT_REQ_BIT 39 +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ_BIT 40 +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_BIT 41 +#define EVT_BLUE_GATT_SERVER_RX_CONFIRMATION_BIT 42 +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ_BIT 43 +#define EVT_LL_CONNECTION_COMPLETE_BIT 44 +#define EVT_LL_ADVERTISING_REPORT_BIT 45 +#define EVT_LL_CONNECTION_UPDATE_COMPLETE_BIT 46 +#define EVT_LL_READ_REMOTE_USED_FEATURES_BIT 47 +#define EVT_LL_LTK_REQUEST_BIT 48 +/** + * @} + */ + +/** + * @name Hardware error event codes + * See @ref EVT_HARDWARE_ERROR. + * @{ + */ +/** + * Error on the SPI bus has been detected, most likely caused by incorrect SPI configuration on the external micro-controller. + */ +#define SPI_FRAMING_ERROR 0 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define RADIO_STATE_ERROR 1 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define TIMER_OVERRUN_ERROR 2 + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,166 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_l2cap_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with L2CAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_L2CAP_ACI_H__ +#define __BLUENRG_L2CAP_ACI_H__ + +/** + *@addtogroup L2CAP L2CAP + *@brief L2CAP layer. + *@{ + */ + +/** + *@defgroup L2CAP_Functions L2CAP functions + *@brief API for L2CAP layer. + *@{ + */ + +/** + * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. + * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request + * (accepts or rejects). + * @param conn_handle Connection handle on which the connection parameter update request has to be sent. + * @param interval_min Defines minimum value for the connection event interval in the following manner: + * connIntervalMin = interval_min x 1.25ms + * @param interval_max Defines maximum value for the connection event interval in the following manner: + * connIntervalMax = interval_max x 1.25ms + * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). + * @param timeout_multiplier Defines connection timeout parameter in the following manner: + * timeout_multiplier x 10ms. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier); +/** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param min_ce_length Minimum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_ce_length Maximum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept); + /** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept); + +/** + * @} + */ + +/** + * @defgroup L2CAP_Events L2CAP events + * @{ + */ + +/** + * This event is generated when the master responds to the L2CAP connection update request packet. + * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. + */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef __packed struct _evt_l2cap_conn_upd_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ +/** + * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. + * @li 0x01 in case of Command Reject. + */ + uint8_t code; + uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ + uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ +/** + * Result code (parameters accepted or rejected) in case of Connection Parameter Update + * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). + */ + uint16_t result; +} PACKED evt_l2cap_conn_upd_resp; + +/** + * This event is generated when the master does not respond to the connection update request + * within 30 seconds. + */ +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) +typedef __packed struct _evt_l2cap_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */ +} PACKED evt_l2cap_procedure_timeout; + +/** + * The event is given by the L2CAP layer when a connection update request is received from the slave. + * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). + */ +#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) +typedef __packed struct _evt_l2cap_conn_upd_req{ +/** + * Handle of the connection for which the connection update request has been received. + * The same handle has to be returned while responding to the event with the command + * aci_l2cap_connection_parameter_update_response(). + */ + uint16_t conn_handle; + uint8_t event_data_length; /**< Length of following data. */ +/** + * This is the identifier which associates the request to the + * response. The same identifier has to be returned by the upper + * layer in the command aci_l2cap_connection_parameter_update_response(). + */ + uint8_t identifier; + uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ + uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ +} PACKED evt_l2cap_conn_upd_req; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_updater_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with updater commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_UPDATER_ACI_H__ +#define __BLUENRG_UPDATER_ACI_H__ + +#include <ble_compiler.h> + +/** + * @defgroup Updater Updater + * @brief Updater. + * @{ + */ + +/** + * @defgroup Updater_Functions Updater functions + * @brief API for BlueNRG Updater. + * @{ + */ + +tBleStatus aci_updater_start(void); + +tBleStatus aci_updater_reboot(void); + +tBleStatus aci_get_updater_version(uint8_t *version); + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); + +tBleStatus aci_erase_blue_flag(void); + +tBleStatus aci_reset_blue_flag(void); + +tBleStatus aci_updater_erase_sector(uint32_t address); + +tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); + +tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); + +tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); + +tBleStatus aci_updater_hw_version(uint8_t *version); + +/** + * @} + */ + +/** + * @defgroup Updater_Events Updater events + * @{ + */ +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_INITIALIZED (0x0001) +typedef __packed struct _evt_blue_initialized{ + uint8_t reason_code; +} PACKED evt_blue_initialized; +/** + * @} + */ + +/** + * @} + */ + + + +#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,204 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_utils.h +* Author : AMS - VMA, RF Application Team +* Version : V1.0.1 +* Date : 03-October-2014 +* Description : Header file for BlueNRG utility functions +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + * @file bluenrg_utils.h + * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description + * + * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> +**/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLUENRG_UTILS_H +#define __BLUENRG_UTILS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ble_hal_types.h" +#include "ble_compiler.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct{ + uint8_t stack_mode; + uint8_t day; + uint8_t month; + uint8_t year; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint16_t hs_startup_time; /* In system time units*/ +} IFR_config2_TypeDef; + +/** + * Structure inside IFR for configuration options. + */ +typedef __packed struct{ + uint8_t cold_ana_act_config_table[64]; + uint8_t hot_ana_config_table[64]; + uint8_t stack_mode; + uint8_t gpio_config; + uint8_t rsrvd1[2]; + uint32_t rsrvd2[3]; + uint32_t max_conn_event_time; + uint32_t ls_crystal_period; + uint32_t ls_crystal_freq; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint8_t rsrvd3; + uint16_t hs_startup_time; /* In system time units*/ + uint8_t rsrvd4[2]; + uint32_t uid; + uint8_t rsrvd5; + uint8_t year; + uint8_t month; + uint8_t day; + uint32_t unused[5]; +} PACKED IFR_config_TypeDef; + +/* Exported constants --------------------------------------------------------*/ +extern const IFR_config_TypeDef IFR_config; + +/* Exported macros -----------------------------------------------------------*/ +#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)+1) +#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) + +/* Convert 2 digit BCD number to an integer */ +#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) + +/* Convert 2 digit number to a BCD number */ +#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) + +/** + * Return values + */ +#define BLE_UTIL_SUCCESS 0 +#define BLE_UTIL_UNSUPPORTED_VERSION 1 +#define BLE_UTIL_WRONG_IMAGE_SIZE 2 +#define BLE_UTIL_ACI_ERROR 3 +#define BLE_UTIL_CRC_ERROR 4 +#define BLE_UTIL_PARSE_ERROR 5 +#define BLE_UTIL_WRONG_VERIFY 6 + +/* Exported functions ------------------------------------------------------- */ +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int program_device(const uint8_t *fw_image, uint32_t fw_size); + +/** + * @brief Read raw data from IFR (3 64-bytes blocks). + * @param data Pointer to the buffer that will contain the read data. + * Its size must be 192 bytes. This data can be parsed by + * parse_IFR_data_config(). + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION) + */ +int read_IFR(uint8_t data[192]); + +/** + * @brief Verify raw data from IFR (3 64-bytes blocks). + * @param ifr_data Pointer to the buffer that will contain the data to verify. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) + */ +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); + +/** + * @brief Program raw data to IFR (3 64-bytes blocks). + * @param ifr_image Pointer to the buffer that will contain the data to program. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful + */ +int program_IFR(const IFR_config_TypeDef *ifr_image); + +/** + * @brief Parse IFR raw data. + * @param data Pointer to the raw data: last 64 bytes read from IFR sector. + * @param IFR_config Data structure that will be filled with parsed data. + * @retval None + */ +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); + +/** + * @brief Check for the correctness of parsed data. + * @param IFR_config Data structure filled with parsed data. + * @retval int It returns 0 if successful, or PARSE_ERROR in case data is + * not correct. + */ +int IFR_validate(IFR_config2_TypeDef *IFR_config); + +/** + * @brief Modify IFR data. (Last 64-bytes block). + * @param IFR_config Structure that contains the new parameters inside the + * IFR configuration data. + * @note It is highly recommended to parse the IFR configuration from + * a working IFR block (this should be done with parse_IFR_data_config()). + * Then it is possible to write the new parameters inside the IFR_config + * structure. + * @param data Pointer to the buffer that contains the original data. It + * will be modified according to the new data in the IFR_config + * structure. Then this data must be written in the last + * 64-byte block in the IFR. + * Its size must be 64 bytes. + * @retval None + */ +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); + +/** + * @brief Get BlueNRG hardware and firmware version + * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). + * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN + * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. + * @retval Status of the call + */ +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); + +/** + * @brief Get BlueNRG updater version + * @param version This parameter returns the updater version. If the updadter version is 0x03 + * the chip has the updater old, needs to update the bootloader. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterVersion(uint8_t *version); + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version); + +/** + * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on + * the HW bootloader related to the 32 MHz external crystal oscillator. + * @retval TRUE if the HW bootloader is already patched, FALSE otherwise + */ +uint8_t isHWBootloader_Patched(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__BLUENRG_UTILS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file bluenrg_targets.h + * @author AST / EST + * @version V0.0.1 + * @date 24-July-2015 + * @brief This header file is intended to manage the differences between + * the different supported base-boards which might mount the + * X_NUCLEO_IDB0XA1 BlueNRG BLE Expansion Board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent from recursive inclusion --------------------------------*/ +#ifndef _BLUENRG_TARGETS_H_ +#define _BLUENRG_TARGETS_H_ + +#if !defined(BLUENRG_PIN_SPI_MOSI) +#define BLUENRG_PIN_SPI_MOSI (D11) +#endif +#if !defined(BLUENRG_PIN_SPI_MISO) +#define BLUENRG_PIN_SPI_MISO (D12) +#endif +#if !defined(BLUENRG_PIN_SPI_nCS) +#define BLUENRG_PIN_SPI_nCS (A1) +#endif +#if !defined(BLUENRG_PIN_SPI_RESET) +#define BLUENRG_PIN_SPI_RESET (D7) +#endif +#if !defined(BLUENRG_PIN_SPI_IRQ) +#define BLUENRG_PIN_SPI_IRQ (A0) +#endif + +/* NOTE: Refer to README for further details regarding BLUENRG_PIN_SPI_SCK */ +#if !defined(BLUENRG_PIN_SPI_SCK) +#define BLUENRG_PIN_SPI_SCK (D3) +#endif + +/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv) + * Mode 0x01: slave or master, 1 connection + * Mode 0x02: slave or master, 1 connection + * Mode 0x03: master/slave, 8 connections + * Mode 0x04: master/slave, 4 connections (simultaneous scanning and advertising) + * Check Table 285 of + * BlueNRG-MS Bluetooth LE stack application command interface (ACI) User Manual (UM1865) at st.com + */ +#if !defined(BLUENRG_STACK_MODE) +#define BLUENRG_STACK_MODE (0x04) +#endif + +#endif // _BLUENRG_TARGTES_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef _BTLE_H_ +#define _BTLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "bluenrg_aci.h" +#include "ble_hci_const.h" +#include "bluenrg_hal_aci.h" +#include "stm32_bluenrg_ble.h" +#include "bluenrg_gap.h" +#include "bluenrg_gatt_server.h" + +extern uint16_t g_gap_service_handle; +extern uint16_t g_appearance_char_handle; +extern uint16_t g_device_name_char_handle; +extern uint16_t g_preferred_connection_parameters_char_handle; + +void btleInit(void); +void SPI_Poll(void); +void User_Process(void); +void setConnectable(void); +void setVersionString(uint8_t hwVersion, uint16_t fwVersion); +const char* getVersionString(void); +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type); + + +extern int btle_handler_pending; +extern void btle_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.h + * @author CL + * @version V1.0.1 + * @date 15-June-2014 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_BLUENRG_BLE_H +#define __STM32_BLUENRG_BLE_H + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdint.h> +#include "ble_gp_timer.h" +#include "ble_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup X-NUCLEO-IDB04A1 + * @{ + */ + +/** @addtogroup STM32_BLUENRG_BLE + * @{ + */ + +/** @defgroup STM32_BLUENRG_BLE_Exported_Functions + * @{ + */ + +// FIXME: add prototypes for BlueNRG here +void BlueNRG_RST(void); +uint8_t BlueNRG_DataPresent(void); +void BlueNRG_HW_Bootloader(void); +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size); +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, + uint8_t Nb_bytes1, + uint8_t Nb_bytes2); +void Clear_SPI_EXTI_Flag(void); + +void print_csv_time(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_BLUENRG_BLE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_debug.h" + +#ifndef __PAYLOAD_H__ +#define __PAYLOAD_H__ + +class UnitPayload +{ +public: + uint8_t length; + uint8_t id; + uint8_t *data; + uint8_t *idptr; + + + + void set_length(uint8_t l) { + length=l; + } + + void set_id(uint8_t i) { + id=i; + } + + void set_data(uint8_t* data1) { + for(int j=0;j<length;j++) + { + data[j]=data1[j]; + } + } + + uint8_t get_length() { + return length; + } + + uint8_t get_id() { + return id; + } + + uint8_t* get_data() { + return data; + } + +}; + +class Payload { + UnitPayload *payload; + int stringLength; + int payloadUnitCount; + +public: + Payload(const uint8_t *tokenString, uint8_t string_ength); + Payload(); + ~Payload(); + uint8_t getPayloadUnitCount(); + + uint8_t getIDAtIndex(int index); + uint8_t getLengthAtIndex(int index); + uint8_t* getDataAtIndex(int index); + int8_t getInt8AtIndex(int index); + uint16_t getUint16AtIndex(int index); + uint8_t* getSerializedAdDataAtIndex(int index); +}; + + +class PayloadUnit { +private: + uint8_t* lenPtr; + uint8_t* adTypePtr; + uint8_t* dataPtr; + +public: + PayloadUnit() { + lenPtr = NULL; + adTypePtr = NULL; + dataPtr = NULL; + } + + PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { + lenPtr = len; + adTypePtr = adType; + dataPtr = data; + } + + void setLenPtr(uint8_t *len) { + lenPtr = len; + } + + void setAdTypePtr(uint8_t *adType) { + adTypePtr = adType; + } + + void setDataPtr(uint8_t *data) { + dataPtr = data; + } + + uint8_t* getLenPtr() { + return lenPtr; + } + + uint8_t* getAdTypePtr() { + return adTypePtr; + } + + uint8_t* getDataPtr() { + return dataPtr; + } + + void printDataAsHex() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("0x%x ", dataPtr[i]); + } + PRINTF("\n"); + } + + void printDataAsString() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("%c", dataPtr[i]); + } + PRINTF("\n"); + } + +}; + +class PayloadPtr { +private: + PayloadUnit *unit; + int payloadUnitCount; +public: + PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + int stringLength = string_ength; + payloadUnitCount = 0; + + int index = 0; + while(index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + // allocate memory to unit + unit = new PayloadUnit[payloadUnitCount]; + int i = 0; + int nextUnitOffset = 0; + + while(i<payloadUnitCount) { + unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); + unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); + unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); + + nextUnitOffset += *unit[i].getLenPtr()+1; + i++; + + } + } + + PayloadUnit getUnitAtIndex(int index) { + return unit[index]; + } + + int getPayloadUnitCount() { return payloadUnitCount; } + + ~PayloadPtr() { + if(unit) delete[] unit; + + unit = NULL; + } +}; + +#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include "ble_status.h" +#include "ble_hal_types.h" + +#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do {\ + uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ + }while(0) + + +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); + +#endif // __UTIL_H__ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/mbed_lib.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "bluenrg", + "target_overrides": { + "K64F": { + "target.macros_add": ["BLUENRG_PIN_SPI_SCK=D13"] + }, + "DISCO_L475VG_IOT01A": { + "target.macros_add": ["BLUENRG_PIN_SPI_MOSI=PC_12", + "BLUENRG_PIN_SPI_MISO=PC_11", + "BLUENRG_PIN_SPI_nCS=PD_13", + "BLUENRG_PIN_SPI_RESET=PA_8", + "BLUENRG_PIN_SPI_IRQ=PE_6", + "BLUENRG_PIN_SPI_SCK=PC_10"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,37 @@ +{ + "name": "x-nucleo-idb0xa1", + "version": "2.2.0", + "description": "ST driver for the mbed BLE API.", + "keywords": [ + "expansion", + "board", + "x-nucleo", + "nucleo", + "ST", + "STM", + "Bluetooth", + "BLE" + ], + "author": "Andrea Palmieri", + "repository": { + "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git", + "type": "git" + }, + "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "extraIncludes": [ + "x-nucleo-idb0xa1", + "x-nucleo-idb0xa1/utils", + "x-nucleo-idb0xa1/platform", + "x-nucleo-idb0xa1/bluenrg-hci" + ], + "dependencies": { + "mbed-drivers": ">=0.11.3", + "ble": "^2.7.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,474 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.cpp + * @author STMicroelectronics + * @brief Implementation of BLEDeviceInstanceBase + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGDevice + * @brief BlueNRG BLE_API Device Adaptation + * @{ + */ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGDevice.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" + +#include "btle.h" +#include "ble_utils.h" +#include "ble_osal.h" + +#include "ble_debug.h" +#include "stm32_bluenrg_ble.h" + +extern "C" { + #include "ble_hci.h" + #include "bluenrg_utils.h" +} + +#define HEADER_SIZE 5 +#define MAX_BUFFER_SIZE 255 + +/** + * The singleton which represents the BlueNRG transport for the BLEDevice. + * + * See file 'bluenrg_targets.h' for details regarding the peripheral pins used! + */ +#include "bluenrg_targets.h" + +BlueNRGDevice bluenrgDeviceInstance(BLUENRG_PIN_SPI_MOSI, + BLUENRG_PIN_SPI_MISO, + BLUENRG_PIN_SPI_SCK, + BLUENRG_PIN_SPI_nCS, + BLUENRG_PIN_SPI_RESET, + BLUENRG_PIN_SPI_IRQ); + +/** +* BLE-API requires an implementation of the following function in order to +* obtain its transport handle. +*/ +BLEInstanceBase * +createBLEInstance(void) +{ + return (&bluenrgDeviceInstance); +} + +/**************************************************************************/ +/** + @brief Constructor + * @param mosi mbed pin to use for MOSI line of SPI interface + * @param miso mbed pin to use for MISO line of SPI interface + * @param sck mbed pin to use for SCK line of SPI interface + * @param cs mbed pin to use for not chip select line of SPI interface + * @param rst mbed pin to use for BlueNRG reset + * @param irq mbed pin for BlueNRG IRQ +*/ +/**************************************************************************/ +BlueNRGDevice::BlueNRGDevice(PinName mosi, + PinName miso, + PinName sck, + PinName cs, + PinName rst, + PinName irq) : + isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq) +{ + // Setup the spi for 8 bit data, low clock polarity, + // 1-edge phase, with an 8MHz clock rate + spi_.format(8, 0); + spi_.frequency(8000000); + + // Deselect the BlueNRG chip by keeping its nCS signal high + nCS_ = 1; + + wait_us(500); + + // Prepare communication between the host and the BlueNRG SPI interface + HCI_Init(); + + // Set the interrupt handler for the device + irq_.mode(PullDown); // set irq mode + irq_.rise(&HCI_Isr); +} + +/**************************************************************************/ +/** + @brief Destructor +*/ +/**************************************************************************/ +BlueNRGDevice::~BlueNRGDevice(void) +{ +} + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param hw_version The HW version is written to this parameter + * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise + */ +uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version) +{ + uint8_t status; + + status = getBlueNRGUpdaterHWVersion(hw_version); + + return (status); +} + +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns BLE_STATUS_SUCCESS on success, or a number + * not equal to 0 in case of error + * (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size) +{ + int status = program_device(fw_image, fw_size); + + return (status); +} + + +/** + * @brief Initialises anything required to start using BLE + * @param[in] instanceID + * The ID of the instance to initialize. + * @param[in] callback + * A callback for when initialization completes for a BLE + * instance. This is an optional parameter set to NULL when not + * supplied. + * + * @return BLE_ERROR_NONE if the initialization procedure was started + * successfully. + */ +ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback) +{ + if (isInitialized) { + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_ALREADY_INITIALIZED + }; + callback.call(&context); + return BLE_ERROR_ALREADY_INITIALIZED; + } + + // Init the BlueNRG/BlueNRG-MS stack + btleInit(); + + isInitialized = true; + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_NONE + }; + callback.call(&context); + + return BLE_ERROR_NONE; +} + + +/** + @brief Resets the BLE HW, removing any existing services and + characteristics + @param[in] void + @returns void +*/ +void BlueNRGDevice::reset(void) +{ + /* Reset BlueNRG SPI interface. Hold reset line to 0 for 1500us */ + rst_ = 0; + wait_us(1500); + rst_ = 1; + + /* Wait for the radio to come back up */ + wait_us(5000); +} + +/*! + @brief Wait for any BLE Event like BLE Connection, Read Request etc. + @param[in] void + @returns char * +*/ +void BlueNRGDevice::waitForEvent(void) +{ + bool must_return = false; + + do { + bluenrgDeviceInstance.processEvents(); + + if(must_return) return; + + __WFE(); /* it is recommended that SEVONPEND in the + System Control Register is NOT set */ + must_return = true; /* after returning from WFE we must guarantee + that conrol is given back to main loop before next WFE */ + } while(true); + +} + +/*! + @brief get GAP version + @brief Get the BLE stack version information + @param[in] void + @returns char * + @returns char * +*/ +const char *BlueNRGDevice::getVersion(void) +{ + return getVersionString(); +} + +/**************************************************************************/ +/*! + @brief get reference to GAP object + @param[in] void + @returns Gap& +*/ +/**************************************************************************/ +Gap &BlueNRGDevice::getGap() +{ + return BlueNRGGap::getInstance(); +} + +const Gap &BlueNRGDevice::getGap() const +{ + return BlueNRGGap::getInstance(); +} + +/**************************************************************************/ +/*! + @brief get reference to GATT server object + @param[in] void + @returns GattServer& +*/ +/**************************************************************************/ +GattServer &BlueNRGDevice::getGattServer() +{ + return BlueNRGGattServer::getInstance(); +} + +const GattServer &BlueNRGDevice::getGattServer() const +{ + return BlueNRGGattServer::getInstance(); +} + +/**************************************************************************/ +/*! + @brief shut down the BLE device + @param[out] error if any +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::shutdown(void) { + PRINTF("BlueNRGDevice::reset\n"); + + if (!isInitialized) { + return BLE_ERROR_INITIALIZATION_INCOMPLETE; + } + + /* Reset the BlueNRG device first */ + reset(); + + /* Shutdown the BLE API and BlueNRG glue code */ + ble_error_t error; + + /* GattServer instance */ + error = BlueNRGGattServer::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* GattClient instance */ + error = BlueNRGGattClient::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* Gap instance */ + error = BlueNRGGap::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + isInitialized = false; + + PRINTF("BlueNRGDevice::reset complete\n"); + return BLE_ERROR_NONE; + +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size) +{ + uint16_t byte_count; + uint8_t len = 0; + uint8_t char_ff = 0xff; + volatile uint8_t read_char; + + uint8_t i = 0; + volatile uint8_t tmpreg; + + uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00}; + uint8_t header_slave[HEADER_SIZE]; + + /* Select the chip */ + nCS_ = 0; + + /* Read the header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = (uint8_t)(tmpreg); + } + + if (header_slave[0] == 0x02) { + /* device is ready */ + byte_count = (header_slave[4]<<8)|header_slave[3]; + + if (byte_count > 0) { + + /* avoid to read more data that size of the buffer */ + if (byte_count > buff_size){ + byte_count = buff_size; + } + + for (len = 0; len < byte_count; len++){ + read_char = spi_.write(char_ff); + buffer[len] = read_char; + } + } + } + /* Release CS line to deselect the chip */ + nCS_ = 1; + + // Add a small delay to give time to the BlueNRG to set the IRQ pin low + // to avoid a useless SPI read at the end of the transaction + for(volatile int i = 0; i < 2; i++)__NOP(); + +#ifdef PRINT_CSV_FORMAT + if (len > 0) { + print_csv_time(); + for (int i=0; i<len; i++) { + PRINT_CSV(" %02x", buffer[i]); + } + PRINT_CSV("\n"); + } +#endif + + return len; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRGDevice::spiWrite(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t result = 0; + uint32_t i; + volatile uint8_t tmpreg; + + unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00}; + + disable_irq(); + + /* CS reset */ + nCS_ = 0; + + /* Exchange header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = tmpreg; + } + + if (header_slave[0] == 0x02) { + /* SPI is ready */ + if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { + + /* Buffer is big enough */ + for (i = 0; i < Nb_bytes1; i++) { + spi_.write(*(data1 + i)); + } + for (i = 0; i < Nb_bytes2; i++) { + spi_.write(*(data2 + i)); + } + } else { + /* Buffer is too small */ + result = -2; + } + } else { + /* SPI is not ready */ + result = -1; + } + + /* Release CS line */ + //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); + nCS_ = 1; + + enable_irq(); + + return result; +} + +bool BlueNRGDevice::dataPresent() +{ + return (irq_ == 1); +} + +void BlueNRGDevice::disable_irq() +{ + irq_.disable_irq(); +} + +void BlueNRGDevice::enable_irq() +{ + irq_.enable_irq(); +} + +void BlueNRGDevice::processEvents() { + btle_handler(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,68 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattClient.h" + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + uuid = uuidIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + + void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) { + lastHandle = lastHandleIn; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1477 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file BlueNRGGap.cpp + * @author STMicroelectronics + * @brief Implementation of BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGap + * @brief BlueNRG BLE_API GAP Adaptation + * @{ + */ + +#include "BlueNRGDevice.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_payload.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/* + * Utility to process GAP specific events (e.g., Advertising timeout) + */ +void BlueNRGGap::Process(void) +{ + if(AdvToFlag) { + AdvToFlag = false; + stopAdvertising(); + } + + if(ScanToFlag) { + ScanToFlag = false; + stopScan(); + } +} + +/**************************************************************************/ +/*! + @brief Sets the advertising parameters and payload for the device. + Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API + + @params[in] advData + The primary advertising data payload + @params[in] scanResponse + The optional Scan Response payload if the advertising + type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED + in \ref GapAdveritinngParams + + @returns \ref ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @retval BLE_ERROR_BUFFER_OVERFLOW + The proposed action would cause a buffer overflow. All + advertising payloads must be <= 31 bytes, for example. + + @retval BLE_ERROR_NOT_IMPLEMENTED + A feature was requested that is not yet supported in the + nRF51 firmware or hardware. + + @retval BLE_ERROR_PARAM_OUT_OF_RANGE + One of the proposed values is outside the valid range. + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) +{ + PRINTF("BlueNRGGap::setAdvertisingData\n\r"); + /* Make sure we don't exceed the advertising payload length */ + if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + PRINTF("Exceeded the advertising payload length\n\r"); + return BLE_ERROR_BUFFER_OVERFLOW; + } + + /* Make sure we have a payload! */ + if (advData.getPayloadLen() != 0) { + PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); + + /* Align the GAP Service Appearance Char value coherently + This setting is duplicate (see below GapAdvertisingData::APPEARANCE) + since BLE API has an overloaded function for appearance + */ + STORE_LE_16(deviceAppearance, advData.getAppearance()); + setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0])); + + + for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { + loadPtr.getUnitAtIndex(index); + + PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); + PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); + + switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { + /**< TX Power Level (in dBm) */ + case GapAdvertisingData::TX_POWER_LEVEL: + { + PRINTF("Advertising type: TX_POWER_LEVEL\n\r"); + int8_t enHighPower = 0; + int8_t paLevel = 0; + + int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); + tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); +#ifdef DEBUG + PRINTF("dbm=%d, ret=%d\n\r", dbm, ret); + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); +#endif + if(ret == BLE_STATUS_SUCCESS) { + aci_hal_set_tx_power_level(enHighPower, paLevel); + } + break; + } + /**< Appearance */ + case GapAdvertisingData::APPEARANCE: + { + PRINTF("Advertising type: APPEARANCE\n\r"); + + GapAdvertisingData::Appearance appearanceP; + memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2); + + PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]); + /* Align the GAP Service Appearance Char value coherently */ + setAppearance(appearanceP); + break; + } + + } // end switch + + } //end for + + } + + // update the advertising data in the shield if advertising is running + if (state.advertising == 1) { + tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS != ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload()); + if (ret) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + } + + _advData = advData; + _scanResponse = scanResponse; + + return BLE_ERROR_NONE; +} + +/* + * Utility to set ADV timeout flag + */ +void BlueNRGGap::setAdvToFlag(void) { + AdvToFlag = true; + signalEventsToProcess(); +} + +/* + * ADV timeout callback + */ +#ifdef AST_FOR_MBED_OS +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().stopAdvertising(); +} +#else +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().setAdvToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getAdvTimeout(); + t.detach(); /* disable the callback from the timeout */ +} +#endif /* AST_FOR_MBED_OS */ + +/* + * Utility to set SCAN timeout flag + */ +void BlueNRGGap::setScanToFlag(void) { + ScanToFlag = true; + signalEventsToProcess(); +} + +static void scanTimeoutCB(void) +{ + BlueNRGGap::getInstance().setScanToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getScanTimeout(); + t.detach(); /* disable the callback from the timeout */ +} + +/**************************************************************************/ +/*! + @brief Starts the BLE HW, initialising any services that were + added before this function was called. + + @param[in] params + Basic advertising details, including the advertising + delay, timeout and how the device should be advertised + + @note All services must be added before calling this function! + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ + +ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) +{ + tBleStatus ret; + int err; + + /* Make sure we support the advertising type */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { + /* ToDo: This requires a proper security implementation, etc. */ + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /* Check interval range */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { + /* Min delay is slightly longer for unconnectable devices */ + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } else { + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } + + /* Check timeout is zero for Connectable Directed */ + if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { + /* Timeout must be 0 with this type, although we'll never get here */ + /* since this isn't implemented yet anyway */ + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* Check timeout for other advertising types */ + if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && + (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* + * Advertising filter policy setting + * FIXME: the Security Manager should be implemented + */ + AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode(); + if(mode != ADV_POLICY_IGNORE_WHITELIST) { + ret = aci_gap_configure_whitelist(); + if(ret != BLE_STATUS_SUCCESS) { + PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret); + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } + + uint8_t advFilterPolicy = NO_WHITE_LIST_USE; + switch(mode) { + case ADV_POLICY_FILTER_SCAN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN; + break; + case ADV_POLICY_FILTER_CONN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN; + break; + case ADV_POLICY_FILTER_ALL_REQS: + advFilterPolicy = WHITE_LIST_FOR_ALL; + break; + default: + advFilterPolicy = NO_WHITE_LIST_USE; + break; + } + + /* Check the ADV type before setting scan response data */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED || + params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) { + + /* set scan response data */ + PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen()); + ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS!=ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + } else { + hci_le_set_scan_resp_data(0, NULL); + } + + setAdvParameters(); + PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType()); + + err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload()); + + if (err) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + + tBDAddr dummy_addr = { 0 }; + uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval; + uint16_t advIntervalMax = advIntervalMin + 1; + + err = hci_le_set_advertising_parameters( + advIntervalMin, + advIntervalMax, + params.getAdvertisingType(), + addr_type, + 0x00, + dummy_addr, + /* all channels */ 7, + advFilterPolicy + ); + + if (err) { + PRINTF("impossible to set advertising parameters\n\r"); + PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1); + PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy); + return BLE_ERROR_INVALID_PARAM; + } + + err = hci_le_set_advertise_enable(0x01); + if (err) { + PRINTF("impossible to start advertising\n\r"); + return BLE_ERROR_UNSPECIFIED; + } + + if(params.getTimeout() != 0) { + PRINTF("!!! attaching adv to!!!\n"); +#ifdef AST_FOR_MBED_OS + minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000)); +#else + advTimeout.attach(advTimeoutCB, params.getTimeout()); +#endif + } + + return BLE_ERROR_NONE; + +} + + +/**************************************************************************/ +/*! + @brief Stops the BLE HW and disconnects from any devices + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::stopAdvertising(void) +{ + if(state.advertising == 1) { + + int err = hci_le_set_advertise_enable(0); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + PRINTF("Advertisement stopped!!\n\r") ; + //Set GapState_t::advertising state + state.advertising = 0; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason) +{ + tBleStatus ret; + + ret = aci_gap_terminate(connectionHandle, reason); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_COMMAND_DISALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason) +{ + return disconnect(m_connectionHandle, reason); +} + +/**************************************************************************/ +/*! + @brief Sets the 16-bit connection handle + + @param[in] conn_handle + Connection Handle which is set in the Gap Instance + + @returns void +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionHandle(uint16_t conn_handle) +{ + m_connectionHandle = conn_handle; +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit connection handle + + @param[in] void + + @returns uint16_t + Connection Handle of the Gap Instance +*/ +/**************************************************************************/ +uint16_t BlueNRGGap::getConnectionHandle(void) +{ + return m_connectionHandle; +} + +/**************************************************************************/ +/*! + @brief Sets the BLE device address. SetAddress will reset the BLE + device and re-initialize BTLE. Will not start advertising. + + @param[in] type + Type of Address + + @param[in] address[6] + Value of the Address to be set + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address) +{ + if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if(type == BLEProtocol::AddressType::PUBLIC){ + tBleStatus ret = aci_hal_write_config_data( + CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + address + ); + if(ret != BLE_STATUS_SUCCESS) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } else if (type == BLEProtocol::AddressType::RANDOM_STATIC) { + // ensure that the random static address is well formed + if ((address[5] & 0xC0) != 0xC0) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // thanks to const correctness of the API ... + tBDAddr random_address = { 0 }; + memcpy(random_address, address, sizeof(random_address)); + int err = hci_le_set_random_address(random_address); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // It is not possible to get the bluetooth address when it is set + // store it locally in class data member + memcpy(bdaddr, address, sizeof(bdaddr)); + } else { + // FIXME random addresses are not supported yet + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + // if we're here then the address was correctly set + // commit it inside the addr_type + addr_type = type; + isSetAddress = true; + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Returns boolean if the address of the device has been set + or not + + @returns bool + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +bool BlueNRGGap::getIsSetAddress() +{ + return isSetAddress; +} + +/**************************************************************************/ +/*! + @brief Returns the address of the device if set + + @returns Pointer to the address if Address is set else NULL + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) +{ + uint8_t bdaddr[BDADDR_SIZE]; + uint8_t data_len_out; + + // precondition, check that pointers in input are valid + if (typeP == NULL || address == NULL) { + return BLE_ERROR_INVALID_PARAM; + } + + if (addr_type == BLEProtocol::AddressType::PUBLIC) { + tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr); + if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) { + return BLE_ERROR_UNSPECIFIED; + } + } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) { + // FIXME hci_read_bd_addr and + // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1 + // does not work, use the address stored in class data member + memcpy(bdaddr, this->bdaddr, sizeof(bdaddr)); + } else { + // FIXME: should be implemented with privacy features + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + *typeP = addr_type; + memcpy(address, bdaddr, BDADDR_SIZE); + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief obtains preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + + if (!g_preferred_connection_parameters_char_handle) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // Peripheral preferred connection parameters are an array of 4 uint16_t + uint8_t parameters_packed[parameter_size * 4]; + uint16_t bytes_read = 0; + + tBleStatus err = aci_gatt_read_handle_value( + g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE, + sizeof(parameters_packed), + &bytes_read, + parameters_packed + ); + + PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read); + + // check that the read succeed and the result have the expected length + if (err || bytes_read != sizeof(parameters_packed)) { + return BLE_ERROR_UNSPECIFIED; + } + + // memcpy field by field + memcpy(¶ms->minConnectionInterval, parameters_packed, parameter_size); + memcpy(¶ms->maxConnectionInterval, ¶meters_packed[parameter_size], parameter_size); + memcpy(¶ms->slaveLatency, ¶meters_packed[2 * parameter_size], parameter_size); + memcpy(¶ms->connectionSupervisionTimeout, ¶meters_packed[3 * parameter_size], parameter_size); + + return BLE_ERROR_NONE; +} + + +/**************************************************************************/ +/*! + @brief sets preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + uint8_t parameters_packed[parameter_size * 4]; + + // ensure that parameters are correct + // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC + if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) && + params->minConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) && + params->maxConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (params->slaveLatency > 0x01F3) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) && + params->connectionSupervisionTimeout != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // copy the parameters inside the byte array + memcpy(parameters_packed, ¶ms->minConnectionInterval, parameter_size); + memcpy(¶meters_packed[parameter_size], ¶ms->maxConnectionInterval, parameter_size); + memcpy(¶meters_packed[2 * parameter_size], ¶ms->slaveLatency, parameter_size); + memcpy(¶meters_packed[3 * parameter_size], ¶ms->connectionSupervisionTimeout, parameter_size); + + tBleStatus err = aci_gatt_update_char_value( + g_gap_service_handle, + g_preferred_connection_parameters_char_handle, + /* offset */ 0, + sizeof(parameters_packed), + parameters_packed + ); + + if (err) { + PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ; + switch (err) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief updates preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) +{ + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(gapRole == Gap::CENTRAL) { + ret = aci_gap_start_connection_update(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout, + CONN_L1, CONN_L2); + } else { + ret = aci_l2cap_connection_parameter_update_request(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout); + } + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case ERR_COMMAND_DISALLOWED: + case BLE_STATUS_NOT_ALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sets the Device Name Characteristic + + @param[in] deviceName + pointer to device name to be set + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) +{ + tBleStatus ret; + uint8_t nameLen = 0; + + nameLen = strlen((const char*)deviceName); + PRINTF("DeviceName Size=%d\n\r", nameLen); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_device_name_char_handle, + 0, + nameLen, + deviceName); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Gets the Device Name Characteristic + + @param[in] deviceName + pointer to device name + + @param[in] lengthP + pointer to device name length + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) +{ + tBleStatus ret; + + ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + *lengthP, + (uint16_t *)lengthP, + deviceName); + PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } +} + +/**************************************************************************/ +/*! + @brief Sets the Device Appearance Characteristic + + @param[in] appearance + device appearance + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance) +{ + tBleStatus ret; + uint8_t deviceAppearance[2]; + + STORE_LE_16(deviceAppearance, appearance); + PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_appearance_char_handle, + 0, 2, (uint8_t *)deviceAppearance); + if (BLE_STATUS_SUCCESS == ret){ + return BLE_ERROR_NONE; + } + + PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Gets the Device Appearance Characteristic + + @param[in] appearance + pointer to device appearance value + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) +{ + tBleStatus ret; + uint16_t lengthP = 2; + + ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + lengthP, + &lengthP, + (uint8_t*)appearanceP); + PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + +} + +GapScanningParams* BlueNRGGap::getScanningParams(void) +{ + return &_scanningParams; +} + +static void makeConnection(void) +{ + BlueNRGGap::getInstance().createConnection(); +} + +void BlueNRGGap::Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI) +{ + switch (reason) { + case DEVICE_FOUND: + { + GapAdvertisingParams::AdvertisingType_t type; + bool isScanResponse = false; + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * Private Random Address + * => scan_results = FALSE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type); + if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV || + (addr_type == RESOLVABLE_PRIVATE_ADDR || + addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) { + return; + } + + switch(adv_type) { + case ADV_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + break; + case ADV_DIRECT_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED; + break; + case ADV_SCAN_IND: + case SCAN_RSP: + type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED; + isScanResponse = true; + break; + case ADV_NONCONN_IND: + type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED; + break; + default: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + } + + PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n", + *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + if(!_connecting) { + processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data); + } + PRINTF("!!!After processAdvertisementReport\n\r"); + } + break; + + case DISCOVERY_COMPLETE: + // The discovery is complete. If this is due to a stop scanning (i.e., the device + // we are interested in has been found) and a connection has been requested + // then we start the device connection. + PRINTF("DISCOVERY_COMPLETE\n\r"); + _scanning = false; + + // Since the DISCOVERY_COMPLETE event can be received during the scanning interval, + // we need to delay the starting of connection + uint16_t delay = (_scanningParams.getInterval()*0.625); + +#ifdef AST_FOR_MBED_OS + if(_connecting) { + minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay)); + } +#else + Clock_Wait(delay); + if(_connecting) { + makeConnection(); + } +#endif /* AST_FOR_MBED_OS */ + + break; + } +} + +ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) +{ + + tBleStatus ret = BLE_STATUS_SUCCESS; + + // Stop ADV before scanning + /* + if (state.advertising == 1) { + stopAdvertising(); + } + */ + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * White List is empty + * => scan operation = FAILURE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + uint8_t whiteListSize = whitelistAddresses.size; + if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + ret = btleStartRadioScan(scanningParams.getActiveScanning(), + scanningParams.getInterval(), + scanningParams.getWindow(), + addr_type); + + PRINTF("Scanning...\n\r"); + PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000); + PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000); + //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval()); + //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1); + //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2); + if (BLE_STATUS_SUCCESS == ret){ + PRINTF("Observation Procedure Started\n"); + _scanning = true; + + if(scanningParams.getTimeout() != 0) { + PRINTF("!!! attaching scan to!!!\n"); + scanTimeout.attach(scanTimeoutCB, scanningParams.getTimeout()); + } + + return BLE_ERROR_NONE; + } + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + switch (ret) { + case BLE_STATUS_INVALID_CID: + PRINTF("Observation Procedure not implemented!!!\n\r"); + return BLE_ERROR_NOT_IMPLEMENTED; + default: + PRINTF("Observation Procedure failed (0x%02X)\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } + +} + +ble_error_t BlueNRGGap::stopScan() { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(_scanning) { + ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC); + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Discovery Procedure Terminated\n"); + return BLE_ERROR_NONE; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief set Tx power level + @param[in] txPower Transmission Power level + @returns ble_error_t +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setTxPower(int8_t txPower) +{ + tBleStatus ret; + + int8_t enHighPower = 0; + int8_t paLevel = 0; + + ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + ret = aci_hal_set_tx_power_level(enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief get permitted Tx power values + @param[in] values pointer to pointer to permitted power values + @param[in] num number of values +*/ +/**************************************************************************/ +void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { + static const int8_t permittedTxValues[] = { + -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8 + }; + + *valueArrayPP = permittedTxValues; + *countP = sizeof(permittedTxValues) / sizeof(int8_t); +} + +/**************************************************************************/ +/*! + @brief Set advertising parameters according to the current state + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setAdvParameters(void) +{ + uint32_t advIntMS; + + if(state.connected == 1) { + advIntMS = (conn_min_interval*1.25)-GUARD_INT; + advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS); + + PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval); + } else { + advInterval = _advParams.getIntervalInADVUnits(); + } +} + +/**************************************************************************/ +/*! + @brief Set connection parameters according to the current state (ADV and/or SCAN) + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionParameters(void) +{ + if (state.connected == 1) { + + PRINTF("state.connected=1\r\n"); + scanInterval = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(conn_min_interval*1.25); + scanWindow = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(((conn_min_interval*1.25)/100)*60); // scanWin ~= 60%(scanInt) + + } else if (state.advertising == 1) { + + if (_scanningParams.getInterval() < advInterval) { + PRINTF("state.adv=1 scanInterval<advInterval\r\n"); + scanInterval = advInterval; + scanWindow = advInterval; + } else { + PRINTF("state.adv=1 scanInterval>=advInterval\r\n"); + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + } + + if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms + conn_min_interval = MAX_INT_CONN; + conn_max_interval = MAX_INT_CONN; + } else { + conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + } + + } else { + + PRINTF("state.adv = 0\r\n"); + + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) || + SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms + conn_min_interval = DEF_INT_CONN; + conn_max_interval = DEF_INT_CONN; + } else { + conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + } + } + PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval)); + PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow)); + PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25)); + PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25)); + +} + +ble_error_t BlueNRGGap::createConnection () +{ + tBleStatus ret; + + /* + Before creating connection, set parameters according + to previous or current procedure (ADV and/or SCAN) + */ + setConnectionParameters(); + + /* + Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, + Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max + */ + ret = aci_gap_create_connection(scanInterval, + scanWindow, + _peerAddrType, + (unsigned char*)_peerAddr, + addr_type, + conn_min_interval, conn_max_interval, 0, + SUPERV_TIMEOUT, CONN_L1, CONN_L1); + + //_connecting = false; + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Connection started.\n"); + _connecting = false; + return BLE_ERROR_NONE; + } +} + +ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) +{ + /* avoid compiler warnings about unused variables */ + (void)connectionParams; + + setScanParams(scanParams->getInterval(), + scanParams->getWindow(), + scanParams->getTimeout(), + scanParams->getActiveScanning() + ); + + // Save the peer address + for(int i=0; i<BDADDR_SIZE; i++) { + _peerAddr[i] = peerAddr[i]; + } + _peerAddrType = peerAddrType; + + _connecting = true; + + if(_scanning) { + stopScan(); + } else { + PRINTF("Calling createConnection from connect()\n\r"); + return createConnection(); + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the advertising policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode) +{ + advertisingPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the scanning policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode) +{ + scanningPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Get the current advertising policy filter mode. + + @returns The advertising policy filter mode. +*/ +/**************************************************************************/ +Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const +{ + return advertisingPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Get the current scanning policy filter mode. + + @returns The scanning policy filter mode. + +*/ +/**************************************************************************/ +Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const +{ + return scanningPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGap's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::reset(void) +{ + PRINTF("BlueNRGGap::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (Gap::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + AdvToFlag = false; + ScanToFlag = false; + + /* Clear derived class members */ + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + return BLE_ERROR_NONE; +} + +void BlueNRGGap::setConnectionInterval(uint16_t interval) { + conn_min_interval = interval; + conn_max_interval = interval; +} + +Gap::Role_t BlueNRGGap::getGapRole(void) +{ + return (gapRole); +} + +void BlueNRGGap::setGapRole(Gap::Role_t role) +{ + gapRole = role; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,403 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTClient + * @brief BlueNRG BLE_API GattClient Adaptation + * @{ + */ + +#include "BlueNRGGattClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +#include <new> +#include <assert.h> + +ble_error_t BlueNRGGattClient::createGattConnectionClient(Gap::Handle_t connectionHandle) +{ + if(MAX_ACTIVE_CONNECTIONS <= _numConnections) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + for(uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + + if(_connectionPool[i] == NULL) { + BlueNRGGattConnectionClient *gattConnectionClient = new(std::nothrow) BlueNRGGattConnectionClient(this, connectionHandle); + + if (gattConnectionClient == NULL) { + return BLE_ERROR_NO_MEM; + } + + _connectionPool[i] = gattConnectionClient; + _connectionPool[i]->onServiceDiscoveryTermination(terminationCallback); + _numConnections++; + + PRINTF("createGattConnectionClient: _connectionPool index=%d\r\n", i); + PRINTF("createGattConnectionClient: succesfully added new gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + break; + } + } + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattClient::removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason) +{ + + PRINTF("removeGattConnectionClient: connectionHandle=%d reason=0x%x\r\n", connectionHandle, reason); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("removeGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("removeGattConnectionClient: Found gattConnectionClient\r\n"); + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + PRINTF("removeGattConnectionClient: succesfully removed gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + + break; + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + + return BLE_ERROR_NONE; +} + +BlueNRGGattConnectionClient * BlueNRGGattClient::getGattConnectionClient(Gap::Handle_t connectionHandle) { + PRINTF("getGattConnectionClient\r\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("getGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("getGattConnectionClient: Found gattConnectionClient\r\n"); + return _connectionPool[i]; + } + } + + return NULL; +} + +void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code) { + + if(error_code != BLE_STATUS_SUCCESS) { + return; + } + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->gattProcedureCompleteCB(error_code); +} + +void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServicesCB(event_data_length, + attribute_data_length, + attribute_data_list); +} + +void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServiceCB(event_data_length, + handles_info_list); +} + +ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->findServiceChars(); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharsCB(event_data_length, + handle_value_pair_length, + handle_value_pair); +} + +void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharByUUIDCB(event_data_length, + attr_handle, + attr_value); +} + +void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->discAllCharacDescCB(event_data_length, + format, + handle_uuid_pair); +} + +void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charReadCB(event_data_length, + attribute_value); +} + +void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWritePrepareCB(event_data_length, + attribute_handle, + offset, + part_attr_value); +} + +void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWriteExecCB(event_data_length); +} + +ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattClient launchServiceDiscovery\n\r"); + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->launchServiceDiscovery(sc, cc, matchingServiceUUID, matchingCharacteristicUUIDIn); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, matchingServiceUUID); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, startHandle, endHandle); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +bool BlueNRGGattClient::isServiceDiscoveryActive(void) const +{ + bool isSDActive = false; + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + isSDActive |= _connectionPool[i]->isServiceDiscoveryActive(); + } + } + + return isSDActive; +} + +void BlueNRGGattClient::terminateServiceDiscovery(void) +{ + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + _connectionPool[i]->terminateServiceDiscovery(); + } + } +} + +void BlueNRGGattClient::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; ++i) { + if (_connectionPool[i]) { + _connectionPool[i]->onServiceDiscoveryTermination(callback); + } + } +} + +ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->read(attributeHandle, offset); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->write(cmd, attributeHandle, length, value); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(characteristic.getConnectionHandle()); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverCharacteristicDescriptors(characteristic, discoveryCallback, terminationCallback); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattClient's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattClient::reset(void) +{ + PRINTF("BlueNRGGattClient::reset\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if(_connectionPool[i] != NULL) { + _connectionPool[i]->reset(); + + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + } + } + + return BLE_ERROR_NONE; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,816 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGattConnectionClient + * @brief BlueNRG GattConnectionClient Adaptation + * @{ + */ + +#include "BlueNRGGattConnectionClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" +#include "ble_debug.h" + +// #define PRINTF printf + +static uint8_t props_mask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 + }; + +void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code) +{ + if(error_code != BLE_STATUS_SUCCESS) { + _currentState = GATT_IDLE; + return; + } + + // Service Discovery complete +/* + if(_currentState != GATT_IDLE && + _currentState != GATT_DISCOVERY_TERMINATED && + _currentState != GATT_WRITE_CHAR && + _currentState != GATT_READ_CHAR) { +*/ + if(_currentState == GATT_SERVICE_DISCOVERY) { + findServiceChars(); + return; + } + + if(_currentState == GATT_CHAR_DESC_DISCOVERY) { + _currentState = GATT_IDLE; + if(charDescTerminationCallback != NULL) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { + _characteristic, + BLE_ERROR_NONE + }; + charDescTerminationCallback(¶ms); + } + return; + } + + // Read complete + if(_currentState == GATT_READ_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processReadResponse(&readCBParams); + free((void*)(readCBParams.data)); + readCBParams.data = NULL; + return; + } + + // Write complete + if(_currentState == GATT_WRITE_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); + return; + } +} + +void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numAttr; + + numAttr = (event_data_length - 1) / attribute_data_length; + + offset = 0; + for (i=0; i<numAttr; i++) { + startHandle = attribute_data_list[offset]; + endHandle = attribute_data_list[offset+2]; + + // UUID Type + if (attribute_data_length == 6) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4]; + PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(attribute_data_list+offset+4, UUID::LSB); + +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + + } + + PRINTF("Setup serviceIndex = %d\n\r", _numServices); + discoveredService[_numServices].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += attribute_data_length; + } + + PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr); + +} + +void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numHandlePairs; + + numHandlePairs = (event_data_length - 1) / 2; + + offset = 0; + for (i=0; i<numHandlePairs; i++) { + startHandle = handles_info_list[offset]; + endHandle = handles_info_list[offset+2]; + + PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle); + + + if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle); + uuid = _matchingServiceUUID.getShortUUID(); + } else { +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02x", longUUIDBytes[i]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB); + } + + discoveredService[i].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += 4; + } +} + +void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) +{ + // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + uint8_t i, numChar, offset; + + numChar = (event_data_length - 1) / handle_value_pair_length; + + PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar); + + offset = 0; + for (i=0; i<numChar; i++) { + // UUID Type + if (handle_value_pair_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(handle_value_pair+offset+5, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & handle_value_pair[offset+2]); + p._read = (props_mask[1] & handle_value_pair[offset+2])>>1; + p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2; + p._write = (props_mask[3] & handle_value_pair[offset+2])>>3; + p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4; + p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5; + p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = handle_value_pair[offset+2]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = handle_value_pair[offset]; + valueHandle = handle_value_pair[offset+3]; + lastHandle = valueHandle+1; + PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle); + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; + + offset += handle_value_pair_length; + } +} + +void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) +{ + // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + + PRINTF("serviceCharByUUIDCB\n\r"); + + // UUID Type + if (event_data_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = attr_value[4]<<8|attr_value[3]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(attr_value+3, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & attr_value[0]); + p._read = (props_mask[1] & attr_value[0])>>1; + p._writeWoResp = (props_mask[2] & attr_value[0])>>2; + p._write = (props_mask[3] & attr_value[0])>>3; + p._notify = (props_mask[4] & attr_value[0])>>4; + p._indicate = (props_mask[5] & attr_value[0])>>5; + p._authSignedWrite = (props_mask[6] & attr_value[0])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = attr_value[0]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = attr_handle; + valueHandle = attr_value[1]; + lastHandle = valueHandle+1; + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + // update the last handle and call the characteristic discovery callback for previous char + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; +} + +ble_error_t BlueNRGGattConnectionClient::findServiceChars(void) +{ + PRINTF("findServiceChars\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + + DiscoveredService *service; + + // complete the discovery of the last characteristic of the previous service. + // Its last handle wasn't known before this point + // update the handle and call the characteristic discovery callback. + if (_servIndex != 0 && _numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle()); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars = 0; + + // We finished chars discovery for all services + if(_servIndex >= _numServices) { + PRINTF("!!!We finished chars discovery for all services!!!\n\r"); + //_currentState = GATT_CHARS_DISCOVERY_COMPLETE; + + terminateServiceDiscovery(); + + return BLE_ERROR_NONE; + } + + service = &discoveredService[_servIndex]; + /* + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID()); + } else { + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); + } + */ + + if(serviceDiscoveryCallback) { + serviceDiscoveryCallback(service); + } + + PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex); + //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle()); + + if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) { + PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r"); + ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle()); + } else { + + uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID()); + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; +#ifdef DEBUG + PRINTF("findServiceChars C UUID-"); + for(unsigned i = 0; i < 2; i++) { + PRINTF("%02X", short_uuid[i]); + } + PRINTF("\n\r"); +#endif + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID(); +#ifdef DEBUG + PRINTF("(findServiceChars) C UUID-"); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", uuid[i]); + } + PRINTF("\r\n"); +#endif + } + + ret = aci_gatt_disc_charac_by_uuid(_connectionHandle, + service->getStartHandle(), + service->getEndHandle(), + uuid_type, + uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _servIndex++; + } + + PRINTF("findServiceChars ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + unsigned j; + + if(isServiceDiscoveryActive()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if(!sc && !cc) { + // nothing to do + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r"); + return BLE_ERROR_NONE; + } + + serviceDiscoveryCallback = sc; + characteristicDiscoveryCallback = cc; + _matchingServiceUUID = matchingServiceUUID; + _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn; + + //reset services + _numServices = 0; + _numChars = 0; + _servIndex = 0; + for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) { + discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE); + } + + if(matchingServiceUUID == BLE_UUID_UNKNOWN) { + + // Wildcard: search for all services + PRINTF("Wildcard: search for all services\r\n"); + ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle); + + } else { + PRINTF("search for specific services\r\n"); + + uint8_t type = matchingServiceUUID.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID()); +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x"); + for(j = 0; j < 2; j++) { + PRINTF("%02X", short_uuid[j]); + } + PRINTF("\n\r"); +#endif + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; + + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)matchingServiceUUID.getBaseUUID(); + +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x"); + for(j = 0; j < 16; j++) { + PRINTF("%02X", uuid[j]); + } + PRINTF("\n\r"); +#endif + } + + // search for specific service by UUID + ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_SERVICE_DISCOVERY; + } + + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)matchingServiceUUID; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)startHandle; + (void)endHandle; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const +{ + if(_currentState == GATT_SERVICE_DISCOVERY) { + return true; + } + + return false; +} + +void BlueNRGGattConnectionClient::terminateServiceDiscovery(void) +{ + _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED; + + if (terminationCallback) { + terminationCallback(_connectionHandle); + } +} + +void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value) +{ + // copy the data read, they will be forwarded to the user once the procedure + // has completed + readCBParams.connHandle = _connectionHandle; + readCBParams.offset = 0; + readCBParams.len = event_data_length; + readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length)); + memcpy((void*)(readCBParams.data), attribute_value, event_data_length); +} + +ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + /* avoid compiler warnings about unused variables */ + (void)offset; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // Save the attribute_handle not provided by evt_att_read_resp + gattc->readCBParams.handle = attributeHandle; + + ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle); + + if(ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_READ_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } +} + +void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) +{ + // Update the write response params + writeCBParams.handle = attribute_handle; + writeCBParams.offset = offset; + writeCBParams.len = event_data_length-4; //(?) + writeCBParams.data = part_attr_value; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length) +{ + /* avoid compiler warnings about unused variables */ + (void)event_data_length; + + writeCBParams.connHandle = _connectionHandle; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + /* avoid compiler warnings about unused variables */ + (void)cmd; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // We save the write response params (used by the callback) because + // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE + gattc->writeCBParams.connHandle = _connectionHandle; + gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD; + gattc->writeCBParams.handle = attributeHandle; + gattc->writeCBParams.offset = 0; + gattc->writeCBParams.len = length; + gattc->writeCBParams.data = value; + + ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); + + if (ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_WRITE_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } + +} + +void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + GattAttribute::Handle_t attHandle; + UUID uuid; + uint8_t i, numCharacDesc, offset, handle_uuid_length; + + handle_uuid_length = 4; //Handle + UUID_16 + if (format == 2) + handle_uuid_length = 18; //Handle + UUID_128 + + numCharacDesc = (event_data_length - 1) / handle_uuid_length; + + offset = 0; + + PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n", + event_data_length, format); + + + for (i=0; i<numCharacDesc; i++) { + memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle)); + + // UUID Type + if (handle_uuid_length == 4) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2]; + PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB); +#ifdef DEBUG + PRINTF("D UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + } + + if(charDescDiscoveryCallback != NULL) { + CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { + _characteristic, + DiscoveredCharacteristicDescriptor( + _characteristic.getGattClient(), + _connectionHandle, + attHandle, + uuid + ) + }; + charDescDiscoveryCallback(¶ms); + } + + _numCharDesc++; + + offset += handle_uuid_length; + } +} + +ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { + + tBleStatus ret; + + if(_currentState != GATT_IDLE) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + charDescDiscoveryCallback = discoveryCallback; + charDescTerminationCallback = terminationCallback; + + GattAttribute::Handle_t valueHandle = characteristic.getValueHandle(); + GattAttribute::Handle_t lastHandle = characteristic.getLastHandle(); + + PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle); + ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle); + + if (ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_CHAR_DESC_DISCOVERY; + _characteristic = characteristic; + return BLE_ERROR_NONE; + } + switch (ret) { + case BLE_STATUS_INVALID_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattConnectionClient::reset(void) { + PRINTF("BlueNRGGattConnectionClient::reset\n"); + + /* Clear all state, including private members */ + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + _numServices = 0; + _servIndex = 0; + _numChars = 0; + _numCharDesc = 0; + + /* Clear class members */ + memset(discoveredService, 0, sizeof(discoveredService)); + memset(discoveredChar, 0, sizeof(discoveredChar)); + + // free response if allocated + if(readCBParams.data) { + free((void*)(readCBParams.data)); + } + + return BLE_ERROR_NONE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,755 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTSERVER + * @brief BlueNRG BLE_API GattServer Adaptation + * @{ + */ + +#include "BlueNRGGattServer.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/**************************************************************************/ +/*! + @brief Adds a new service to the GATT table on the peripheral + + @params[in] service + Pointer to instance of the Gatt Server to add + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::addService(GattService &service) +{ + /* ToDo: Make sure we don't overflow the array, etc. */ + /* ToDo: Make sure this service UUID doesn't already exist (?) */ + /* ToDo: Basic validation */ + + tBleStatus ret; + uint8_t type; + uint16_t short_uuid; + uint8_t primary_short_uuid[2]; + uint8_t primary_base_uuid[16]; + uint8_t char_base_uuid[16]; + const uint8_t *base_uuid; + const uint8_t *base_char_uuid; + + uint8_t charsCount = service.getCharacteristicCount(); + const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount; + + // check that there is enough characteristics left in the + // characteristic array. + if (charsCount > available_characteristics) { + PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics); + return BLE_ERROR_NO_MEM; + } + + const uint16_t maxAttrRecords = computeAttributesRecord(service); + + type = (service.getUUID()).shortOrLong(); + PRINTF("AddService(): Type:%d\n\r", type); + + /* Add the service to the BlueNRG */ + short_uuid = (service.getUUID()).getShortUUID(); + STORE_LE_16(primary_short_uuid, short_uuid); + + if(type==UUID::UUID_TYPE_LONG) { + base_uuid = (service.getUUID()).getBaseUUID(); + + COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]); + } + + ret = BLE_STATUS_SUCCESS; + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_serv(UUID_TYPE_16, + primary_short_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_serv(UUID_TYPE_128, + primary_base_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_OUT_OF_HANDLE: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case ERR_UNSPECIFIED_ERROR: + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_ERROR: + default: + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + + + service.setHandle(servHandle); + //serviceHandleVector.push_back(servHandle); + PRINTF("added servHandle handle =%u\n\r", servHandle); + uint16_t bleCharacteristic; + + //iterate to include all characteristics + for (uint8_t i = 0; i < charsCount; i++) { + GattCharacteristic *p_char = service.getCharacteristic(i); + uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); + + uint8_t int_8_uuid[2]; + STORE_LE_16(int_8_uuid, char_uuid); + + type = (p_char->getValueAttribute().getUUID()).shortOrLong(); + + if(type==UUID::UUID_TYPE_LONG) { + base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); +#ifdef DEBUG + for(uint8_t j=0; j<16; j++) { + PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]); + } + PRINTF("\n\r"); +#endif + COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]); + } + + PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); + /* + * Gatt_Evt_Mask -> HardCoded (0) + * Encryption_Key_Size -> Hardcoded (16) + * isVariable (variable length value field) -> Hardcoded (1) + */ + uint8_t Gatt_Evt_Mask = 0x0; + + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP; + } + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; + } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_16, + int_8_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_128, + char_base_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + case BLE_STATUS_CHARAC_ALREADY_EXISTS: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); + + p_characteristics[characteristicCount++] = p_char; + /* Set the characteristic value handle */ + p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE); + PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle()); + + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + ble_error_t err = write(p_char->getValueAttribute().getHandle(), + p_char->getValueAttribute().getValuePtr(), + p_char->getValueAttribute().getLength(), false /* localOnly */); + if (err) { + PRINTF("ERROR HERE !!!!\r\n"); + return err; + } + } + + // add descriptors now + uint16_t descHandle = 0; + PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); + + for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { + GattAttribute *descriptor = p_char->getDescriptor(descIndex); + uint8_t desc_uuid[16] = { 0 }; + + + uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT; + STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID()); + + if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) { + desc_uuid_type = CHAR_DESC_TYPE_128_BIT; + const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID(); + + COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]); + } + + ret = aci_gatt_add_char_desc(service.getHandle(), + bleCharacteristic, + desc_uuid_type, + desc_uuid, + descriptor->getMaxLength(), + descriptor->getLength(), + descriptor->getValuePtr(), + CHAR_DESC_SECURITY_PERMISSION, + CHAR_DESC_ACCESS_PERMISSION, + GATT_NOTIFY_ATTRIBUTE_WRITE, + MIN_ENCRY_KEY_SIZE, + CHAR_ATTRIBUTE_LEN_IS_FIXED, + &descHandle); + PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); + + switch (ret) { + case BLE_STATUS_SUCCESS: + PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); + descriptor->setHandle(descHandle); + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_INVALID_OPERATION: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + } + + serviceCount++; + + //FIXME: There is no GattService pointer array in GattServer. + // There should be one? (Only the user is aware of GattServices!) Report to forum. + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on char handle + + @param[in] attributeHandle + The handle of the GattCharacteristic to read from + @param[in] buffer + Buffer to hold the the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes read into the buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) +{ + tBleStatus ret; + uint16_t charHandle = attributeHandle; + + ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer); + + if(ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on the connection + and char handle + + @param[in] connectionHandle + The handle of the connection + @param[in] attributeHandle + The handle of the GattCharacteristic to write to + @param[in] buffer + Data to use when updating the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes in buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + uint8_t buffer[], + uint16_t *lengthP) { + + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)attributeHandle; + (void)buffer; + (void)lengthP; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t, + const uint8_t[], + uint16_t, bool localOnly) { + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)localOnly; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly) +{ + /* avoid compiler warnings about unused variables */ + (void)localOnly; + + // check that the len of the data to write are compatible with the characteristic + GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle); + if (!characteristic) { + PRINTF("characteristic not found\r\n"); + return BLE_ERROR_INVALID_PARAM; + } + + // if the attribute handle is the attribute handle of the characteristic value then + // write the value + if (attributeHandle == characteristic->getValueHandle()) { + // assert the len in input is correct for this characteristic + const GattAttribute& value_attribute = characteristic->getValueAttribute(); + + // reject write if the lenght exceed the maximum lenght of this attribute + if (value_attribute.getMaxLength() < len) { + PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + // reject write if the attribute size is fixed and the lenght in input is different than the + // length of the attribute. + if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) { + PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + tBleStatus ret; + + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + + PRINTF("updating bleCharacteristic valueHandle=%u,\ + corresponding serviceHandle=%u len=%d\n\r", + attributeHandle, bleCharHandleMap.find(charHandle)->second, len); + + /* + * If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. + */ + ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } else { + // write this handle has a descriptor handle + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + uint16_t service_handle = bleCharHandleMap.find(charHandle)->second; + + tBleStatus ret = aci_gatt_set_desc_value( + service_handle, + charHandle, + attributeHandle, + 0, + len, + buffer + ); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } +} + +/**************************************************************************/ +/*! + @brief Reads a value according to the handle provided + + @param[in] attributeHandle + The handle of the attribute to read from + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle) +{ + uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); + + GattReadCallbackParams readParams; + readParams.handle = attributeHandle; + + //PRINTF("readParams.handle = %d\n\r", readParams.handle); + HCIDataReadEvent(&readParams); + + //EXIT: + if(gapConnectionHandle != 0){ + //PRINTF("Calling aci_gatt_allow_read\n\r"); + aci_gatt_allow_read(gapConnectionHandle); + } + + return BLE_ERROR_NONE; +} + +// ask if the write request should be accepted of rejected +// return 0 in case of success or an ATT error response in +// case of faillure +uint8_t BlueNRGGattServer::Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length, + const uint8_t* data) { + + GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle); + if(!characteristic) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF; + } + + // check if the data length is in range + if (characteristic->getValueAttribute().getMaxLength() < data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + // if the length of the characteristic value is fixed + // then the data in input should be of that length + if (characteristic->getValueAttribute().hasVariableLength() == false && + characteristic->getValueAttribute().getMaxLength() != data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + GattWriteAuthCallbackParams params = { + connection_handle, + attr_handle, + /* offset */ 0, + data_length, + data, + /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED + }; + + return characteristic->authorizeWrite(¶ms) & 0xFF; +} + +/**************************************************************************/ +/*! + @brief Returns the GattCharacteristic according to the handle provided + + @param[in] attrHandle + The handle of the attribute + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) +{ + GattCharacteristic *p_char = NULL; + int i; + uint16_t handle, handle_1; + + PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle); + for(i=0; i<characteristicCount; i++) + { + handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + PRINTF("handle(%d)=%d\n\r", i, handle); + if(i==characteristicCount-1)//Last Characteristic check + { + if(attrHandle>=handle) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); + break; + } + } + else { + handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + //Testing if attribute handle is between two Characteristic Handles + if(attrHandle>=handle && attrHandle<handle_1) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); + break; + } else continue; + } + } + + return p_char; +} + +void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { + this->handleDataWrittenEvent(params); +} + +void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { + PRINTF("Called HCIDataReadEvent\n\r"); + this->handleDataReadEvent(params); +} + +void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { + this->handleEvent(type, charHandle); +} + +void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { + this->handleDataSentEvent(count); +} + + +ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { + // <TODO> + return (ble_error_t)0; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::reset(void) +{ + PRINTF("BlueNRGGattServer::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (GattServer::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + /* Clear class members */ + memset(p_characteristics, 0, sizeof(p_characteristics)); + memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles)); + serviceCount = 0; + characteristicCount = 0; + + return BLE_ERROR_NONE; +} + + +/// compute the number of attributes needed by this service. +uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) { + uint16_t attribute_records = 1; + + for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) { + // add two attributes, one for the characteristic declaration + // and the other for the characteristic value. + attribute_records += 2; + + const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index); + const uint8_t properties = characteristic->getProperties(); + // if notify or indicate are present, two attributes are + // needed + if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) || + (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { + attribute_records += 2; + } + + // if broadcast is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) { + attribute_records += 2; + } + + // if extended properties flag is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) { + attribute_records += 2; + } + + attribute_records += characteristic->getDescriptorCount(); + } + + // for some reason, if there is just a service, this value should + // be equal to 5 + if (attribute_records == 1) { + attribute_records = 5; + } + + return attribute_records; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,421 @@ +/** + ****************************************************************************** + * @file ble_hci.c + * @author AMS/HESA Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "ble_gp_timer.h" +#include "ble_debug.h" + +#include "stm32_bluenrg_ble.h" + +#if BLE_CONFIG_DBG_ENABLE +#undef PRINTF +#endif + +#define HCI_LOG_ON 0 + +#define HCI_READ_PACKET_NUM_MAX (0x40) + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tListNode hciReadPktPool; +tListNode hciReadPktRxQueue; + +// betzw - DEBUG: +//#define POOL_CNT +#ifdef POOL_CNT +#include <stdio.h> +static unsigned int nr_hciReadPktPool; +static unsigned int lowest_nr_hciReadPktPool; +#endif // POOL_CNT + +/* pool of hci read packets */ +static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; + +static volatile uint8_t hci_timer_id; +static volatile uint8_t hci_timeout; + +void hci_timeout_callback(void) +{ + hci_timeout = 1; + return; +} + +void HCI_Init(void) +{ + uint8_t index; + +#ifdef POOL_CNT + nr_hciReadPktPool = 0; +#endif // POOL_CNT + + /* Initialize list heads of ready and free hci data packet queues */ + list_init_head (&hciReadPktPool); + list_init_head (&hciReadPktRxQueue); + + /* Initialize the queue of free hci data packets */ + for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) + { + list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif // POOL_CNT + } + +#ifdef POOL_CNT + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif // POOL_CNT +} + +#define HCI_PCK_TYPE_OFFSET 0 +#define EVENT_PARAMETER_TOT_LEN_OFFSET 2 + +/** + * Verify if HCI packet is correctly formatted. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * @return 0 if HCI packet is as expected + */ +int HCI_verify(const tHciDataPacket * hciReadPacket) +{ + const uint8_t *hci_pckt = hciReadPacket->dataBuff; + + if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) + return 1; /* Incorrect type. */ + + if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) + return 2; /* Wrong length (packet truncated or too long). */ + + return 0; +} + +void HCI_Process(void) +{ + tHciDataPacket * hciReadPacket = NULL; + +#ifdef POOL_CNT + printf("betzw(%s, %d): nr_hciReadPktPool = %u (lowest = %u)\r\n", __func__, __LINE__, + nr_hciReadPktPool, lowest_nr_hciReadPktPool); +#endif // POOL_CNT + + Disable_SPI_IRQ(); + uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); + /* process any pending events read */ + while(list_empty == FALSE) + { + list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + Enable_SPI_IRQ(); + HCI_Event_CB(hciReadPacket->dataBuff); + Disable_SPI_IRQ(); + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + list_empty = list_is_empty(&hciReadPktRxQueue); + } + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG. */ + HCI_HandleSPI(); + Enable_SPI_IRQ(); +} + +BOOL HCI_Queue_Empty(void) +{ + return list_is_empty(&hciReadPktRxQueue); +} + +/** + * When an interrupt is raised by BlueNRG, + * just signal that a new event (availability of SPI data to be read) + * needs to be processed. + */ +void HCI_Isr(void) +{ + signalEventsToProcess(); +} + +/** + * Now, SPI Data are handled in user space. + * In case it has to be called in ISR, take care to + * call Disable_SPI_IRQ/Enable_SPI_IRQ in a proper way. + * The calls Disable_SPI_IRQ/Enable_SPI_IRQ have not been removed + * from this code for backward compatibility. + */ +void HCI_HandleSPI(void) +{ + tHciDataPacket * hciReadPacket = NULL; + uint8_t data_len; + + Clear_SPI_EXTI_Flag(); + while(BlueNRG_DataPresent()){ + if (list_is_empty (&hciReadPktPool) == FALSE){ + + /* enqueueing a packet for read */ + list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool--; + if(nr_hciReadPktPool < lowest_nr_hciReadPktPool) + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif + + data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); + if(data_len > 0){ + hciReadPacket->data_len = data_len; + if(HCI_verify(hciReadPacket) == 0) { + list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); + } else { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else { + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else{ + // HCI Read Packet Pool is empty, wait for a free packet. + Clear_SPI_EXTI_Flag(); + return; + } + + Clear_SPI_EXTI_Flag(); + } +} + +void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){ +#if HCI_LOG_ON + PRINTF("HCI <- "); + for(int i=0; i < n_bytes1; i++) + PRINTF("%02X ", *((uint8_t*)data1 + i)); + for(int i=0; i < n_bytes2; i++) + PRINTF("%02X ", *((uint8_t*)data2 + i)); + PRINTF("\n"); +#endif + + Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); +} + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) +{ + hci_command_hdr hc; + + hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); + hc.plen= plen; + + uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; + header[0] = HCI_COMMAND_PKT; + Osal_MemCpy(header+1, &hc, sizeof(hc)); + + hci_write(header, param, sizeof(header), plen); +} + +static void move_list(tListNode * dest_list, tListNode * src_list) +{ + pListNode tmp_node; + + while(!list_is_empty(src_list)){ + list_remove_tail(src_list, &tmp_node); + list_insert_head(dest_list, tmp_node); + } +} + + /* It ensures that we have at least half of the free buffers in the pool. */ +static void free_event_list(void) +{ + tHciDataPacket * pckt; + + Disable_SPI_IRQ(); + + while(list_get_size(&hciReadPktPool) < HCI_READ_PACKET_NUM_MAX/2){ + list_remove_head(&hciReadPktRxQueue, (tListNode **)&pckt); + list_insert_tail(&hciReadPktPool, (tListNode *)pckt); + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG */ + HCI_HandleSPI(); + } + + Enable_SPI_IRQ(); +} + +int hci_send_req(struct hci_request *r, BOOL async) +{ + uint8_t *ptr; + uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + hci_event_pckt *event_pckt; + hci_uart_pckt *hci_hdr; + int to = DEFAULT_TIMEOUT; + struct timer t; + tHciDataPacket * hciReadPacket = NULL; + tListNode hciTempQueue; + + list_init_head(&hciTempQueue); + + free_event_list(); + + hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); + + if(async){ + return 0; + } + + /* Minimum timeout is 1. */ + if(to == 0) + to = 1; + + Timer_Set(&t, to); + + while(1) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + evt_le_meta_event *me; + int len; + + while(1){ + + Disable_SPI_IRQ(); + HCI_HandleSPI(); + Enable_SPI_IRQ(); + + if(Timer_Expired(&t)){ + goto failed; + } + if(!HCI_Queue_Empty()){ + break; + } + } + + /* Extract packet from HCI event queue. */ + Disable_SPI_IRQ(); + list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + + hci_hdr = (void *)hciReadPacket->dataBuff; + + if(hci_hdr->type == HCI_EVENT_PKT){ + + event_pckt = (void *) (hci_hdr->data); + + ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); + len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); + + switch (event_pckt->evt) { + + case EVT_CMD_STATUS: + cs = (void *) ptr; + + if (cs->opcode != opcode) + goto failed; + + if (r->event != EVT_CMD_STATUS) { + if (cs->status) { + goto failed; + } + break; + } + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_CMD_COMPLETE: + cc = (void *) ptr; + + if (cc->opcode != opcode) + goto failed; + + ptr += EVT_CMD_COMPLETE_SIZE; + len -= EVT_CMD_COMPLETE_SIZE; + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_LE_META_EVENT: + me = (void *) ptr; + + if (me->subevent != r->event) + break; + + len -= 1; + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, me->data, r->rlen); + goto done; + + case EVT_HARDWARE_ERROR: + goto failed; + + default: + break; + } + } + + /* If there are no more packets to be processed, be sure there is at list one + packet in the pool to process the expected event. + If no free packets are available, discard the processed event and insert it + into the pool. */ + if(list_is_empty(&hciReadPktPool) && list_is_empty(&hciReadPktRxQueue)){ + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); + hciReadPacket=NULL; + } + else { + /* Insert the packet in a different queue. These packets will be + inserted back in the main queue just before exiting from send_req(), so that + these events can be processed by the application. + */ + list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); + hciReadPacket = NULL; + } + + HCI_HandleSPI(); + + Enable_SPI_IRQ(); + + } + +failed: + if(hciReadPacket != NULL) { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + move_list(&hciReadPktRxQueue, &hciTempQueue); + Enable_SPI_IRQ(); + return -1; + +done: + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + move_list(&hciReadPktRxQueue, &hciTempQueue); + + Enable_SPI_IRQ(); + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,837 @@ +/** + ****************************************************************************** + * @file ble_hci_le.c + * @author AMG RF Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +int hci_reset(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_RESET; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_disconnect(uint16_t handle, uint8_t reason) +{ + struct hci_request rq; + disconnect_cp cp; + uint8_t status; + + cp.handle = handle; + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) +{ + struct hci_request rq; + read_local_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + + *hci_version = resp.hci_version; + *hci_revision = btohs(resp.hci_revision); + *lmp_pal_version = resp.lmp_pal_version; + *manufacturer_name = btohs(resp.manufacturer_name); + *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); + + return 0; +} + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) +{ + struct hci_request rq; + le_read_buffer_size_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_BUFFER_SIZE; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *pkt_len = resp.pkt_len; + *max_pkt = resp.max_pkt; + + return 0; +} + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter) +{ + struct hci_request rq; + le_set_adv_parameters_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.min_interval = min_interval; + adv_cp.max_interval = max_interval; + adv_cp.advtype = advtype; + adv_cp.own_bdaddr_type = own_bdaddr_type; + adv_cp.direct_bdaddr_type = direct_bdaddr_type; + if(direct_bdaddr != NULL) + Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); + adv_cp.chan_map = chan_map; + adv_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_PARAMETERS; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_adv_data_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.length = length; + Osal_MemCpy(adv_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_DATA; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertise_enable(uint8_t enable) +{ + struct hci_request rq; + le_set_advertise_enable_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.enable = enable?1:0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter) +{ + struct hci_request rq; + le_set_scan_parameters_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.type = type; + scan_cp.interval = interval; + scan_cp.window = window; + scan_cp.own_bdaddr_type = own_bdaddr_type; + scan_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) +{ + struct hci_request rq; + le_set_scan_enable_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.enable = enable?1:0; + scan_cp.filter_dup = filter_dup; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_ENABLE; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_rand(uint8_t random_number[8]) +{ + struct hci_request rq; + le_rand_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_RAND; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + Osal_MemCpy(random_number, resp.random, 8); + + return 0; +} + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_scan_response_data_cp scan_resp_cp; + uint8_t status; + + Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); + scan_resp_cp.length = length; + Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; + rq.cparam = &scan_resp_cp; + rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) +{ + struct hci_request rq; + le_read_adv_channel_tx_power_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *tx_power_level = resp.level; + + return 0; +} + +int hci_le_set_random_address(tBDAddr bdaddr) +{ + struct hci_request rq; + le_set_random_address_cp set_rand_addr_cp; + uint8_t status; + + Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); + Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; + rq.cparam = &set_rand_addr_cp; + rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_read_bd_addr(tBDAddr bdaddr) +{ + struct hci_request rq; + read_bd_addr_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_BD_ADDR; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_BD_ADDR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); + + return 0; +} + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) +{ + struct hci_request rq; + le_create_connection_cp create_cp; + uint8_t status; + + Osal_MemSet(&create_cp, 0, sizeof(create_cp)); + create_cp.interval = interval; + create_cp.window = window; + create_cp.initiator_filter = initiator_filter; + create_cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); + create_cp.own_bdaddr_type = own_bdaddr_type; + create_cp.min_interval=min_interval; + create_cp.max_interval=max_interval; + create_cp.latency = latency; + create_cp.supervision_timeout=supervision_timeout; + create_cp.min_ce_length=min_ce_length; + create_cp.max_ce_length=max_ce_length; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN; + rq.cparam = &create_cp; + rq.clen = LE_CREATE_CONN_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_create_connection_cancel(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN_CANCEL; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) +{ + struct hci_request rq; + le_encrypt_cp params; + le_encrypt_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemCpy(params.key, key, 16); + Osal_MemCpy(params.plaintext, plaintextData, 16); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ENCRYPT; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + le_ltk_neg_reply_cp params; + le_ltk_neg_reply_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + params.handle = 1; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_LTK_NEG_REPLY; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CLEAR_WHITE_LIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0){ + return BLE_STATUS_TIMEOUT; + } + + return status; +} + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) +{ + struct hci_request rq; + le_add_device_to_white_list_cp params; + uint8_t status; + + params.bdaddr_type = bdaddr_type; + Osal_MemCpy(params.bdaddr, bdaddr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; + rq.cparam = ¶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/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1309 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB05A1 cp; + gap_init_rp resp; + + cp.role = role; + cp.privacy_enabled = privacy_enabled; + cp.device_name_char_len = device_name_char_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} +tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB04A1 cp; + gap_init_rp resp; + + cp.role = role; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + SlaveConnIntervMin = htobs(SlaveConnIntervMin); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + SlaveConnIntervMax = htobs(SlaveConnIntervMax); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB05A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.directed_adv_type = directed_adv_type; + cp.adv_interv_min = adv_interv_min; + cp.adv_interv_max = adv_interv_max; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB04A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_io_capability(uint8_t io_capability) +{ + struct hci_request rq; + uint8_t status; + gap_set_io_capability_cp cp; + + cp.io_capability = io_capability; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_IO_CAPABILITY; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode) +{ + struct hci_request rq; + gap_set_auth_requirement_cp cp; + uint8_t status; + + cp.mitm_mode = mitm_mode; + cp.oob_enable = oob_enable; + Osal_MemCpy(cp.oob_data, oob_data, 16); + cp.min_encryption_key_size = min_encryption_key_size; + cp.max_encryption_key_size = max_encryption_key_size; + cp.use_fixed_pin = use_fixed_pin; + cp.fixed_pin = htobl(fixed_pin); + cp.bonding_mode = bonding_mode; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) +{ + struct hci_request rq; + gap_set_author_requirement_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorization_enable = authorization_enable; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) +{ + struct hci_request rq; + gap_passkey_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.passkey = htobl(passkey); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_PASSKEY_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) +{ + struct hci_request rq; + gap_authorization_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorize = authorize; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB05A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + cp.own_address_type = own_address_type; + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB04A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) +{ + struct hci_request rq; + gap_set_undirected_connectable_cp cp; + uint8_t status; + + cp.own_addr_type = own_addr_type; + cp.adv_filter_policy = adv_filter_policy; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) +{ + struct hci_request rq; + gap_slave_security_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.bonding = bonding; + cp.mitm_protection = mitm_protection; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[32]; + uint8_t indx = 0; + + if (AdvLen > (sizeof(buffer)-1)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvLen; + indx++; + + Osal_MemCpy(buffer + indx, AdvData, AdvLen); + indx += AdvLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_UPDATE_ADV_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) +{ + struct hci_request rq; + gap_delete_ad_type_cp cp; + uint8_t status; + + cp.ad_type = ad_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_DELETE_AD_TYPE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required) +{ + struct hci_request rq; + gap_get_security_level_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; + rq.rparam = &resp; + rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *mitm_protection = resp.mitm_protection; + *bonding = resp.bonding; + *oob_data = resp.oob_data; + *passkey_required = resp.passkey_required; + + return resp.status; +} + +tBleStatus aci_gap_configure_whitelist(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) +{ + struct hci_request rq; + gap_terminate_cp cp; + uint8_t status; + + cp.handle = htobs(conn_handle); + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_clear_security_database(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) +{ + struct hci_request rq; + gap_allow_rebond_cp_IDB05A1 cp; + uint8_t status; + + cp.conn_handle = conn_handle; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_allow_rebond_IDB04A1(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_limited_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_general_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_name_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = use_reconn_addr; + indx++; + + Osal_MemCpy(buffer + indx, reconn_addr, 6); + indx += 6; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB05A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB04A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.use_reconn_addr = use_reconn_addr; + Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_start_selective_conn_establish_proc_cp cp; + uint8_t status; + + if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.num_whitelist_entries = num_whitelist_entries; + + Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_create_connection_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CREATE_CONNECTION; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; + rq.cparam = &procedure_code; + rq.clen = 1; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_connection_update_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) +{ + struct hci_request rq; + gap_send_pairing_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.force_rebond = force_rebond; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + gap_resolve_private_address_rp rp; + + Osal_MemCpy(cp.address, private_address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); + + return 0; +} +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + uint8_t status; + + Osal_MemCpy(cp.address, address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_set_broadcast_mode_cp cp; + uint8_t status; + uint8_t indx = 0; + uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; + + if (variable_size > sizeof(cp.var_len_data) ) + return BLE_STATUS_INVALID_PARAMS; + + cp.adv_interv_min = htobs(adv_interv_min); + cp.adv_interv_max = htobs(adv_interv_max); + cp.adv_type = adv_type; + cp.own_addr_type = own_addr_type; + + cp.var_len_data[indx] = adv_data_length; + indx++; + Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); + indx += adv_data_length; + cp.var_len_data[indx] = num_whitelist_entries; + indx ++; + Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_BROADCAST_MODE; + rq.cparam = &cp; + rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_observation_proc_cp cp; + uint8_t status; + + cp.scan_interval = scan_interval; + cp.scan_window = scan_window; + cp.scan_type = scan_type; + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_OBSERVATION_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) +{ + struct hci_request rq; + gap_is_device_bonded_cp cp; + uint8_t status; + + cp.peer_address_type = peer_address_type; + Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_IS_DEVICE_BONDED; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) +{ + struct hci_request rq; + gap_get_bonded_devices_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_BONDED_DEVICES; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (rp.status) { + return rp.status; + } + + *num_devices = rp.num_addr; + if(device_list != NULL) + Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1505 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.c +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : File with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_gatt_init(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INIT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[19]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, service_uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = service_type; + indx++; + + buffer[indx] = max_attr_records; + indx++; + + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle) +{ + struct hci_request rq; + gatt_include_serv_rp resp; + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + service_handle = htobs(service_handle); + Osal_MemCpy(buffer, &service_handle, 2); + indx += 2; + + included_start_handle = htobs(included_start_handle); + Osal_MemCpy(buffer+indx, &included_start_handle, 2); + indx += 2; + + included_end_handle = htobs(included_end_handle); + Osal_MemCpy(buffer+indx, &included_end_handle, 2); + indx += 2; + + if(included_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } else { + uuid_len = 16; + } + + buffer[indx] = included_uuid_type; + indx++; + + Osal_MemCpy(buffer + indx, included_uuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INCLUDE_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *included_handle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[25]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + buffer[indx] = charValueLen; + indx++; + + buffer[indx] = charProperties; + indx++; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *charHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle) +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = descValueMaxLen; + indx++; + + buffer[indx] = descValueLen; + indx++; + + if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + Osal_MemCpy(buffer + indx, descValue, descValueLen); + indx += descValueLen; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = accPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR_DESC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *descHandle = btohs(resp.handle); + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = charValOffset; + indx++; + + buffer[indx] = charValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charValue, charValueLen); + indx += charValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_char_cp cp; + + cp.service_handle = htobs(servHandle); + cp.char_handle = htobs(charHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_CHAR; + rq.cparam = &cp; + rq.clen = GATT_DEL_CHAR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_service(uint16_t servHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_serv_cp cp; + + cp.service_handle = htobs(servHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_inc_serv_cp cp; + + cp.service_handle = htobs(servHandle); + cp.inc_serv_handle = htobs(includeServHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_INC_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_INC_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) +{ + struct hci_request rq; + uint8_t status; + gatt_set_evt_mask_cp cp; + + cp.evt_mask = htobs(event_mask); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_EVT_MASK; + rq.cparam = &cp; + rq.clen = GATT_SET_EVT_MASK_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_exchange_config_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_EXCHANGE_CONFIG; + rq.cparam = &cp; + rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) +{ + struct hci_request rq; + uint8_t status; + att_find_info_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_INFO_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_find_by_type_value_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + Osal_MemCpy(cp.uuid, uuid, 2); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_group_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_prepare_write_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.value_offset = htobs(value_offset); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) +{ + struct hci_request rq; + uint8_t status; + att_execute_write_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.execute = execute; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_prim_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_prim_service_by_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; + rq.cparam = &cp; + rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, + uint16_t end_service_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_find_included_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_service_handle); + cp.end_handle = htobs(end_service_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_of_serv_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_attr_handle = htobs(start_attr_handle); + cp.end_attr_handle = htobs(end_attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t charUuidType, + const uint8_t* charUuid) +{ + struct hci_request rq; + uint8_t status; + + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + start_handle = htobs(start_handle); + Osal_MemCpy(buffer + indx, &start_handle, 2); + indx += 2; + + end_handle = htobs(end_handle); + Osal_MemCpy(buffer + indx, &end_handle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == 0x01){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_descriptors_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.char_val_handle = htobs(char_val_handle); + cp.char_end_handle = htobs(char_end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_read_using_charac_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; + rq.cparam = &cp; + rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles) +{ + struct hci_request rq; + uint8_t status; + gatt_read_multiple_charac_val_cp cp; + + if(num_handles*2 > sizeof(cp.set_of_handles)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.num_handles = htobs(num_handles); + Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_long_charac_val_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; + rq.cparam = &cp; + rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_signed_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_confirm_indication_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_CONFIRM_INDICATION; + rq.cparam = &cp; + rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = write_status; + indx += 1; + + buffer[indx] = err_code; + indx += 1; + + buffer[indx] = att_val_len; + indx += 1; + + Osal_MemCpy(buffer + indx, att_val, att_val_len); + indx += att_val_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(uint16_t conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ALLOW_READ; + rq.cparam = &cp; + rq.clen = GATT_ALLOW_READ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission) +{ + struct hci_request rq; + gatt_set_security_permission_cp cp; + uint8_t status; + + cp.service_handle = htobs(service_handle); + cp.attr_handle = htobs(attr_handle); + cp.security_permission = security_permission; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; + rq.cparam = &cp; + rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + charDescHandle = htobs(charDescHandle); + Osal_MemCpy(buffer + indx, &charDescHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charDescValOffset, 2); + indx += 2; + + buffer[indx] = charDescValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); + indx += charDescValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_DESC_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_cp cp; + gatt_read_handle_val_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = btohs(rp.value_len); + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_offset_cp cp; + gatt_read_handle_val_offset_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rp.value_len; + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value) +{ + struct hci_request rq; + uint8_t status; + gatt_upd_char_val_ext_cp cp; + + if(value_length > sizeof(cp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.service_handle = htobs(service_handle); + cp.char_handle = htobs(char_handle); + cp.update_type = update_type; + cp.char_length = htobs(char_length); + cp.value_offset = htobs(value_offset); + cp.value_length = value_length; + Osal_MemCpy(cp.value, value, value_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL_EXT; + rq.cparam = &cp; + rq.clen = GATT_UPD_CHAR_VAL_EXT_CP_SIZE + value_length; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,266 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number) +{ + struct hci_request rq; + hal_get_fw_build_number_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_FW_BUILD_NUMBER; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *build_number = rp.build_number; + + return 0; +} + +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((len+2) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = offset; + indx++; + + buffer[indx] = len; + indx++; + + Osal_MemCpy(buffer + indx, val, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + hal_read_config_data_cp cp; + hal_read_config_data_rp rp; + + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_READ_CONFIG_DATA; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rq.rlen-1; + + Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) +{ + struct hci_request rq; + hal_set_tx_power_level_cp cp; + uint8_t status; + + cp.en_high_power = en_high_power; + cp.pa_level = pa_level; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets) +{ + struct hci_request rq; + hal_le_tx_test_packet_number_rp resp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_LE_TX_TEST_PACKET_NUMBER; + rq.rparam = &resp; + rq.rlen = sizeof(resp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *number_of_packets = btohl(resp.number_of_packets); + + return 0; +} + +tBleStatus aci_hal_device_standby(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_DEVICE_STANDBY; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_start(uint8_t rf_channel) +{ + struct hci_request rq; + hal_tone_start_cp cp; + uint8_t status; + + cp.rf_channel = rf_channel; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_START; + rq.cparam = &cp; + rq.clen = HAL_TONE_START_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_stop(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_STOP; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]) +{ + struct hci_request rq; + hal_get_link_status_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_LINK_STATUS; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(link_status,rp.link_status,sizeof(link_status)); + for(int i = 0; i < 8; i++) + conn_handle[i] = btohs(rp.conn_handle[i]); + + return 0; +} + +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot) +{ + struct hci_request rq; + hal_get_anchor_period_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_ANCHOR_PERIOD; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *anchor_period = btohl(rp.anchor_period); + *max_free_slot = btohl(rp.max_free_slot); + + return 0; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,117 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB05A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.min_ce_length = htobs(min_ce_length); + cp.max_ce_length = htobs(max_ce_length); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB04A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,269 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_updater_aci.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_updater_reboot(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_get_updater_version(uint8_t *version) +{ + struct hci_request rq; + get_updater_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_VERSION; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) +{ + struct hci_request rq; + get_updater_bufsize_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_BUFSIZE; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_reset_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = htobl(address); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_SECTOR; + rq.cparam = &cp; + rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_program_data_block(uint32_t address, + uint16_t len, + const uint8_t *data) +{ + struct hci_request rq; + uint8_t status; + updater_prog_data_block_cp cp; + + if( len > sizeof(cp.data)) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(len); + Osal_MemCpy(cp.data, data, len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_read_data_block(uint32_t address, + uint16_t data_len, + uint8_t *data) +{ + struct hci_request rq; + updater_read_data_block_cp cp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + + if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(data_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; + rq.rparam = buffer; + rq.rlen = data_len + 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + // First byte is status + Osal_MemCpy(data, buffer+1, data_len); + + return buffer[0]; +} + +tBleStatus aci_updater_calc_crc(uint32_t address, + uint8_t num_sectors, + uint32_t *crc) +{ + struct hci_request rq; + updater_calc_crc_cp cp; + updater_calc_crc_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + cp.address = htobl(address); + cp.num_sectors = num_sectors; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_CALC_CRC; + rq.cparam = &cp; + rq.clen = UPDATER_CALC_CRC_CP_SIZE; + rq.rparam = &resp; + rq.rlen = UPDATER_CALC_CRC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *crc = btohl(resp.crc); + + return resp.status; +} + +tBleStatus aci_updater_hw_version(uint8_t *version) +{ + struct hci_request rq; + updater_hw_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_HW_VERSION; + rq.rparam = &resp; + rq.rlen = UPDATER_HW_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,423 @@ + +#include "ble_hal.h" +#include "ble_hal_types.h" +#include "ble_status.h" +#include "bluenrg_aci.h" +#include "bluenrg_utils.h" +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "ble_osal.h" +#include "string.h" +#include "stm32_bluenrg_ble.h" + +#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 +#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 + +#define BASE_ADDRESS 0x10010000 + +#define FW_OFFSET (2*1024) // 2 KB +#define FW_OFFSET_MS 0 +#define FULL_STACK_SIZE (66*1024) // 66 KB +#define BOOTLOADER_SIZE (2*1024) // 2 kB +#define SECTOR_SIZE (2*1024) // 2 KB + +// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + +// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 +#define CRC_POLY 0x04C11DB7 // the poly without the x**32 + +#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC + +#define IFR_SIZE 192 +#define IFR_BASE_ADDRESS 0x10020000 +#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data + +#if BLUENRG_MS +#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET +#else +#define IFR_WRITE_OFFSET_BEGIN 0 +#endif + + +#define BLUE_FLAG_OFFSET 0x8C0 +#define MAX_ERASE_RETRIES 2 +#define MAX_WRITE_RETRIES 2 +#define MIN_WRITE_BLOCK_SIZE 4 +#define MAX_WRITE_BLOCK_SIZE 64 // 64 bytes +#define READ_BLOCK_SIZE 64 // 64 bytes + +#define RETRY_COMMAND(func, num_ret, error) \ +{ \ + uint8_t num_retries; \ + num_retries = 0; \ + error = 0; \ + while (num_retries++ < num_ret) { \ + if (func == BLE_STATUS_SUCCESS) \ + break; \ + if (num_retries == num_ret) \ + error = BLE_UTIL_ACI_ERROR; \ + } \ +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, + they are extended with 0xFF until sector size is reached +*/ +static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) +{ + uint32_t i, j, a1; + uint32_t crc, value; + + crc = 0; + for (i = 0; i < SECTOR_SIZE; i += 4) { + uint8_t *dataw = (uint8_t *) &value; + + dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; + dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; + dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; + dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; + + crc = crc ^ value; + for (j = 0; j < 32; j ++) { + a1 = (crc >> 31) & 0x1; + crc = (crc << 1) ^ (a1 * CRC_POLY); + } + } + + return crc; +} + +int program_device(const uint8_t *fw_image, uint32_t fw_size) +{ + uint8_t version, num_erase_retries, status, write_block_size; + uint32_t address; + uint32_t crc, crc2, crc_size; + uint32_t fw_offset = FW_OFFSET; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + if(aci_updater_hw_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version==0x31){ + // It does not contain bootloader inside first sector. It may contain code. + fw_offset = FW_OFFSET_MS; + } + + if (fw_size != FULL_STACK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + if (fw_size % MIN_WRITE_BLOCK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + + /*********************************************************************** + * Erase BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + /*********************************************************************** + * Erase and Program sectors + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE) { + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(BASE_ADDRESS + i); + for (int j=i; ((j<i+SECTOR_SIZE)&&(j<fw_size)); j += write_block_size) { + + write_block_size = MIN(fw_size-j, MAX_WRITE_BLOCK_SIZE); + + RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, write_block_size, fw_image+j), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + break; + } + if (status == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + } + + /*********************************************************************** + * Verify firmware + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE){ + address = BASE_ADDRESS + i; + if(aci_updater_calc_crc(address, 1, &crc)) + return BLE_UTIL_ACI_ERROR; + + crc_size = MIN(fw_size-i,SECTOR_SIZE); + + crc2 = updater_calc_crc(fw_image+i,crc_size); + if(crc!=crc2) + return BLE_UTIL_CRC_ERROR; + } + + /*********************************************************************** + * Write BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +int read_IFR(uint8_t *data) +{ + uint8_t version, offset; + tBleStatus ret; + + offset = 0; + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + /*********************************************************************** + * Reading last 3 IFR 64-byte blocks + ************************************************************************/ + for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(BASE_ADDRESS+i, READ_BLOCK_SIZE, (data+offset)); + offset += READ_BLOCK_SIZE; + if(ret) return BLE_UTIL_ACI_ERROR; + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; + +} + +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) +{ + IFR_config->stack_mode = data[0]; + IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); + IFR_config->master_sca = data[30]; + IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); + IFR_config->year = BCD_TO_INT(data[41]); + IFR_config->month = BCD_TO_INT(data[42]); + IFR_config->day = BCD_TO_INT(data[43]); +} + +int IFR_validate(IFR_config2_TypeDef *IFR_config) +{ +#if BLUENRG_MS + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) +#else + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) +#endif + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode + if(IFR_config->master_sca > 7) + return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->day > 31 || IFR_config->day < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + + return BLE_STATUS_SUCCESS; +} + +/* TODO: Function to generate data from given options. */ + +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) +{ + data[0] = IFR_config->stack_mode; + HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); + data[30] = IFR_config->master_sca; + HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); + data[41] = INT_TO_BCD(IFR_config->year); + data[42] = INT_TO_BCD(IFR_config->month); + data[43] = INT_TO_BCD(IFR_config->day); +} + + +int program_IFR(const IFR_config_TypeDef *ifr_image) +{ + uint8_t version, num_erase_retries; + tBleStatus ret; +#if BLUENRG_MS + const uint8_t *ifr_data = (uint8_t *)ifr_image; +#else + uint8_t ifr_data[SECTOR_SIZE]; +#endif + uint8_t hwVersion; + uint16_t fwVersion; + + if(getBlueNRGVersion(&hwVersion, &fwVersion)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + +#ifndef BLUENRG_MS + /*********************************************************************** + * READ IFR data + ************************************************************************/ + for(int i = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_data+i); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + } +#endif + + /*********************************************************************** + * Erase & Flashing IFR sectors + ************************************************************************/ +#ifndef BLUENRG_MS + Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); +#endif + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(IFR_BASE_ADDRESS); + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += MAX_WRITE_BLOCK_SIZE, j += MAX_WRITE_BLOCK_SIZE) { + RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, MAX_WRITE_BLOCK_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); + if (ret != BLE_STATUS_SUCCESS) + break; + } + if (ret == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + + /*********************************************************************** + * Verify IFR + ************************************************************************/ + { + uint8_t ifr_updated[READ_BLOCK_SIZE]; + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE, j += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ifr_data+j, READ_BLOCK_SIZE) != 0) + return BLE_UTIL_WRONG_VERIFY; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) +{ + uint8_t ifr_updated[READ_BLOCK_SIZE]; + uint8_t version, ret = BLE_STATUS_SUCCESS; + + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + for(int i = 0; i < IFR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, READ_BLOCK_SIZE) != 0) + { + ret = BLE_UTIL_WRONG_VERIFY; + break; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return ret; +} + +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) +{ + uint8_t status; + uint8_t hci_version, lmp_pal_version; + uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; + + status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, + &manufacturer_name, &lmp_pal_subversion); + + if (status == BLE_STATUS_SUCCESS) { + *hwVersion = hci_revision >> 8; + *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number + *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number + *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number + } + + return status; +} + +uint8_t getBlueNRGUpdaterVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(version)) + return BLE_UTIL_ACI_ERROR; + + if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_updater_hw_version(version)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t isHWBootloader_Patched(void) +{ + uint8_t status, version; + uint32_t crc, address = 0x10010000; + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); + if (status != BLE_STATUS_SUCCESS) + return 0; + + if (crc == BOOTLOADER_CRC_NOT_PATCHED) + return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +#include "ble_gp_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function sets a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * @param[in] t A pointer to the timer + * @param[in] interval The interval before the timer expires. + * + */ +void +Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +Timer_Expired(struct timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + tClockTime diff = (Clock_Time() - t->start) + 1; + return t->interval < diff; + +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +tClockTime +Timer_Remaining(struct timer *t) +{ + return t->start + t->interval - Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +#ifdef __DMA_LP__ + +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID) +{ + TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, + (pf_TIMER_TimerCallBack_t) timercb); + TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); + + return (BLE_STATUS_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) +{ + TIMER_Delete(timerID); + + return (BLE_STATUS_SUCCESS); +} + +#endif /* __DMA_LP__ */ +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,119 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Circular Linked List Implementation. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/****************************************************************************** + * Include Files +******************************************************************************/ +#include <ble_hal_types.h> +#include "ble_list.h" + +/****************************************************************************** + * Function Definitions +******************************************************************************/ +void list_init_head (tListNode * listHead) +{ + listHead->next = listHead; + listHead->prev = listHead; +} + +uint8_t list_is_empty (tListNode * listHead) +{ + return ((listHead->next == listHead)? TRUE:FALSE); +} + +void list_insert_head (tListNode * listHead, tListNode * node) +{ + node->next = listHead->next; + node->prev = listHead; + listHead->next = node; + (node->next)->prev = node; +} + + +void list_insert_tail (tListNode * listHead, tListNode * node) +{ + node->next = listHead; + node->prev = listHead->prev; + listHead->prev = node; + (node->prev)->next = node; +} + + +void list_remove_node (tListNode * node) +{ + (node->prev)->next = node->next; + (node->next)->prev = node->prev; +} + + +void list_remove_head (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->next; + list_remove_node (listHead->next); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_remove_tail (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->prev; + list_remove_node (listHead->prev); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_insert_node_after (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node->next; + node->prev = ref_node; + ref_node->next = node; + (node->next)->prev = node; +} + + +void list_insert_node_before (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node; + node->prev = ref_node->prev; + ref_node->prev = node; + (node->prev)->next = node; +} + + +int list_get_size (tListNode * listHead) +{ + int size = 0; + tListNode * temp = listHead->next; + while (temp != listHead) + { + size++; + temp = temp->next; + } + return (size); +} + +void list_get_next_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->next; +} + + +void list_get_prev_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->prev; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,72 @@ +/** +****************************************************************************** +* @file ble_osal.c +* @author AMS - HEA&RF BU / CL +* @version V1.0.0 +* @date 04-July-2014 +* @brief Implementation of OS abstraction layer functions used by the +* library. +****************************************************************************** +* @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> +#include <ble_osal.h> + + /** + * @brief Osal_MemCpy + * @param dest: Pointer to the destination buffer + * @param src : Pointer to the source buffer + * @param size: Number of bytes to copy from the source to the destination + * buffer + * @retval Pointer to the destination buffer + */ +void* Osal_MemCpy(void *dest, const void *src, unsigned int size) +{ + return(memcpy(dest,src,size)); +} + +/** + * @brief Osal_MemSet + * @param ptr : Pointer to block of memory to fill + * @param value: Value to assign to each byte of the memory block + * @param size : Number of bytes to be set to "value" + * @retval Pointer to the filled block of memory + */ +void* Osal_MemSet(void *ptr, int value, unsigned int size) +{ + return(memset(ptr,value,size)); +} + +/****************************************************************************** + * local Functions + *****************************************************************************/ + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ + +#include "ble_clock.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/wait_api.h" + #include "mbed-drivers/rtc_time.h" +#else + #include "wait_api.h" + #include "rtc_time.h" +#endif + +const uint32_t CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + //Not Used +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return clock(); +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,715 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file btle.cpp + * @author STMicroelectronics + * @brief Implementation BlueNRG Init and helper functions. + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + + +#include "btle.h" +#include "ble/Gap.h" +#include "ble/GapEvents.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" + +#include "bluenrg_targets.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* C File Includes ------------------------------------------------------------------*/ +#include <stdio.h> +#include <string.h> +#include "ble_hci.h" +#include "ble_hci_const.h" +#include "bluenrg_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" +#include "bluenrg_utils.h" + +#include "ble_hal_types.h" +#include "ble_hal.h" +#include "ble_gp_timer.h" +#include "ble_osal.h" +#include "ble_sm.h" +#include "ble_debug.h" + +#ifdef __cplusplus +} +#endif + +#define IDB04A1 0 +#define IDB05A1 1 + +/* See file 'bluenrg_targets.h' for details regarding the BLUENRG_STACK_MODE */ +#define STACK_MODE BLUENRG_STACK_MODE + +void HCI_Input(tHciDataPacket * hciReadPacket); + +uint16_t g_gap_service_handle = 0; +uint16_t g_appearance_char_handle = 0; +uint16_t g_device_name_char_handle = 0; +uint16_t g_preferred_connection_parameters_char_handle = 0; + +/* Private variables ---------------------------------------------------------*/ +volatile uint8_t set_connectable = 1; + +static char versionString[32]; +uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ + +/**************************************************************************/ +/*! + @brief Init the BTLE stack with the specified role + @returns void +*/ +/**************************************************************************/ +void btleInit(void) +{ + PRINTF("btleInit>>\n\r"); + + int ret; + uint8_t hwVersion; + uint16_t fwVersion; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* get the BlueNRG HW and FW versions */ + getBlueNRGVersion(&hwVersion, &fwVersion); + + /* + * Reset BlueNRG again otherwise we won't + * be able to change its MAC address. + * aci_hal_write_config_data() must be the first + * command after reset otherwise it will fail. + */ + BlueNRG_RST(); + + if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ + bnrg_expansion_board = IDB05A1; + } + + /* set BLE version string */ + setVersionString(hwVersion, fwVersion); + + if (bnrg_expansion_board == IDB05A1) { + uint8_t stackMode = STACK_MODE; + ret = aci_hal_write_config_data(CONFIG_DATA_MODE_OFFSET, + CONFIG_DATA_MODE_LEN, + &stackMode); + } + + ret = aci_gatt_init(); + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GATT_Init failed.\n"); + } + if (bnrg_expansion_board == IDB05A1) { + ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1, + 0, + 0x18, + &service_handle, + &dev_name_char_handle, + &appearance_char_handle); + } else { + // IDB04A1 is configured as peripheral by default + ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + } + + // read the default static address and inject it into the GAP object + { + Gap::Address_t BLE_address_BE = { 0 }; + uint8_t data_len_out; + aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS, BDADDR_SIZE, &data_len_out, BLE_address_BE); + // FIXME error handling of this function + BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE); + } + + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GAP_Init failed.\n"); + } + + //FIXME: Security and passkey set by default + ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, + OOB_AUTH_DATA_ABSENT, + NULL, + 7, + 16, + USE_FIXED_PIN_FOR_PAIRING, + 123456, + BONDING); + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Auth Req set failed.\n"); + } + + aci_hal_set_tx_power_level(1,4); + + g_gap_service_handle = service_handle; + g_appearance_char_handle = appearance_char_handle; + g_device_name_char_handle = dev_name_char_handle; + //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API + /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, + strlen(name), (tHalUint8 *)name);*/ + + signalEventsToProcess(); + // update the peripheral preferred conenction parameters handle + // This value is hardcoded at the moment. + g_preferred_connection_parameters_char_handle = 10; + + return; +} + +/**************************************************************************/ +/*! + @brief mbedOS + + @param[in] void + + @returns +*/ +/**************************************************************************/ +int btle_handler_pending = 0; + +void btle_handler(void) +{ + btle_handler_pending = 0; + BlueNRGGap::getInstance().Process(); + HCI_HandleSPI(); + HCI_Process(); +} + +/* set BLE Version string */ +void setVersionString(uint8_t hwVersion, uint16_t fwVersion) +{ + if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) { + snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u", + hwVersion>>4, (hwVersion&0x0F), + fwVersion>>8, (fwVersion&0x00F0)>>4); + } else { + snprintf(versionString, sizeof(versionString), "ST (unknown spec)"); + } +} + +/* get BLE Version string */ +const char* getVersionString(void) +{ + return versionString; +} + +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type) +{ + tBleStatus ret; + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + if(bnrg_expansion_board == IDB05A1) { + PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window); + PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type); + ret = aci_gap_start_observation_procedure(scan_interval, + scan_window, + scan_type, + own_address_type, + 0); // 1 to filter duplicates + } else { + ret = BLE_STATUS_INVALID_CID; + } + + return ret; + +} + +/*! + @brief Not Used + + @param[in] void + + @returns +*/ +void SPI_Poll(void) +{ + //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); + return; +} + +void Attribute_Modified_CB(evt_blue_aci *blue_evt) +{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t *att_data; + uint8_t offset; + + if (bnrg_expansion_board == IDB05A1) { + evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = evt->offset; + } else { + evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = 0; + } + + //Extract the GattCharacteristic from p_characteristics[] and find the properties mask + GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle); + if(p_char!=NULL) { + GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE; + PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]); + PRINTF("getProperties 0x%x\n\r",p_char->getProperties()); + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; + } + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; + } + PRINTF("currentHandle %d\n\r", currentHandle); + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && + currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { + + GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1; + + PRINTF("*****NOTIFICATION CASE\n\r"); + //Now Check if data written in Enable or Disable + if((uint16_t)att_data[0]==1) { + //PRINTF("Notify ENABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle); + } else { + //PRINTF("Notify DISABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle); + } + return; + } + + //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) && + currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) { + + PRINTF("*****WRITE CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = p_char->getValueAttribute().getHandle(); + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle); + //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + BlueNRGGattServer::getInstance().write( + p_char->getValueAttribute().getHandle(), + (uint8_t*)att_data, + data_length, + false + ); + } + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } else { + PRINTF("*****WRITE DESCRIPTOR CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = attr_handle; + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } + } + +} + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************************/ + /*! + @brief Handle HCI Stack Event + + @param[in] pckt + Event Packet sent by the stack to be decoded + + @returns + */ + /**************************************************************************/ + extern void HCI_Event_CB(void *pckt) { + hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; + hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; + + if(hci_pckt->type != HCI_EVENT_PKT) + return; + + switch(event_pckt->evt){ + + case EVT_DISCONN_COMPLETE: + { + PRINTF("EVT_DISCONN_COMPLETE\n"); + + evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data; + + if(BlueNRGGap::getInstance().getGapRole() == Gap::CENTRAL) { + BlueNRGGattClient::getInstance().removeGattConnectionClient(evt->handle, evt->reason); + } + + BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason); + } + break; + + case EVT_LE_META_EVENT: + { + PRINTF("EVT_LE_META_EVENT\n"); + + evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; + + switch(evt->subevent){ + + case EVT_LE_CONN_COMPLETE: + { + PRINTF("EVT_LE_CONN_COMPLETE\n"); + Gap::Address_t ownAddr; + Gap::AddressType_t ownAddrType; + BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr); + + Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + Gap::Role_t role; + + evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; + + BlueNRGGap::getInstance().setConnectionHandle(cc->handle); + BlueNRGGap::ConnectionParams_t connectionParams = { + /* minConnectionInterval = */ cc->interval, + /* maxConnectionInterval = */ cc->interval, + /* slaveLatency = */ cc->latency, + /* connectionSupervisionTimeout = */ cc->supervision_timeout + }; + + BlueNRGGap::getInstance().setConnectionInterval(cc->interval); + + switch (cc->peer_bdaddr_type) { + case PUBLIC_ADDR: + peerAddrType = BLEProtocol::AddressType::PUBLIC; + break; + case STATIC_RANDOM_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + break; + case RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE; + break; + case NON_RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE; + break; + } + //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role); + switch (cc->role) { + case 0: //master + role = Gap::CENTRAL; + BlueNRGGattClient::getInstance().createGattConnectionClient(cc->handle); + break; + case 1: + role = Gap::PERIPHERAL; + break; + default: + role = Gap::PERIPHERAL; + break; + } + + BlueNRGGap::getInstance().setGapRole(role); + + BlueNRGGap::getInstance().processConnectionEvent(cc->handle, + role, + peerAddrType, + cc->peer_bdaddr, + ownAddrType, + ownAddr, + &connectionParams); + } + break; + + case EVT_LE_ADVERTISING_REPORT: + PRINTF("EVT_LE_ADVERTISING_REPORT\n\r"); + /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */ + // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT) + // Formally the structure related to both events are identical except that for the ADV REPORT + // there is one more field (number of reports) which is not forwarded to upper layer. + // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT. + le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1); + PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + break; + } + } + break; + + case EVT_VENDOR: + { + evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; + //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode); + + switch(blue_evt->ecode){ + + case EVT_BLUE_GATT_WRITE_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_WRITE_PERMIT_REQ\r\n"); + evt_gatt_write_permit_req* write_req = (evt_gatt_write_permit_req*)blue_evt->data; + + // ask the local server if the write operation is authorized + uint8_t err_code = BlueNRGGattServer::getInstance().Write_Request_CB( + write_req->conn_handle, + write_req->attr_handle, + write_req->data_length, + write_req->data + ); + uint8_t write_status = err_code == 0 ? 0 : 1; + + // reply to the shield + aci_gatt_write_response( + write_req->conn_handle, + write_req->attr_handle, + write_status, + err_code, + write_req->data_length, + write_req->data + ); + } + break; + + case EVT_BLUE_GATT_READ_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r"); + evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle); + BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle); + } + break; + + case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: + { + PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r"); + /* this callback is invoked when a GATT attribute is modified + extract callback data and pass to suitable handler function */ + Attribute_Modified_CB(blue_evt); + } + break; + + //Any cases for Data Sent Notifications? + case EVT_BLUE_GATT_NOTIFICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_NOTIFICATION"); + break; + case EVT_BLUE_GATT_INDICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_INDICATION"); + break; + + case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r"); + evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_data_length, + pr->attribute_data_list); + } + break; + case EVT_BLUE_ATT_READ_BY_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r"); + evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle, + pr->event_data_length, + pr->handle_value_pair_length, + pr->handle_value_pair); + } + break; + case EVT_BLUE_ATT_READ_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_RESP\n\r"); + evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_value); + } + break; + case EVT_BLUE_ATT_EXEC_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle, + pr->event_data_length); + } + break; + case EVT_BLUE_ATT_PREPARE_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_handle, + pr->offset, + pr->part_attr_value); + } + break; + case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP: + { + PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r"); + evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle, + pr->event_data_length, + pr->attr_handle, + pr->attr_value); + } + break; + case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r"); + evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle, + pr->event_data_length, + pr->handles_info_list); + } + break; + case EVT_BLUE_ATT_FIND_INFORMATION_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r"); + evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle, + pr->event_data_length, + pr->format, + pr->handle_uuid_pair); + } + break; + case EVT_BLUE_GATT_PROCEDURE_COMPLETE: + { + evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code); + BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code); + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_REQ: + { + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_REQ\r\n"); + evt_l2cap_conn_upd_req *evt = (evt_l2cap_conn_upd_req*)blue_evt->data; + if(bnrg_expansion_board == IDB05A1) { + // we assume the application accepts the request from the slave + aci_l2cap_connection_parameter_update_response_IDB05A1(evt->conn_handle, + evt->interval_min, + evt->interval_max, + evt->slave_latency, + evt->timeout_mult, + CONN_L1, CONN_L2, + evt->identifier, + 0x0000); + } + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_RESP: + { + evt_l2cap_conn_upd_resp *evt = (evt_l2cap_conn_upd_resp*)blue_evt->data; + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_RESP code=0x%x, result=0x%x\r\n", evt->code, evt->result); + } + break; + + case EVT_LE_CONN_UPDATE_COMPLETE: + { + evt_le_connection_update_complete *evt = (evt_le_connection_update_complete*)blue_evt->data; + PRINTF("EVT_LE_CONN_UPDATE_COMPLETE status=0x%x\r\n", evt->status); + } + break; + + case EVT_BLUE_GAP_DEVICE_FOUND: + { + evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data; + PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + } + break; + + case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + { + evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data; + //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code); + + switch(pr->procedure_code) { + case GAP_OBSERVATION_PROC_IDB05A1: + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL); + break; + } + } + break; + } + } + break; + } + return ; + } + + +#ifdef __cplusplus +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,217 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.cpp + * @author CL + * @version V1.0.0 + * @date 15-June-2015 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRGGap.h" +#include "BlueNRGDevice.h" +#include "btle.h" + +// FIXME: find a better way to get the instance of the BlueNRG device +extern BlueNRGDevice bluenrgDeviceInstance; + + +//////////////////////////////////////// +// Start of C function wrappers +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32_bluenrg_ble.h" +#include "ble_debug.h" + + +void BlueNRG_RST(void) +{ + bluenrgDeviceInstance.reset(); +} + +uint8_t BlueNRG_DataPresent(void) +{ + return (bluenrgDeviceInstance.dataPresent()); +} + + +/** + * @brief This function is a utility to print the log time +* in the format HH:MM:SS:MSS (DK GUI time format) + * @param None + * @retval None + */ +void print_csv_time(void){ +#ifdef PRINT_CSV_FORMAT + uint32_t ms = 0;//ms_counter; + PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000); +#endif +} + +/** + * @brief Writes data to a serial interface. + * @param data1 : 1st buffer + * @param data2 : 2nd buffer + * @param n_bytes1: number of bytes in 1st buffer + * @param n_bytes2: number of bytes in 2nd buffer + * @retval None + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, + int32_t n_bytes2) +{ + struct timer t; + + Timer_Set(&t, CLOCK_SECOND/10); + +#ifdef PRINT_CSV_FORMAT + print_csv_time(); + for (int i=0; i<n_bytes1; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data1)[i]); + } + for (int i=0; i<n_bytes2; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data2)[i]); + } + PRINT_CSV("\n"); +#endif + + while(1){ + if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; + if(Timer_Expired(&t)){ + break; + } + } +} + + +/** + * @brief Activate internal bootloader using pin. + * @param None + * @retval None + */ +void BlueNRG_HW_Bootloader(void) +{ + // Reset BlueNRG SPI interface + BlueNRG_RST(); + + // Send an ACI command to reboot BlueNRG in bootloader mode + // The safest way to get in bootloader mode is keeping high + // the interrupt pin during reset, but this would require many + // changes to the current mbed driver + aci_updater_start(); +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size) +{ + int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size); + + return ret; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2); + + return ret; +} + +/** + * @brief Enable SPI IRQ. + * @param None + * @retval None + */ +void Enable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.enable_irq(); +} + +void signalEventsToProcess(void) { + if(btle_handler_pending == 0) { + btle_handler_pending = 1; + bluenrgDeviceInstance.signalEventsToProcess(BLE::DEFAULT_INSTANCE); + } +} + +/** + * @brief Disable SPI IRQ. + * @param None + * @retval None + */ +void Disable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.disable_irq(); +} + +/** + * @brief Clear Pending SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_IRQ(void) +{ +} + +/** + * @brief Clear EXTI (External Interrupt) line for SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_EXTI_Flag(void) +{ +} + + + + +#ifdef __cplusplus +} +#endif +// End of C function wrappers +//////////////////////////////////////// + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <ble_payload.h> + +Payload::Payload() { + stringLength = 0; + payloadUnitCount = 0; + payload = NULL; +} + +Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + stringLength = string_ength; + payloadUnitCount = 0; + payload = NULL; + + int index = 0; + while( index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + UnitPayload *obj = new UnitPayload[payloadUnitCount]; + int i=0; + int c=0; + int j,k; + + while(i<payloadUnitCount) + { + obj[i].length=tokenString[c]; + obj[i].id=tokenString[c+1]; + + obj[i].data = new uint8_t[obj[i].length]; + for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) + { + obj[i].data[k]=tokenString[j]; + + } + + c=c+obj[i].length+1; + i++; + + } + payload = obj; +} + +uint8_t Payload::getPayloadUnitCount() { + return payloadUnitCount; +} + +uint8_t Payload::getIDAtIndex(int index) { + return payload[index].get_id(); +} + +uint8_t Payload::getLengthAtIndex(int index) { + return payload[index].get_length(); +} + +uint8_t* Payload::getDataAtIndex(int index) { + return payload[index].get_data(); +} + +int8_t Payload::getInt8AtIndex(int index) { + uint8_t* str = payload[index].get_data(); + int8_t value = (int8_t)str[0]; + return value; +} + +uint16_t Payload::getUint16AtIndex(int index) { + uint16_t* str = (uint16_t*)payload[index].get_data(); + uint16_t value = str[0]; + return value; +} + +uint8_t* Payload::getSerializedAdDataAtIndex(int index) { + uint8_t length = payload[index].get_length(); + uint8_t* data = payload[index].get_data(); + uint8_t id = payload[index].get_id(); + uint8_t *serializedAdData = new uint8_t[length]; + + serializedAdData[0] = id; + for(int i=0; i<length-1; i++) { + serializedAdData[i+1] = data[i]; + } + return serializedAdData; +} + +Payload::~Payload() { + int i = 0; + + if(payload) { + while(i<payloadUnitCount) { + if(payload->data) { + delete[] payload->data; + payload->data = NULL; + } + } + delete[] payload; + payload = NULL; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,93 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ble_utils.h" + +/**************************************************************************/ +/*! + @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power + +*/ +/**************************************************************************/ +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(dBMLevel==-18) { + EN_HIGH_POWER = 0; + PA_LEVEL = 0; + } + else if(dBMLevel==-15) { + EN_HIGH_POWER = 0; + PA_LEVEL = 1; + } + else if(dBMLevel==-14) { + EN_HIGH_POWER = 1; + PA_LEVEL = 0; + } + else if(dBMLevel==-12) { + EN_HIGH_POWER = 0; + PA_LEVEL = 2; + } + else if(dBMLevel==-11) { + EN_HIGH_POWER = 1; + PA_LEVEL = 1; + } + else if(dBMLevel==-9) { + EN_HIGH_POWER = 0; + PA_LEVEL = 3; + } + else if(dBMLevel==-8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 2; + } + else if(dBMLevel==-6) { + EN_HIGH_POWER = 0; + PA_LEVEL = 4; + } + else if(dBMLevel==-5) { + EN_HIGH_POWER = 1; + PA_LEVEL = 3; + } + else if(dBMLevel==-2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 4; + } + else if(dBMLevel==0) { + EN_HIGH_POWER = 0; + PA_LEVEL = 6; + } + else if(dBMLevel==2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 5; + } + else if(dBMLevel==4) { + EN_HIGH_POWER = 1; + PA_LEVEL = 6; + } + else if(dBMLevel==5) { + EN_HIGH_POWER = 0; + PA_LEVEL = 7; + } + else if(dBMLevel==8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + else { + ret = ERR_INVALID_HCI_CMD_PARAMS; + } + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_LEDBlinker/source/main.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,199 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <events/mbed_events.h> +#include <mbed.h> +#include "ble/BLE.h" +#include "ble/DiscoveredCharacteristic.h" +#include "ble/DiscoveredService.h" + +DigitalOut alivenessLED(LED1, 1); +static DiscoveredCharacteristic ledCharacteristic; +static bool triggerLedCharacteristic; +static const char PEER_NAME[] = "LED"; + +static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); + +void periodicCallback(void) { + alivenessLED = !alivenessLED; /* Do blinky on LED1 while we're waiting for BLE events */ +} + +void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { + // parse the advertising payload, looking for data type COMPLETE_LOCAL_NAME + // The advertising payload is a collection of key/value records where + // byte 0: length of the record excluding this byte + // byte 1: The key, it is the type of the data + // byte [2..N] The value. N is equal to byte0 - 1 + for (uint8_t i = 0; i < params->advertisingDataLen; ++i) { + + const uint8_t record_length = params->advertisingData[i]; + if (record_length == 0) { + continue; + } + const uint8_t type = params->advertisingData[i + 1]; + const uint8_t* value = params->advertisingData + i + 2; + const uint8_t value_length = record_length - 1; + + if(type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { + if ((value_length == sizeof(PEER_NAME)) && (memcmp(value, PEER_NAME, value_length) == 0)) { + printf( + "adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n", + params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], + params->peerAddr[1], params->peerAddr[0], params->rssi, params->isScanResponse, params->type + ); + BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL); + break; + } + } + i += record_length; + } +} + +void serviceDiscoveryCallback(const DiscoveredService *service) { + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle()); + } else { + printf("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + printf("%02x", longUUIDBytes[i]); + } + printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle()); + } +} + +void updateLedCharacteristic(void) { + if (!BLE::Instance().gattClient().isServiceDiscoveryActive()) { + ledCharacteristic.read(); + } +} + +void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) { + printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); + if (characteristicP->getUUID().getShortUUID() == 0xa001) { /* !ALERT! Alter this filter to suit your device. */ + ledCharacteristic = *characteristicP; + triggerLedCharacteristic = true; + } +} + +void discoveryTerminationCallback(Gap::Handle_t connectionHandle) { + printf("terminated SD for handle %u\r\n", connectionHandle); + if (triggerLedCharacteristic) { + triggerLedCharacteristic = false; + eventQueue.call(updateLedCharacteristic); + } +} + +void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { + if (params->role == Gap::CENTRAL) { + BLE &ble = BLE::Instance(); + ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); + ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, 0xa000, 0xa001); + } +} + +void triggerToggledWrite(const GattReadCallbackParams *response) { + if (response->handle == ledCharacteristic.getValueHandle()) { + printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len); + for (unsigned index = 0; index < response->len; index++) { + printf("%c[%02x]", response->data[index], response->data[index]); + } + printf("\r\n"); + + uint8_t toggledValue = response->data[0] ^ 0x1; + ledCharacteristic.write(1, &toggledValue); + } +} + +void triggerRead(const GattWriteCallbackParams *response) { + if (response->handle == ledCharacteristic.getValueHandle()) { + ledCharacteristic.read(); + } +} + +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) { + printf("disconnected\r\n"); + /* Start scanning and try to connect again */ + BLE::Instance().gap().startScan(advertisementCallback); +} + +void onBleInitError(BLE &ble, ble_error_t error) +{ + /* Initialization error handling should go here */ +} + +void printMacAddress() +{ + /* Print out device MAC address to the console*/ + Gap::AddressType_t addr_type; + Gap::Address_t address; + BLE::Instance().gap().getAddress(&addr_type, address); + printf("DEVICE MAC ADDRESS: "); + for (int i = 5; i >= 1; i--){ + printf("%02x:", address[i]); + } + printf("%02x\r\n", address[0]); +} + +void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) +{ + BLE& ble = params->ble; + ble_error_t error = params->error; + + if (error != BLE_ERROR_NONE) { + /* In case of error, forward the error handling to onBleInitError */ + onBleInitError(ble, error); + return; + } + + /* Ensure that it is the default instance of BLE */ + if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { + return; + } + + ble.gap().onDisconnection(disconnectionCallback); + ble.gap().onConnection(connectionCallback); + + ble.gattClient().onDataRead(triggerToggledWrite); + ble.gattClient().onDataWrite(triggerRead); + + // scan interval: 400ms and scan window: 400ms. + // Every 400ms the device will scan for 400ms + // This means that the device will scan continuously. + ble.gap().setScanParams(400, 400); + ble.gap().startScan(advertisementCallback); + + printMacAddress(); +} + +void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { + BLE &ble = BLE::Instance(); + eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); +} + +int main() +{ + triggerLedCharacteristic = false; + eventQueue.call_every(500, periodicCallback); + + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(scheduleBleEventsProcessing); + ble.init(bleInitComplete); + + eventQueue.dispatch_forever(); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Privacy/.mbed Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +ROOT=.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Privacy/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,27 @@ +# Privacy - example usage of the privacy feature + +Demonstration of privacy features in Gap. It shows how to use private addresses when advertising and connecting and how filtering ties in with these operations. + +The application will start by repeatedly trying to connect to the same application running on another board. It will do this by advertising and scanning for random intervals waiting until the difference in intervals between the boards will make them meet when one is advertising and the other scanning. + +Two devices will be operating using random resolvable addresses. The application will connect to the peer and pair. It will attempt bonding and if possible create a whitelist based on the bond. + +Subsequent connections will turn on filtering if the whitelist has been successfully created. + +# Running the application + +## Requirements + +Application requires two devices. Each one should be loaded with the same example. The application will alternate between scanning and advertising until the two devices find each other and the demonstration proceeds. + +Information about activity is printed over the serial connection - please have two clients open, each connected to a device. You may use: + +- [Tera Term](https://ttssh2.osdn.jp/index.html.en) + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +Note: example currently doesn't use ST provided stack and instead uses a Cordio port for the ST.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Privacy/mbed-os.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#6817dc43f9f5216cbe077059fc561fa89a766dc9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Privacy/mbed_app.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,5 @@ +{ + "target_overrides": { + + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Privacy/source/main.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,498 @@ +/* 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 <events/mbed_events.h> +#include <mbed.h> +#include "ble/BLE.h" +#include "SecurityManager.h" +#include <algorithm> + +/** This example demonstrates privacy features in Gap. It shows how to use + * private addresses when advertising and connecting and how filtering ties + * in with these operations. + * + * The application will start by repeatedly trying to connect to the same + * application running on another board. It will do this by advertising and + * scanning for random intervals waiting until the difference in intervals + * between the boards will make them meet when one is advertising and the + * other scanning. + * + * Two devices will be operating using random resolvable addresses. The + * applications will connect to the peer and pair. It will attempt bonding + * to store the IRK that resolve the peer. Subsequent connections will + * turn on filtering based on stored IRKs. + */ + +static const uint8_t DEVICE_NAME[] = "Privacy"; + +/** print device address to the terminal */ +void print_address(const Gap::Address_t &addr) +{ + printf("%02x:%02x:%02x:%02x:%02x:%02x\r\n", + addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); +} + +/** Base class for both peripheral and central. The same class that provides + * the logic for the application also implements the SecurityManagerEventHandler + * which is the interface used by the Security Manager to communicate events + * back to the applications. You can provide overrides for a selection of events + * your application is interested in. + */ +class PrivacyDevice : private mbed::NonCopyable<PrivacyDevice>, + public SecurityManager::EventHandler +{ +public: + PrivacyDevice(BLE &ble, events::EventQueue &event_queue) : + _ble(ble), + _event_queue(event_queue), + _handle(0), + _bonded(false), + _led1(LED1, 0) { }; + + virtual ~PrivacyDevice() { + _ble.onEventsToProcess(NULL); + }; + + /** Start BLE interface initialisation */ + void run() + { + /* to show we're running we'll blink every 500ms */ + _event_queue.call_every(500, this, &PrivacyDevice::blink); + + /* this will inform us off all events so we can schedule their handling + * using our event queue */ + _ble.onEventsToProcess( + makeFunctionPointer(this, &PrivacyDevice::schedule_ble_events) + ); + + if (_ble.hasInitialized()) { + /* ble instance already initialised, skip init and start activity */ + start(); + } else { + ble_error_t error = _ble.init(this, &PrivacyDevice::on_init_complete); + + if (error) { + printf("Error returned by BLE::init.\r\n"); + return; + } + } + + /* this will not return until shutdown */ + _event_queue.dispatch_forever(); + }; + + /** Override to start chosen activity when initialisation completes */ + virtual void start() = 0; + + /** Override to start chosen activity after initial bonding */ + virtual void start_after_bonding() = 0; + + /* event handler functions */ + + /** Inform the application of pairing */ + virtual void pairingResult( + ble::connection_handle_t connectionHandle, + SecurityManager::SecurityCompletionStatus_t result + ) { + if (result == SecurityManager::SEC_STATUS_SUCCESS) { + printf("Pairing successful\r\n"); + _bonded = true; + } else { + printf("Pairing failed\r\n"); + } + + /* disconnect in 2s */ + _event_queue.call_in( + 2000, &_ble.gap(), + &Gap::disconnect, _handle, Gap::REMOTE_USER_TERMINATED_CONNECTION + ); + } + + /* callbacks */ + + /** This is called when BLE interface is initialised and starts the demonstration */ + void on_init_complete(BLE::InitializationCompleteCallbackContext *event) + { + ble_error_t error; + + if (event->error) { + printf("Error during the initialisation\r\n"); + _event_queue.break_dispatch(); + return; + } + + /* for use by tools we print out own address and also use it + * to seed RNG as the address is unique */ + print_local_address(); + + /* when scanning we want to connect to a peer device so we need to + * attach callbacks that are used by Gap to notify us of events */ + _ble.gap().onConnection(this, &PrivacyDevice::on_connect); + _ble.gap().onDisconnection(this, &PrivacyDevice::on_disconnect); + _ble.gap().onTimeout(makeFunctionPointer(this, &PrivacyDevice::on_timeout)); + + /* Privacy requires the security manager */ + + error = _ble.securityManager().init( + /* enableBonding */ true, + /* requireMITM */ false, + /* iocaps */ SecurityManager::IO_CAPS_NONE, + /* passkey */ NULL, + /* signing */ false, + /* dbFilepath */ NULL + ); + + if (error) { + printf("Error during security manager initialisation\r\n"); + _event_queue.break_dispatch(); + return; + } + + /* Tell the security manager to use methods in this class to inform us + * of any events. Class needs to implement SecurityManagerEventHandler. */ + _ble.securityManager().setSecurityManagerEventHandler(this); + + /* privacy */ + + error = _ble.gap().enablePrivacy(true); + + if (error) { + printf("Error enabling privacy.\r\n"); + _event_queue.break_dispatch(); + return; + } + + start(); + }; + + /** This is called by Gap to notify the application we connected */ + void on_connect(const Gap::ConnectionCallbackParams_t *connection_event) + { + printf("Connected to peer: "); + print_address(connection_event->peerAddr); + printf("Peer random resolvable address: "); + print_address(connection_event->peerResolvableAddr); + + _handle = connection_event->handle; + + if (_bonded) { + /* disconnect in 2s */ + _event_queue.call_in( + 2000, &_ble.gap(), + &Gap::disconnect, _handle, Gap::REMOTE_USER_TERMINATED_CONNECTION + ); + } + }; + + /** This is called by Gap to notify the application we disconnected */ + void on_disconnect(const Gap::DisconnectionCallbackParams_t *event) + { + if (_bonded) { + /* we have connected to and bonded with the other device, from now + * on we will use the second start function and stay in the same role + * as peripheral or central */ + printf("Disconnected.\r\n"); + _event_queue.call_in(2000, this, &PrivacyDevice::start_after_bonding); + } else { + printf("Failed to bond.\r\n"); + _event_queue.break_dispatch(); + } + }; + + /** When scanning on advertising time runs out this is called */ + void on_timeout(const Gap::TimeoutSource_t source) + { + /* if we failed to find the other device, abort so that we change roles */ + printf("Haven't seen other device, switch modes.\r\n"); + _event_queue.break_dispatch(); + }; + + /** Schedule processing of events from the BLE in the event queue. */ + void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) + { + _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents)); + }; + + /** Blink LED to show we're running */ + void blink(void) + { + _led1 = !_led1; + }; + + void print_local_address() + { + /* show what address we are using now */ + Gap::AddressType_t addr_type; + Gap::Address_t addr; + _ble.gap().getAddress(&addr_type, addr); + printf("Device address: "); + print_address(addr); + + if (!_seeded) { + _seeded = true; + /* use the address as a seed */ + uint8_t* random_data = addr; + srand(*((unsigned int*)random_data)); + } + } + +public: + static bool _seeded; + +protected: + BLE &_ble; + events::EventQueue &_event_queue; + ble::connection_handle_t _handle; + bool _bonded; + +private: + DigitalOut _led1; +}; + +/** A peripheral device will advertise and accept the connections */ +class PrivacyPeripheral : public PrivacyDevice { +public: + PrivacyPeripheral(BLE &ble, events::EventQueue &event_queue) + : PrivacyDevice(ble, event_queue) { } + + /** Set up and start advertising accepting anyone */ + virtual void start() + { + if (!set_advertising_data()) { + return; + } + + Gap::PeripheralPrivacyConfiguration_t privacy_configuration = { + /* use_non_resolvable_random_address */ false, + Gap::PeripheralPrivacyConfiguration_t::PERFORM_PAIRING_PROCEDURE + }; + + _ble.gap().setPeripheralPrivacyConfiguration(&privacy_configuration); + + start_advertising(); + }; + + /** advertise and filter based on known devices */ + virtual void start_after_bonding() + { + Gap::PeripheralPrivacyConfiguration_t privacy_configuration = { + /* use_non_resolvable_random_address */ false, + Gap::PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS + }; + + _ble.gap().setPeripheralPrivacyConfiguration(&privacy_configuration); + + start_advertising(); + } + + /* helper functions */ + +private: + bool set_advertising_data() + { + GapAdvertisingData advertising_data; + + /* add device name */ + advertising_data.addData( + GapAdvertisingData::COMPLETE_LOCAL_NAME, + DEVICE_NAME, + sizeof(DEVICE_NAME) + ); + + ble_error_t error = _ble.gap().setAdvertisingPayload(advertising_data); + + if (error) { + printf("Error during Gap::setAdvertisingPayload\r\n"); + _event_queue.break_dispatch(); + return false; + } + + return true; + } + + bool start_advertising() + { + _ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + _ble.gap().setAdvertisingInterval(20); + + if (_bonded) { + /* if we bonded it means we have found the other device, from now on + * wait at each step until completion */ + _ble.gap().setAdvertisingTimeout(0); + } else { + /* since we have two boards which might start running this example at the same time + * we randomise the interval of advertising to have them meet when one is advertising + * and the other one is scanning (we use their random address as source of randomness) */ + const uint16_t random_interval = 1 + rand() % 5; + _ble.gap().setAdvertisingTimeout(random_interval); + } + + ble_error_t error = _ble.gap().startAdvertising(); + + if (error) { + printf("Error during Gap::startAdvertising.\r\n"); + _event_queue.break_dispatch(); + return false; + } + + printf("Advertising...\r\n"); + + return true; + } + +}; + +/** A central device will scan and connect to a peer. */ +class PrivacyCentral : public PrivacyDevice { +public: + PrivacyCentral(BLE &ble, events::EventQueue &event_queue) + : PrivacyDevice(ble, event_queue), + _is_connecting(false) { } + + /** start scanning and attach a callback that will handle advertisements + * and scan requests responses */ + virtual void start() + { + Gap::CentralPrivacyConfiguration_t privacy_configuration = { + /* use_non_resolvable_random_address */ false, + Gap::CentralPrivacyConfiguration_t::DO_NOT_RESOLVE + }; + + _ble.gap().setCentralPrivacyConfiguration(&privacy_configuration); + + start_scanning(); + } + + virtual void start_after_bonding() + { + Gap::CentralPrivacyConfiguration_t privacy_configuration = { + /* use_non_resolvable_random_address */ false, + Gap::CentralPrivacyConfiguration_t::RESOLVE_AND_FILTER + }; + + _ble.gap().setCentralPrivacyConfiguration(&privacy_configuration); + + start_scanning(); + } + + /* callbacks */ + + /** Look at scan payload to find a peer device and connect to it */ + void on_scan(const Gap::AdvertisementCallbackParams_t *params) + { + /* don't bother with analysing scan result if we're already connecting */ + if (_is_connecting) { + return; + } + + /* parse the advertising payload, looking for a discoverable device */ + for (uint8_t i = 0; (i + 2) < params->advertisingDataLen; ++i) { + /* The advertising payload is a collection of key/value records where + * byte 0: length of the record excluding this byte + * byte 1: The key, it is the type of the data + * byte [2..N] The value. N is equal to byte0 - 1 */ + const uint8_t max_record_length = params->advertisingDataLen - i; + const uint8_t record_length = std::min(params->advertisingData[i], + max_record_length); + const uint8_t type = params->advertisingData[i + 1]; + const uint8_t *value = params->advertisingData + i + 2; + + if (record_length < 2) { + /* malformed record */ + } else if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { + /* connect based on the name of the device */ + if (memcmp((const char*)DEVICE_NAME, (const char*)value, record_length - 1) == 0) { + _ble.gap().stopScan(); + + ble_error_t error = _ble.gap().connect( + params->peerAddr, params->peerAddrType, + NULL, NULL + ); + + if (error) { + printf("Error during Gap::connect %d\r\n", error); + return; + } + + /* we may have already scan events waiting + * to be processed so we need to remember + * that we are already connecting and ignore them */ + _is_connecting = true; + + return; + } + } + + i += record_length; + } + }; + + /* helper functions */ +private: + bool start_scanning() { + if (_bonded) { + /* if we bonded it means we have found the other device, from now on + * wait at each step until completion */ + _ble.gap().setScanParams(4, 4, 0 /*timeout*/); + } else { + /* otherwise only scan for a limited time before changing roles again + * if we fail to find the other device */ + _ble.gap().setScanParams(4, 4, 4/*timeout*/); + } + + _is_connecting = false; + + ble_error_t error = _ble.gap().startScan(this, &PrivacyCentral::on_scan); + + if (error) { + printf("Error during Gap::startScan %d\r\n", error); + _event_queue.break_dispatch(); + return false; + } + + printf("Scanning...\r\n"); + + return true; + } + +private: + bool _is_connecting; +}; + +/* only seed the random number generation once per application run */ +bool PrivacyDevice::_seeded = false; + +int main() +{ + BLE& ble = BLE::Instance(); + + while(1) { + { + events::EventQueue queue; + printf("\r\n * Device is a peripheral *\r\n\r\n"); + PrivacyPeripheral peripheral(ble, queue); + peripheral.run(); + } + { + events::EventQueue queue; + printf("\r\n * Device is a central *\r\n\r\n"); + PrivacyCentral central(ble, queue); + central.run(); + } + } + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_SM/.mbed Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +ROOT=.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_SM/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,29 @@ +# SM - example usage of the Security Manager to pair and encrypt + +Demonstration of possible usage of the Security Manager. Security Manager deals with pairing, authentication and encryption. + +The application demonstrates usage as a central and a peripheral. The central will connect to any connectable device present. Please have one ready and advertising. Application will attempt pairing. Please authorise your peer device to pair. + +Upon success it will disconnect and start advertising to demonstrate usage as a peripheral. Please scan and connect using your peer device. Upon connection grant pairing if prompted. Upon success the application will disconnect. Observe the terminal to keep track of the sequence. + +# Running the application + +## Requirements + +The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : + +- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. + +- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. + +Information about activity is printed over the serial connection - please have a client open. You may use: + +- [Tera Term](https://ttssh2.osdn.jp/index.html.en) + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +Note: example currently doesn't use ST provided stack and instead uses a Cordio port for the ST.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_SM/mbed-os.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_SM/mbed_app.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "target_overrides": { + "K64F": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG", "CORDIO"] + }, + "NUCLEO_F401RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG", "CORDIO"] + }, + "DISCO_L475VG_IOT01A": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG", "CORDIO"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_SM/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,15 @@ +{ + "name": "ble-securitymanager", + "version": "0.0.1", + "description": "BLE Security Manager usage example", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "dependencies": { + "ble": "^2.0.0" + }, + "bin": "./source" +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_SM/source/main.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,417 @@ +/* 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 <events/mbed_events.h> +#include <mbed.h> +#include "ble/BLE.h" +#include "SecurityManager.h" + +/** This example demonstrates all the basic setup required + * for pairing and setting up link security both as a central and peripheral + * + * The example is implemented as two classes, one for the peripheral and one + * for central inheriting from a common base. They are run in sequence and + * require a peer device to connect to. During the peripheral device demonstration + * a peer device is required to connect. In the central device demonstration + * this peer device will be scanned for and connected to - therefore it should + * be advertising with the same address as when it connected. + * + * During the test output is written on the serial connection to monitor its + * progress. + */ + +static const uint8_t DEVICE_NAME[] = "SM_device"; + +/* for demonstration purposes we will store the peer device address + * of the device that connects to us in the first demonstration + * so we can use its address to reconnect to it later */ +static BLEProtocol::AddressBytes_t peer_address; + +/** Base class for both peripheral and central. The same class that provides + * the logic for the application also implements the SecurityManagerEventHandler + * which is the interface used by the Security Manager to communicate events + * back to the applications. You can provide overrides for a selection of events + * your application is interested in. + */ +class SMDevice : private mbed::NonCopyable<SMDevice>, + public SecurityManager::EventHandler +{ +public: + SMDevice(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) : + _led1(LED1, 0), + _ble(ble), + _event_queue(event_queue), + _peer_address(peer_address), + _handle(0), + _is_connecting(false) { }; + + virtual ~SMDevice() + { + if (_ble.hasInitialized()) { + _ble.shutdown(); + } + }; + + /** Start BLE interface initialisation */ + void run() + { + ble_error_t error; + + /* to show we're running we'll blink every 500ms */ + _event_queue.call_every(500, this, &SMDevice::blink); + + if (_ble.hasInitialized()) { + printf("Ble instance already initialised.\r\n"); + return; + } + + /* this will inform us off all events so we can schedule their handling + * using our event queue */ + _ble.onEventsToProcess( + makeFunctionPointer(this, &SMDevice::schedule_ble_events) + ); + + /* handle timeouts, for example when connection attempts fail */ + _ble.gap().onTimeout( + makeFunctionPointer(this, &SMDevice::on_timeout) + ); + + error = _ble.init(this, &SMDevice::on_init_complete); + + if (error) { + printf("Error returned by BLE::init.\r\n"); + return; + } + + /* this will not return until shutdown */ + _event_queue.dispatch_forever(); + }; + + /* event handler functions */ + + /** Respond to a pairing request. This will be called by the stack + * when a pairing request arrives and expects the application to + * call acceptPairingRequest or cancelPairingRequest */ + virtual void pairingRequest( + ble::connection_handle_t connectionHandle + ) { + printf("Pairing requested. Authorising.\r\n"); + _ble.securityManager().acceptPairingRequest(connectionHandle); + } + + /** Inform the application of a successful pairing. Terminate the demonstration. */ + virtual void pairingResult( + ble::connection_handle_t connectionHandle, + SecurityManager::SecurityCompletionStatus_t result + ) { + if (result == SecurityManager::SEC_STATUS_SUCCESS) { + printf("Pairing successful\r\n"); + } else { + printf("Pairing failed\r\n"); + } + + /* disconnect in 500 ms */ + _event_queue.call_in( + 500, &_ble.gap(), + &Gap::disconnect, _handle, Gap::REMOTE_USER_TERMINATED_CONNECTION + ); + } + + /** Inform the application of change in encryption status. This will be + * communicated through the serial port */ + virtual void linkEncryptionResult( + ble::connection_handle_t connectionHandle, + ble::link_encryption_t result + ) { + if (result == ble::link_encryption_t::ENCRYPTED) { + printf("Link ENCRYPTED\r\n"); + } else if (result == ble::link_encryption_t::ENCRYPTED_WITH_MITM) { + printf("Link ENCRYPTED_WITH_MITM\r\n"); + } else if (result == ble::link_encryption_t::NOT_ENCRYPTED) { + printf("Link NOT_ENCRYPTED\r\n"); + } + } + +private: + /** Override to start chosen activity when initialisation completes */ + virtual void start() = 0; + + /** This is called when BLE interface is initialised and starts the demonstration */ + void on_init_complete(BLE::InitializationCompleteCallbackContext *event) + { + ble_error_t error; + + if (event->error) { + printf("Error during the initialisation\r\n"); + return; + } + + /* If the security manager is required this needs to be called before any + * calls to the Security manager happen. */ + error = _ble.securityManager().init(); + + if (error) { + printf("Error during init %d\r\n", error); + return; + } + + /* Tell the security manager to use methods in this class to inform us + * of any events. Class needs to implement SecurityManagerEventHandler. */ + _ble.securityManager().setSecurityManagerEventHandler(this); + + /* print device address */ + Gap::AddressType_t addr_type; + Gap::Address_t addr; + _ble.gap().getAddress(&addr_type, addr); + printf("Device address: %02x:%02x:%02x:%02x:%02x:%02x\r\n", + addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + + /* when scanning we want to connect to a peer device so we need to + * attach callbacks that are used by Gap to notify us of events */ + _ble.gap().onConnection(this, &SMDevice::on_connect); + _ble.gap().onDisconnection(this, &SMDevice::on_disconnect); + + /* start test in 500 ms */ + _event_queue.call_in(500, this, &SMDevice::start); + }; + + /** This is called by Gap to notify the application we connected */ + virtual void on_connect(const Gap::ConnectionCallbackParams_t *connection_event) = 0; + + /** This is called by Gap to notify the application we disconnected, + * in our case it ends the demonstration. */ + void on_disconnect(const Gap::DisconnectionCallbackParams_t *event) + { + printf("Disconnected - demonstration ended \r\n"); + _event_queue.break_dispatch(); + }; + + /** End demonstration unexpectedly. Called if timeout is reached during advertising, + * scanning or connection initiation */ + void on_timeout(const Gap::TimeoutSource_t source) + { + printf("Unexpected timeout - aborting \r\n"); + _event_queue.break_dispatch(); + }; + + /** Schedule processing of events from the BLE in the event queue. */ + void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) + { + _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents)); + }; + + /** Blink LED to show we're running */ + void blink(void) + { + _led1 = !_led1; + }; + +private: + DigitalOut _led1; + +protected: + BLE &_ble; + events::EventQueue &_event_queue; + BLEProtocol::AddressBytes_t &_peer_address; + ble::connection_handle_t _handle; + bool _is_connecting; +}; + +/** A peripheral device will advertise, accept the connection and request + * a change in link security. */ +class SMDevicePeripheral : public SMDevice { +public: + SMDevicePeripheral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) + : SMDevice(ble, event_queue, peer_address) { } + + virtual void start() + { + /* Set up and start advertising */ + + ble_error_t error; + GapAdvertisingData advertising_data; + + /* add advertising flags */ + advertising_data.addFlags(GapAdvertisingData::LE_GENERAL_DISCOVERABLE + | GapAdvertisingData::BREDR_NOT_SUPPORTED); + + /* add device name */ + advertising_data.addData( + GapAdvertisingData::COMPLETE_LOCAL_NAME, + DEVICE_NAME, + sizeof(DEVICE_NAME) + ); + + error = _ble.gap().setAdvertisingPayload(advertising_data); + + if (error) { + printf("Error during Gap::setAdvertisingPayload\r\n"); + return; + } + + /* advertise to everyone */ + _ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + /* how many milliseconds between advertisements, lower interval + * increases the chances of being seen at the cost of more power */ + _ble.gap().setAdvertisingInterval(20); + _ble.gap().setAdvertisingTimeout(0); + + error = _ble.gap().startAdvertising(); + + if (error) { + printf("Error during Gap::startAdvertising.\r\n"); + return; + } + + /** This tells the stack to generate a pairingRequest event + * which will require this application to respond before pairing + * can proceed. Setting it to false will automatically accept + * pairing. */ + _ble.securityManager().setPairingRequestAuthorisation(true); + }; + + /** This is called by Gap to notify the application we connected, + * in our case it immediately requests a change in link security */ + virtual void on_connect(const Gap::ConnectionCallbackParams_t *connection_event) + { + ble_error_t error; + + /* remember the device that connects to us now so we can connect to it + * during the next demonstration */ + memcpy(_peer_address, connection_event->peerAddr, sizeof(_peer_address)); + + /* store the handle for future Security Manager requests */ + _handle = connection_event->handle; + + /* Request a change in link security. This will be done + * indirectly by asking the master of the connection to + * change it. Depending on circumstances different actions + * may be taken by the master which will trigger events + * which the applications should deal with. */ + error = _ble.securityManager().setLinkSecurity( + _handle, + SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM + ); + + if (error) { + printf("Error during SM::setLinkSecurity %d\r\n", error); + return; + } + }; +}; + +/** A central device will scan, connect to a peer and request pairing. */ +class SMDeviceCentral : public SMDevice { +public: + SMDeviceCentral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) + : SMDevice(ble, event_queue, peer_address) { } + + virtual void start() + { + /* start scanning and attach a callback that will handle advertisements + * and scan requests responses */ + ble_error_t error = _ble.gap().startScan(this, &SMDeviceCentral::on_scan); + + if (error) { + printf("Error during Gap::startScan %d\r\n", error); + return; + } + } + + /** Look at scan payload to find a peer device and connect to it */ + void on_scan(const Gap::AdvertisementCallbackParams_t *params) + { + /* don't bother with analysing scan result if we're already connecting */ + if (_is_connecting) { + return; + } + + /* parse the advertising payload, looking for a discoverable device */ + for (uint8_t i = 0; i < params->advertisingDataLen; ++i) { + /* The advertising payload is a collection of key/value records where + * byte 0: length of the record excluding this byte + * byte 1: The key, it is the type of the data + * byte [2..N] The value. N is equal to byte0 - 1 */ + const uint8_t record_length = params->advertisingData[i]; + if (record_length == 0) { + continue; + } + + /* connect to the same device that connected to us */ + if (memcmp(params->peerAddr, _peer_address, sizeof(_peer_address)) == 0) { + + ble_error_t error = _ble.gap().connect( + params->peerAddr, params->addressType, + NULL, NULL + ); + + if (error) { + printf("Error during Gap::connect %d\r\n", error); + return; + } + + /* we may have already scan events waiting + * to be processed so we need to remember + * that we are already connecting and ignore them */ + _is_connecting = true; + + return; + } + + i += record_length; + } + }; + + /** This is called by Gap to notify the application we connected, + * in our case it immediately request pairing */ + virtual void on_connect(const Gap::ConnectionCallbackParams_t *connection_event) + { + ble_error_t error; + + /* store the handle for future Security Manager requests */ + _handle = connection_event->handle; + + /* in this example the local device is the master so we request pairing */ + error = _ble.securityManager().requestPairing(_handle); + + if (error) { + printf("Error during SM::requestPairing %d\r\n", error); + return; + } + + /* upon pairing success the application will disconnect */ + }; +}; + +int main() +{ + BLE& ble = BLE::Instance(); + events::EventQueue queue; + + { + printf("\r\n PERIPHERAL \r\n\r\n"); + SMDevicePeripheral peripheral(ble, queue, peer_address); + peripheral.run(); + } + + { + printf("\r\n CENTRAL \r\n\r\n"); + SMDeviceCentral central(ble, queue, peer_address); + central.run(); + } + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/.mbed Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +ROOT=.
Binary file mbed-os-example-ble-master/BLE_Thermometer/img/connection.png has changed
Binary file mbed-os-example-ble-master/BLE_Thermometer/img/discovery.png has changed
Binary file mbed-os-example-ble-master/BLE_Thermometer/img/notifications.png has changed
Binary file mbed-os-example-ble-master/BLE_Thermometer/img/register_to_notifications.png has changed
Binary file mbed-os-example-ble-master/BLE_Thermometer/img/scan_results.png has changed
Binary file mbed-os-example-ble-master/BLE_Thermometer/img/start_scan.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/mbed-os.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/mbed_app.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "target_overrides": { + "K64F": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "NUCLEO_F401RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "DISCO_L475VG_IOT01A": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,15 @@ +{ + "name": "ble-thermometer", + "version": "0.0.1", + "description": "This example demonstrates how to use the Health Thermometer Service. The Health Thermometer service reports two pieces of information, Temperature and Sensor Location.", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "dependencies": { + "ble": "^2.0.0" + }, + "bin": "./source" +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/readme.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,80 @@ +# Thermometer + +This example uses the [Health Thermometer Profile](https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.health_thermometer.xml) to send thermometer information: + +1. Sensor location: thermometer placement on the body. The default value in this application is the ear (``LOCATION_EAR``). The [characteristic description](https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml) shows the other possible values. + +1. Temperature: the initial temperature is 39.6, and it's incremented by 0.1 every half second. It resets to 39.6 when it reaches 43.0. + +For more information see: + +* [Temperature Service](https://developer.bluetooth.org/gatt/profiles/Pages/ProfileViewer.aspx?u=org.bluetooth.profile.health_thermometer.xml): GATT profile details. + +* [Temperature Measurement](https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml): GATT characteristic details for temperature measurement. + +* [Temperature Type](https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml): GATT characteristic details for temperature type (sensor location). + +# Running the application + +## Requirements + +The sample application can be seen on any BLE scanner on a smartphone. If you don't have a scanner on your phone, please install : + +- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android. + +- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone. + +Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Building instructions + +Building instructions for all mbed OS samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md). + +## Checking for success + +**Note:** Screens captures depicted below show what is expected from this example if the scanner used is *nRF Master Control Panel* version 4.0.5. If you encounter any difficulties consider trying another scanner or another version of nRF Master Control Panel. Alternative scanners may require reference to their manuals. + +1. Build the application and install it on your board as explained in the building instructions. + +1. Open the BLE scanner on your phone. + +1. Start a scan. + +  + + **figure 1** How to start scan using nRF Master Control Panel 4.0.5 + +1. Find your device; it should be named *Therm*. + +  + + **figure 2** Scan results using nRF Master Control Panel 4.0.5 + +1. Establish a connection with your device. + +  + + **figure 3** How to establish a connection using Master Control Panel 4.0.5 + + +1. Discover the services and the characteristics on the device. The *Health Thermometer* service has the UUID `0x1809` and includes the *Temperature Measurement* characteristic which has the UUID `0x2A1C`. + +  + + **figure 4** Representation of the Thermometer service using Master Control Panel 4.0.5 + + +1. Register for the notifications sent by the *Temperature Measurement* characteristic. + +  + + **figure 5** How to register to notifications using Master Control Panel 4.0.5 + + +1. You should see the temperature value change every half second. It begins at 39.6, goes up to 43.0 (in steps of 0.1), resets to 39.6 and so on. + +  + + **figure 6** Notifications view using Master Control Panel 4.0.5 + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG.lib Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/#b630517008bbe47592927cc8e5dfcd2e5b9de968
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/.gitignore Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,9 @@ +# vim temporary files +*.sw* + +# yotta files +build +yotta_modules +yotta_targets +.yotta.json +upload.tar.gz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,34 @@ +# BLE-X-NUCLEO-IDB0XA1 + +BLE_API wrapper Library for X-NUCLEO-IDB05A1 BlueNRG (Bluetooth Low Energy) Expansion Board + +## Introduction + +This firmware package implements the port of BLE_API to STMicroelectronics' [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) Bluetooth Low Energy Nucleo Expansion Board. + +### Arduino Connector Compatibility Warning + +X-NUCLEO-IDB05A1 is Arduino compatible with an exception: instead of using pin **D13** for the SPI clock, pin **D3** is used. +The default configuration for this library is having the SPI clock on pin **D3**. + +To be fully Arduino compatible, X-NUCLEO-IDB05A1 needs a small HW patch. + +For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor **R4** and instead soldering zero resistor **R6**. + +In case you patch your board, then you also have to configure this library to use pin **D13** to drive the SPI clock. To this aim you need to compile this driver with macro `BLUENRG_PIN_SPI_SCK=D13` defined. + +If you use pin **D13** for the SPI clock, please be aware that on STM32 Nucleo boards you may **not** drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin **D13**. + +Referring to the current list of tested platforms (see [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) page), the patch is required by [ST-Nucleo-F103RB](https://developer.mbed.org/platforms/ST-Nucleo-F103RB/); [ST-Nucleo-F302R8](https://developer.mbed.org/platforms/ST-Nucleo-F302R8/); [ST-Nucleo-F411RE](https://developer.mbed.org/platforms/ST-Nucleo-F411RE/); [ST-Nucleo-F446RE](https://developer.mbed.org/platforms/ST-Nucleo-F446RE/); and [FRDM-K64F](https://developer.mbed.org/platforms/FRDM-K64F/). + +### Firmware update + +For better performance and compatibility with latest mbed API, you should update firmware of X-NUCLEO-IDB05A1 component by using this simple [application](https://developer.mbed.org/teams/ST/code/BlueNRG-MS-Stack-Updater). + +### Driver configuration + +In order to use the BlueNRG-MS module together with other targets, you need to set the macros defined in file [bluenrg_targets.h](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/bluenrg/bluenrg_targets.h). Please, update the [mbed_lib.json](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/mbed_lib.json) to include the list of extra macros that configure the driver for your target. + +## Example Applications + +To run BLE example applications using X-NUCLEO-IDB05A1 Expansion Board based on mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli), please refer to section [Using ST shield on other targets](https://github.com/ARMmbed/mbed-os-example-ble#using-st-nucleo-shield-on-other-targets) in the official [mbed-os-example-ble](https://github.com/ARMmbed/mbed-os-example-ble) page.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.h + * @author STMicroelectronics + * @brief Header file for BLEDeviceInstanceBase based BlueNRGDevice + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_DEVICE_H__ +#define __BLUENRG_DEVICE_H__ + +#define BLUENRG +#define DEBUG_BLUENRG_USER + +#include "btle.h" + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "ble/BLEInstanceBase.h" +#include "ble/BLE.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" + + +class BlueNRGDevice : public BLEInstanceBase +{ + +public: + BlueNRGDevice(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rst, PinName irq); + virtual ~BlueNRGDevice(void); + + virtual ble_error_t init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback); + virtual ble_error_t shutdown(void); + virtual const char *getVersion(void); + virtual Gap& getGap(); + virtual const Gap& getGap() const; + virtual GattServer& getGattServer(); + virtual const GattServer& getGattServer() const; + virtual void waitForEvent(void); + + virtual GattClient& getGattClient() { + return BlueNRGGattClient::getInstance(); + } + + virtual SecurityManager& getSecurityManager() { + return *sm; + } + + virtual const SecurityManager& getSecurityManager() const { + return *sm; + } + void reset(void); + virtual bool hasInitialized(void) const { + return isInitialized; + } + + uint8_t getUpdaterHardwareVersion(uint8_t *hw_version); + int updateFirmware(const uint8_t *fw_image, uint32_t fw_size); + bool dataPresent(); + int32_t spiRead(uint8_t *buffer, uint8_t buff_size); + int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2); + void disable_irq(); + void enable_irq(); + + virtual void processEvents(); + +private: + bool isInitialized; + + SPI spi_; + DigitalOut nCS_; + DigitalOut rst_; + InterruptIn irq_; + + //FIXME: TBI (by now just placeholders to let build + /*** betzw: placeholders ***/ + SecurityManager *sm; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ +#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ + +#include "ble/DiscoveredCharacteristic.h" + +class BlueNRGGattClient; /* forward declaration */ + +class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic { +public: + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + + void setLastHandle(GattAttribute::Handle_t lastHandleIn); +}; + +#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGGap.h + * @author STMicroelectronics + * @brief Header file for BlueNRG BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GAP_H__ +#define __BLUENRG_GAP_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/Gap.h" + +#define BLE_CONN_HANDLE_INVALID 0x0 +#define BDADDR_SIZE 6 + +#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020) +#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000) +#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0) + +// Scanning and Connection Params used by Central for creating connection +#define GAP_OBSERVATION_PROC (0x80) + +#define SCAN_P (0x0010) +#define SCAN_L (0x0010) +#define SUPERV_TIMEOUT (0xC80) +#define CONN_P(x) ((int)((x)/1.25f)) +#define CONN_L(x) ((int)((x)/0.625f)) +#define CONN_P1 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_P2 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C) +#define CONN_L1 (0x0008) +#define CONN_L2 (0x0008) +#define GUARD_INT 5 //msec +#define MIN_INT_CONN 0x0006 //=>7.5msec +#define MAX_INT_CONN 0x0C80 //=>4000msec +#define DEF_INT_CONN 0x0140 //=>400msec (default value for connection interval) + +/**************************************************************************/ +/*! + \brief + +*/ +/**************************************************************************/ +class BlueNRGGap : public Gap +{ +public: + static BlueNRGGap &getInstance() { + static BlueNRGGap m_instance; + return m_instance; + } + + enum Reason_t { + DEVICE_FOUND, + DISCOVERY_COMPLETE + }; + + /* Functions that must be implemented from Gap */ + virtual ble_error_t setAddress(addr_type_t type, const BLEProtocol::AddressBytes_t address); + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address); + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &); + virtual ble_error_t startAdvertising(const GapAdvertisingParams &); + virtual ble_error_t stopAdvertising(void); + virtual ble_error_t stopScan(); + virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);} + virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);} + virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);} + virtual ble_error_t disconnect(DisconnectionReason_t reason); + virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason); + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params); + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); + + virtual ble_error_t setDeviceName(const uint8_t *deviceName); + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); + virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance); + virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP); + + virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode); + virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode); + virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const; + virtual ScanningPolicyMode_t getScanningPolicyMode(void) const; + + virtual ble_error_t setTxPower(int8_t txPower); + virtual void getPermittedTxPowerValues(const int8_t **, size_t *); + + virtual ble_error_t connect(const Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams); + + virtual ble_error_t reset(void); + + void Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI); + ble_error_t createConnection(void); + + void setConnectionHandle(uint16_t con_handle); + uint16_t getConnectionHandle(void); + + bool getIsSetAddress(); + + // ADV timeout handling + Timeout& getAdvTimeout(void) { + return advTimeout; + } + uint8_t getAdvToFlag(void) { + return AdvToFlag; + } + void setAdvToFlag(void); + + // SCAN timeout handling + Timeout& getScanTimeout(void) { + return scanTimeout; + } + uint8_t getScanToFlag(void) { + return ScanToFlag; + } + void setScanToFlag(void); + + void Process(void); + + GapScanningParams* getScanningParams(void); + + virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams); + + void setConnectionInterval(uint16_t interval); + Gap::Role_t getGapRole(void); + void setGapRole(Gap::Role_t role); + +private: + uint16_t m_connectionHandle; + Role_t gapRole; + AddressType_t addr_type; + Address_t _peerAddr; + AddressType_t _peerAddrType; + uint8_t bdaddr[BDADDR_SIZE]; + bool _scanning; + bool _connecting; + bool isSetAddress; + uint8_t deviceAppearance[2]; + + // ADV timeout handling + Timeout advTimeout; + bool AdvToFlag; + + // SCAN timeout handling + Timeout scanTimeout; + bool ScanToFlag; + + static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) { + return (duration * 625) / 1000; + } + + uint16_t scanInterval; + uint16_t scanWindow; + uint16_t advInterval; + uint16_t slaveConnIntervMin; + uint16_t slaveConnIntervMax; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + void setAdvParameters(void); + void setConnectionParameters(void); + + Gap::AdvertisingPolicyMode_t advertisingPolicyMode; + Gap::ScanningPolicyMode_t scanningPolicyMode; + + Whitelist_t whitelistAddresses; + + ble_error_t updateAdvertisingData(void); + + BlueNRGGap() : AdvToFlag(false), ScanToFlag(false) { + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + addr_type = BLEProtocol::AddressType::RANDOM_STATIC; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + isSetAddress = false; + memset(deviceAppearance, 0, sizeof(deviceAppearance)); + } + + BlueNRGGap(BlueNRGGap const &); + void operator=(BlueNRGGap const &); + + GapAdvertisingData _advData; + GapAdvertisingData _scanResponse; +}; + +#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,157 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattClient.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CLIENT_H__ +#define __BLUENRG_GATT_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattConnectionClient.h" + +using namespace std; + +#define MAX_ACTIVE_CONNECTIONS 7 + +class BlueNRGGattClient : public GattClient +{ +public: + static BlueNRGGattClient &getInstance() { + static BlueNRGGattClient m_instance; + return m_instance; + } + + ble_error_t createGattConnectionClient(Gap::Handle_t connectionHandle); + ble_error_t removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason); + + /* Functions that must be implemented from GattClient */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + virtual bool isServiceDiscoveryActive(void) const; + virtual void terminateServiceDiscovery(void); + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback); + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + virtual ble_error_t write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + virtual ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + virtual ble_error_t reset(void); + + void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code); + + void primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(Gap::Handle_t connectionHandle); + + void serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length); + + +protected: + + BlueNRGGattClient(): _connectionPool() {}; + + ServiceDiscovery::TerminationCallback_t terminationCallback; + +private: + + BlueNRGGattClient(BlueNRGGattClient const &); + void operator=(BlueNRGGattClient const &); + + BlueNRGGattConnectionClient *_connectionPool[MAX_ACTIVE_CONNECTIONS]; + uint8_t _numConnections; + + BlueNRGGattConnectionClient * getGattConnectionClient(Gap::Handle_t connectionHandle); + +}; + +#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,185 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattConnectionClient.cpp + * @author STMicroelectronics + * @brief Header file for BlueNRGGattConnectionClient Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_CONNECTION_CLIENT_H__ +#define __BLUENRG_GATT_CONNECTION_CLIENT_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattClient.h" +#include "ble/DiscoveredService.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "BlueNRGDiscoveredCharacteristic.h" + +using namespace std; + +#define BLE_TOTAL_DISCOVERED_SERVICES 10 +#define BLE_TOTAL_DISCOVERED_CHARS 10 + +class BlueNRGGattConnectionClient +{ +public: + + enum { + GATT_IDLE, + GATT_SERVICE_DISCOVERY, + GATT_CHAR_DESC_DISCOVERY, + //GATT_CHARS_DISCOVERY_COMPLETE, + //GATT_DISCOVERY_TERMINATED, + GATT_READ_CHAR, + GATT_WRITE_CHAR + }; + + /* Functions that must be implemented from GattClient */ + ble_error_t launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + ble_error_t discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle); + + bool isServiceDiscoveryActive(void) const; + void terminateServiceDiscovery(void); + void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + } + ble_error_t read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const; + ble_error_t write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const; + ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback); + + ble_error_t reset(void); + + void gattProcedureCompleteCB(uint8_t error_code); + + void primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list); + + void primaryServiceCB(uint8_t event_data_length, + uint8_t *handles_info_list); + + ble_error_t findServiceChars(void); + + void serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair); + + void serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value); + + void discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair); + + void charReadCB(uint8_t event_data_length, + uint8_t* attribute_value); + + void charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value); + + void charWriteExecCB(uint8_t event_data_length); + +protected: + + BlueNRGGattConnectionClient(BlueNRGGattClient *gattClient, Gap::Handle_t connectionHandle): + discoveredService(), + discoveredChar(), + readCBParams(), + writeCBParams(), + _characteristic() { + + //PRINTF("BlueNRGGattConnectionClient construtor: connHandle=%d\n\r", connectionHandle); + + _gattClient = gattClient; + _connectionHandle = connectionHandle; + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + } + + ServiceDiscovery::ServiceCallback_t serviceDiscoveryCallback; + ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback; + ServiceDiscovery::TerminationCallback_t terminationCallback; + CharacteristicDescriptorDiscovery::DiscoveryCallback_t charDescDiscoveryCallback; + CharacteristicDescriptorDiscovery::TerminationCallback_t charDescTerminationCallback; + +private: + + BlueNRGGattConnectionClient(BlueNRGGattConnectionClient const &); + void operator=(BlueNRGGattConnectionClient const &); + ~BlueNRGGattConnectionClient() {}; + + BlueNRGGattClient *_gattClient; + + Gap::Handle_t _connectionHandle; + DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES]; + BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS]; + + GattReadCallbackParams readCBParams; + GattWriteCallbackParams writeCBParams; + + // The char for which the descriptor discovery has been launched + DiscoveredCharacteristic _characteristic; + + UUID _matchingServiceUUID; + UUID _matchingCharacteristicUUIDIn; + uint8_t _currentState; + uint8_t _numServices, _servIndex; + uint8_t _numChars; + uint8_t _numCharDesc; + + friend class BlueNRGGattClient; +}; + +#endif /* __BLUENRG_GATT_CONNECTION_CLIENT_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Header file for BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#ifndef __BLUENRG_GATT_SERVER_H__ +#define __BLUENRG_GATT_SERVER_H__ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble/blecommon.h" +#include "btle.h" +#include "ble/GattService.h" +#include "ble/GattServer.h" +#include <vector> +#include <map> + +#define BLE_TOTAL_CHARACTERISTICS 10 + +using namespace std; + +class BlueNRGGattServer : public GattServer +{ +public: + static BlueNRGGattServer &getInstance() { + static BlueNRGGattServer m_instance; + return m_instance; + } + + enum HandleEnum_t { + CHAR_HANDLE = 0, + CHAR_VALUE_HANDLE, + CHAR_DESC_HANDLE + }; + + /* Functions that must be implemented from GattServer */ + virtual ble_error_t addService(GattService &); + virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); + virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); + virtual ble_error_t initializeGATTDatabase(void); + + virtual bool isOnDataReadAvailable() const { + return true; + } + + virtual ble_error_t reset(void); + + /* BlueNRG Functions */ + void eventCallback(void); + //void hwCallback(void *pckt); + ble_error_t Read_Request_CB(uint16_t attributeHandle); + uint8_t Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, + uint8_t data_length, const uint8_t* data + ); + GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle); + void HCIDataWrittenEvent(const GattWriteCallbackParams *params); + void HCIDataReadEvent(const GattReadCallbackParams *params); + void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle); + void HCIDataSentEvent(unsigned count); + +private: + + // compute the number of attribute record needed by a service + static uint16_t computeAttributesRecord(GattService& service); + + + static const int MAX_SERVICE_COUNT = 10; + uint8_t serviceCount; + uint8_t characteristicCount; + uint16_t servHandle, charHandle; + + std::map<uint16_t, uint16_t> bleCharHandleMap; // 1st argument is characteristic, 2nd argument is service + GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS]; + uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS]; + + BlueNRGGattServer() { + serviceCount = 0; + characteristicCount = 0; + }; + + BlueNRGGattServer(BlueNRGGattServer const &); + void operator=(BlueNRGGattServer const &); + + static const int CHAR_DESC_TYPE_16_BIT=0x01; + static const int CHAR_DESC_TYPE_128_BIT=0x02; + static const int CHAR_DESC_SECURITY_PERMISSION=0x00; + static const int CHAR_DESC_ACCESS_PERMISSION=0x03; + static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_CLOCK_H__ +#define __BLE_CLOCK_H__ + +#include <ble_hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __BLE_CLOCK_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file ble_debug.h + * @author CL + * @version V1.0.0 + * @date 04-July-2014 + * @brief This file defines print functions for debug purposes. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLE_DEBUG_H +#define __BLE_DEBUG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> + +/* Exported macro ------------------------------------------------------------*/ +//#define DEBUG +#ifdef DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Print the data travelling over the SPI in the .csv format for the GUI*/ +//#define PRINT_CSV_FORMAT +#ifdef PRINT_CSV_FORMAT +#include <stdio.h> +#define PRINT_CSV(...) printf(__VA_ARGS__) +#else +#define PRINT_CSV(...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __BLE_DEBUG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_gp_timer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : General purpose timer library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_GP_TIMER_H__ +#define __BLE_GP_TIMER_H__ + +#include "ble_clock.h" +#include "ble_status.h" +#ifdef __DMA_LP__ +#include "stm32xx_timerserver.h" +#endif /* __DMA_LP__ */ + +/** + * timer + * + * A structure that represents a timer. Use Timer_Set() to set the timer. + * + */ +struct timer { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + tClockTime start; + tClockTime interval; + +#endif +}; + +typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); + +/** + * Timer_Set + * + * @param[in] t Pointer to a timer structure + * @param[in] interval timeout value + * + * This function sets the timeout value of a timer. + * + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * Timer_Reset + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the time it previously expired. + * + */ +void Timer_Reset(struct timer *t); + +/** + * Timer_Restart + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the current time. + * + */ +void Timer_Restart(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns TRUE if timer is expired, FALSE otherwise. + * + */ +int Timer_Expired(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns the time needed for expiration. + * + * @return Time before timer's expiration. + */ +tClockTime Timer_Remaining(struct timer *t); + +#ifdef __DMA_LP__ +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID); + +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); +#endif /* __DMA_LP__ */ + +#endif /* __BLE_GP_TIMER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,108 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_H__ +#define __BLE_HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void signalEventsToProcess(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __BLE_HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_TYPES_H__ +#define __BLE_HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __BLE_HAL_TYPES_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,126 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.0, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_H_ +#define __BLE_HCI_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ble_hal_types.h" +#include "ble_link_layer.h" +#include <ble_list.h> + +#define HCI_READ_PACKET_SIZE 128 //71 + +/** + * Maximum payload of HCI commands that can be sent. Change this value if needed. + * This value can be up to 255. + */ +#define HCI_MAX_PAYLOAD_SIZE 128 + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_READ_PACKET_SIZE]; + uint8_t data_len; +} tHciDataPacket; + +struct hci_request { + uint16_t ogf; + uint16_t ocf; + int event; + void *cparam; + int clen; + void *rparam; + int rlen; +}; + +typedef enum +{ + BUSY, + AVAILABLE +} HCI_CMD_STATUS_t; + + +/** + * This function must be used to pass the packet received from the HCI + * interface to the BLE Stack HCI state machine. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * + */ +void HCI_Input(tHciDataPacket *hciReadPacket); + +/** + * Initialization function. Must be done before any data can be received from + * BLE controller. + */ +void HCI_Init(void); + +/** + * Callback used to pass events to application. + * + * @param[in] pckt The event. + * + */ +extern void HCI_Event_CB(void *pckt); + +/** + * Processing function that must be called after an event is received from + * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if + * necessary. +*/ +void HCI_Process(void); + +/** + * @brief Check if queue of HCI event is empty or not. + * @note This funtion can be used to check if the event queue from BlueNRG is empty. This + * is useful when checking if it is safe to go to sleep. + * @return TRUE if event queue is empty. FALSE otherwhise. + */ +BOOL HCI_Queue_Empty(void); +/** + * Iterrupt service routine that must be called when the BlueNRG + * reports a packet received or an event to the host through the + * BlueNRG interrupt line. + */ +#ifdef __DMA_LP__ +void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); +void HCI_Process_Notification_Request(void); +void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); +void HCI_Wait_For_Response(void); +#else +void HCI_Isr(void); +void HCI_HandleSPI(void); + +int hci_send_req(struct hci_request *r, BOOL async); +#endif /* __DMA_LP__ */ + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#ifdef __cplusplus +} +#endif + + +#endif /* __BLE_HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,548 @@ +/****************************************************************************** +* +* File Description +* --------------------- +* This file defines constants and functions for HCI layer. +* See Bluetooth Core v 4.0, Vol. 2, Part E. +* +*******************************************************************************/ + +#ifndef __HCI_INTERNAL_H_ +#define __HCI_INTERNAL_H_ + +#include "ble_compiler.h" +#include "ble_hal_types.h" +#include "ble_clock.h" +#include "ble_link_layer.h" +#include "ble_hci.h" + +#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) + + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +typedef __packed struct _hci_uart_pckt{ + uint8_t type; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef __packed struct _hci_command_hdr{ + uint16_t opcode; /* OCF & OGF */ + uint8_t plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef __packed struct _hci_event_pckt{ + uint8_t evt; + uint8_t plen; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef __packed struct _hci_acl_hdr{ + uint16_t handle; /* Handle & Flags(PB, BC) */ + uint16_t dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef __packed struct _disconnect_cp{ + uint16_t handle; + uint8_t reason; +} PACKED disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 + +#define OCF_SET_EVENT_MASK 0x0001 +#define OCF_RESET 0x0003 + +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D +typedef __packed struct _read_transmit_power_level_cp{ + uint16_t handle; + uint8_t type; +} PACKED read_transmit_power_level_cp; +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 +typedef __packed struct _read_transmit_power_level_rp{ + uint8_t status; + uint16_t handle; + int8_t level; +} PACKED read_transmit_power_level_rp; +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 + +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 +#define OCF_HOST_BUFFER_SIZE 0x0033 +#define OCF_HOST_NUM_COMP_PKTS 0x0035 + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef __packed struct _read_local_version_rp{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t manufacturer_name; + uint16_t lmp_pal_subversion; +} PACKED read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_COMMANDS 0x0002 +#define OCF_READ_LOCAL_FEATURES 0x0003 + +#define OCF_READ_BD_ADDR 0x0009 +typedef __packed struct _read_bd_addr_rp{ + uint8_t status; + tBDAddr bdaddr; +} PACKED read_bd_addr_rp; +#define READ_BD_ADDR_RP_SIZE 7 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +#define OCF_READ_RSSI 0x0005 +typedef __packed struct _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef __packed struct _read_rssi_rp{ + uint8_t status; + uint16_t handle; + int8_t rssi; +} PACKED read_rssi_rp; +#define READ_RSSI_RP_SIZE 4 + + +/* LE commands */ +#define OGF_LE_CTL 0x08 + +#define OCF_LE_SET_EVENT_MASK 0x0001 +typedef __packed struct _le_set_event_mask_cp{ + uint8_t mask[8]; +} PACKED le_set_event_mask_cp; +#define LE_SET_EVENT_MASK_CP_SIZE 8 + +#define OCF_LE_READ_BUFFER_SIZE 0x0002 +typedef __packed struct _le_read_buffer_size_rp{ + uint8_t status; + uint16_t pkt_len; + uint8_t max_pkt; +} PACKED le_read_buffer_size_rp; +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 + +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 +typedef __packed struct _le_read_local_supported_features_rp{ + uint8_t status; + uint8_t features[8]; +} PACKED le_read_local_supported_features_rp; +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 + +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 +typedef __packed struct _le_set_random_address_cp{ + tBDAddr bdaddr; +} PACKED le_set_random_address_cp; +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 + +#define OCF_LE_SET_ADV_PARAMETERS 0x0006 +typedef __packed struct _le_set_adv_parameters_cp{ + uint16_t min_interval; + uint16_t max_interval; + uint8_t advtype; + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint8_t chan_map; + uint8_t filter; +} PACKED le_set_adv_parameters_cp; +#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 + +#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 +typedef __packed struct _le_read_adv_channel_tx_power_rp{ + uint8_t status; + int8_t level; +} PACKED le_read_adv_channel_tx_power_rp; +#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 + +#define OCF_LE_SET_ADV_DATA 0x0008 +typedef __packed struct _le_set_adv_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_adv_data_cp; +#define LE_SET_ADV_DATA_CP_SIZE 32 + +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 +typedef __packed struct _le_set_scan_response_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_scan_response_data_cp; +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 + +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A +typedef __packed struct _le_set_advertise_enable_cp{ + uint8_t enable; +} PACKED le_set_advertise_enable_cp; +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 + +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B +typedef __packed struct _le_set_scan_parameters_cp{ + uint8_t type; + uint16_t interval; + uint16_t window; + uint8_t own_bdaddr_type; + uint8_t filter; +} PACKED le_set_scan_parameters_cp; +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 + +#define OCF_LE_SET_SCAN_ENABLE 0x000C +typedef __packed struct _le_set_scan_enable_cp{ + uint8_t enable; + uint8_t filter_dup; +} PACKED le_set_scan_enable_cp; +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 + +#define OCF_LE_CREATE_CONN 0x000D +typedef __packed struct _le_create_connection_cp{ + uint16_t interval; + uint16_t window; + uint8_t initiator_filter; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_create_connection_cp; +#define LE_CREATE_CONN_CP_SIZE 25 + +#define OCF_LE_CREATE_CONN_CANCEL 0x000E + +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F +typedef __packed struct _le_read_white_list_size_rp{ + uint8_t status; + uint8_t size; +} PACKED le_read_white_list_size_rp; +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 + +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 +typedef __packed struct _le_add_device_to_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_add_device_to_white_list_cp; +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 +typedef __packed struct _le_remove_device_from_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_remove_device_from_white_list_cp; +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_CONN_UPDATE 0x0013 +typedef __packed struct _le_connection_update_cp{ + uint16_t handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_connection_update_cp; +#define LE_CONN_UPDATE_CP_SIZE 14 + +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 +typedef __packed struct _le_set_host_channel_classification_cp{ + uint8_t map[5]; +} PACKED le_set_host_channel_classification_cp; +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 + +#define OCF_LE_READ_CHANNEL_MAP 0x0015 +typedef __packed struct _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef __packed struct _le_read_channel_map_rp{ + uint8_t status; + uint16_t handle; + uint8_t map[5]; +} PACKED le_read_channel_map_rp; +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 + +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 +typedef __packed struct _le_read_remote_used_features_cp{ + uint16_t handle; +} PACKED le_read_remote_used_features_cp; +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 + +#define OCF_LE_ENCRYPT 0x0017 +typedef __packed struct _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef __packed struct _le_encrypt_rp{ + uint8_t status; + uint8_t encdata[16]; +} PACKED le_encrypt_rp; +#define LE_ENCRYPT_RP_SIZE 17 + +#define OCF_LE_RAND 0x0018 +typedef __packed struct _le_rand_rp{ + uint8_t status; + uint8_t random[8]; +} PACKED le_rand_rp; +#define LE_RAND_RP_SIZE 9 + +#define OCF_LE_START_ENCRYPTION 0x0019 +typedef __packed struct _le_start_encryption_cp{ + uint16_t handle; + uint8_t random[8]; + uint16_t diversifier; + uint8_t key[16]; +} PACKED le_start_encryption_cp; +#define LE_START_ENCRYPTION_CP_SIZE 28 + +#define OCF_LE_LTK_REPLY 0x001A +typedef __packed struct _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef __packed struct _le_ltk_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_reply_rp; +#define LE_LTK_REPLY_RP_SIZE 3 + +#define OCF_LE_LTK_NEG_REPLY 0x001B +typedef __packed struct _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef __packed struct _le_ltk_neg_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_neg_reply_rp; +#define LE_LTK_NEG_REPLY_RP_SIZE 3 + +#define OCF_LE_READ_SUPPORTED_STATES 0x001C +typedef __packed struct _le_read_supported_states_rp{ + uint8_t status; + uint8_t states[8]; +} PACKED le_read_supported_states_rp; +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 + +#define OCF_LE_RECEIVER_TEST 0x001D +typedef __packed struct _le_receiver_test_cp{ + uint8_t frequency; +} PACKED le_receiver_test_cp; +#define LE_RECEIVER_TEST_CP_SIZE 1 + +#define OCF_LE_TRANSMITTER_TEST 0x001E +typedef __packed struct _le_transmitter_test_cp{ + uint8_t frequency; + uint8_t length; + uint8_t payload; +} PACKED le_transmitter_test_cp; +#define LE_TRANSMITTER_TEST_CP_SIZE 3 + +#define OCF_LE_TEST_END 0x001F +typedef __packed struct _le_test_end_rp{ + uint8_t status; + uint16_t num_pkts; +} PACKED le_test_end_rp; +#define LE_TEST_END_RP_SIZE 3 + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3f + + +/*------------- Events -------------*/ +#define EVT_CONN_COMPLETE 0x03 +typedef __packed struct _evt_conn_complete{ + uint8_t status; + uint16_t handle; + tBDAddr bdaddr; + uint8_t link_type; + uint8_t encr_mode; +} PACKED evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef __packed struct _evt_disconn_complete{ + uint8_t status; + uint16_t handle; + uint8_t reason; +} PACKED evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef __packed struct _evt_encrypt_change{ + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} PACKED evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C + +#define EVT_CMD_COMPLETE 0x0E +typedef __packed struct _evt_cmd_complete{ + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef __packed struct _evt_cmd_status{ + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef __packed struct _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef __packed struct _evt_num_comp_pkts{ + uint8_t num_hndl; + /* variable length part */ +} PACKED evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +/* variable length part of evt_num_comp_pkts. */ +typedef __packed struct _evt_num_comp_pkts_param{ + uint16_t hndl; + uint16_t num_comp_pkts; +} PACKED evt_num_comp_pkts_param; +#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 + +#define EVT_DATA_BUFFER_OVERFLOW 0x1A +typedef __packed struct _evt_data_buffer_overflow{ + uint8_t link_type; +} PACKED evt_data_buffer_overflow; +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 + +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef __packed struct _evt_encryption_key_refresh_complete{ + uint8_t status; + uint16_t handle; +} PACKED evt_encryption_key_refresh_complete; +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 + +#define EVT_LE_META_EVENT 0x3E +typedef __packed struct _evt_le_meta_event{ + uint8_t subevent; + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef __packed struct _evt_le_connection_complete{ + uint8_t status; + uint16_t handle; + uint8_t role; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; +} PACKED evt_le_connection_complete; +#define EVT_LE_CONN_COMPLETE_SIZE 18 + +#define EVT_LE_ADVERTISING_REPORT 0x02 +typedef __packed struct _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t data_length; + uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef __packed struct _evt_le_connection_update_complete{ + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; +} PACKED evt_le_connection_update_complete; +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 + +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +typedef __packed struct _evt_le_read_remote_used_features_complete{ + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} PACKED evt_le_read_remote_used_features_complete; +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 + +#define EVT_LE_LTK_REQUEST 0x05 +typedef __packed struct _evt_le_long_term_key_request{ + uint16_t handle; + uint8_t random[8]; + uint16_t ediv; +} PACKED evt_le_long_term_key_request; +#define EVT_LE_LTK_REQUEST_SIZE 12 + +/** +* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, +* application can use @ref evt_blue_aci structure to parse the packet. +*/ +#define EVT_VENDOR 0xFF + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + + + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); + +typedef enum { + WAITING_TYPE, + WAITING_OPCODE1, + WAITING_OPCODE2, + WAITING_EVENT_CODE, + WAITING_HANDLE, + WAITING_HANDLE_FLAG, + WAITING_PARAM_LEN, + WAITING_DATA_LEN1, + WAITING_DATA_LEN2, + WAITING_PAYLOAD +}hci_state; + +typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); + +/* HCI library functions. */ + +int hci_send_req(struct hci_request *r, BOOL async); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,170 @@ +/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +* File Name : ble_hci_le.h +* Author : AMG RF FW team +* Version : V1.1.0 +* Date : 18-July-2016 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.1, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_LE_H_ +#define __BLE_HCI_LE_H_ + +#include "ble_hal_types.h" +#include "ble_link_layer.h" + +/** + * @defgroup HCI_Error_codes HCI Error codes + * @{ + */ +#define HCI_UNKNOWN_COMMAND 0x01 +#define HCI_NO_CONNECTION 0x02 +#define HCI_HARDWARE_FAILURE 0x03 +#define HCI_PAGE_TIMEOUT 0x04 +#define HCI_AUTHENTICATION_FAILURE 0x05 +#define HCI_PIN_OR_KEY_MISSING 0x06 +#define HCI_MEMORY_FULL 0x07 +#define HCI_CONNECTION_TIMEOUT 0x08 +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a +#define HCI_ACL_CONNECTION_EXISTS 0x0b +#define HCI_COMMAND_DISALLOWED 0x0c +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d +#define HCI_REJECTED_SECURITY 0x0e +#define HCI_REJECTED_PERSONAL 0x0f +#define HCI_HOST_TIMEOUT 0x10 +#define HCI_UNSUPPORTED_FEATURE 0x11 +#define HCI_INVALID_PARAMETERS 0x12 +#define HCI_OE_USER_ENDED_CONNECTION 0x13 +#define HCI_OE_LOW_RESOURCES 0x14 +#define HCI_OE_POWER_OFF 0x15 +#define HCI_CONNECTION_TERMINATED 0x16 +#define HCI_REPEATED_ATTEMPTS 0x17 +#define HCI_PAIRING_NOT_ALLOWED 0x18 +#define HCI_UNKNOWN_LMP_PDU 0x19 +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a +#define HCI_SCO_OFFSET_REJECTED 0x1b +#define HCI_SCO_INTERVAL_REJECTED 0x1c +#define HCI_AIR_MODE_REJECTED 0x1d +#define HCI_INVALID_LMP_PARAMETERS 0x1e +#define HCI_UNSPECIFIED_ERROR 0x1f +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 +#define HCI_UNIT_LINK_KEY_USED 0x26 +#define HCI_QOS_NOT_SUPPORTED 0x27 +#define HCI_INSTANT_PASSED 0x28 +#define HCI_PAIRING_NOT_SUPPORTED 0x29 +#define HCI_TRANSACTION_COLLISION 0x2a +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c +#define HCI_QOS_REJECTED 0x2d +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e +#define HCI_INSUFFICIENT_SECURITY 0x2f +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 +#define HCI_ROLE_SWITCH_PENDING 0x32 +#define HCI_SLOT_VIOLATION 0x34 +#define HCI_ROLE_SWITCH_FAILED 0x35 +#define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 +#define HCI_CONN_REJ_NO_CH_FOUND 0x39 +#define HCI_CONTROLLER_BUSY 0x3A +#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B +#define HCI_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_CONN_TERM_MIC_FAIL 0x3D +#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E +#define HCI_MAC_CONN_FAILED 0x3F +/** + * @} + */ + + +/* + * HCI library functions. + * Each function returns 0 in case of success, otherwise one of the error codes. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(uint8_t enable); + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter); + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter); + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); + +int hci_le_rand(uint8_t random_number[8]); + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); + +int hci_acl_data(const uint8_t * data, uint16_t len); + +int hci_le_set_random_address(tBDAddr bdaddr); + +int hci_read_bd_addr(tBDAddr bdaddr); + +int hci_le_read_white_list_size(uint8_t *size); + +int hci_le_clear_white_list(); + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); + +int hci_le_ltk_request_reply(uint8_t key[16]); + +int hci_le_ltk_request_neg_reply(); + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); + +int hci_le_create_connection_cancel(void); + +int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level); + +int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi); + +int hci_le_read_local_supported_features(uint8_t *features); + +int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); + +int hci_le_read_supported_states(uint8_t states[8]); + +int hci_le_receiver_test(uint8_t frequency); + +int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); + +int hci_le_test_end(uint16_t *num_pkts); + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion); + + + +#endif /* __BLE_HCI_LE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,161 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_link_layer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's link layer. It contains +* definition of functions for link layer, most of which are +* mapped to HCI commands. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef _BLE_LINK_LAYER_H +#define _BLE_LINK_LAYER_H + +#include <ble_status.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + *@name Advertising filter + *Advertising policy for filtering (white list related) + *@{ + */ +#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ +#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ +/** + * @} + */ + + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef uint8_t tBDAddr[6]; + + +/** + *@name Bluetooth address types + * Bluetooth address types + *@{ + */ +#define PUBLIC_ADDR (0) +#define RANDOM_ADDR (1) +#define STATIC_RANDOM_ADDR (1) +#define RESOLVABLE_PRIVATE_ADDR (2) +#define NON_RESOLVABLE_PRIVATE_ADDR (3) +/** + * @} + */ + +/** + *@name Directed advertising types + * Type of advertising during directed advertising + *@{ + */ +#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) +#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) +/** + * @} + */ + +/** + * @name Advertising type + * @{ + */ + +/** + * undirected scannable and connectable + */ +#define ADV_IND (0x00) + +/** + * directed non scannable + */ +#define ADV_DIRECT_IND (0x01) + +/** + * scannable non connectable + */ +#define ADV_SCAN_IND (0x02) + +/** + * non-connectable and no scan response + */ +#define ADV_NONCONN_IND (0x03) + +/** + * scan response + */ +#define SCAN_RSP (0x04) + +/** + * @} + */ + +/* 0X05-0XFF RESERVED */ + +/** + * @name Advertising ranges + * @{ + */ + +/** + * lowest allowed interval value for connectable types(20ms)..multiple of 625us + */ +#define ADV_INTERVAL_LOWEST_CONN (0X0020) + +/** + * highest allowed interval value (10.24s)..multiple of 625us. + */ +#define ADV_INTERVAL_HIGHEST (0X4000) + +/** + * lowest allowed interval value for non connectable types + * (100ms)..multiple of 625us. + */ +#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) + +/** + * @} + */ + +/** + * @name Advertising channels + * @{ + */ +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 +/** + * @} + */ + +/** + * @name Scan_types Scan types + * @{ + */ +#define PASSIVE_SCAN 0 +#define ACTIVE_SCAN 1 +/** + * @} + */ + +/** + * @} + */ + + +#endif /* _BLE_LINK_LAYER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,47 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for linked list library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef _BLE_LIST_H_ +#define _BLE_LIST_H_ + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +uint8_t list_is_empty (tListNode * listHead); + +void list_insert_head (tListNode * listHead, tListNode * node); + +void list_insert_tail (tListNode * listHead, tListNode * node); + +void list_remove_node (tListNode * node); + +void list_remove_head (tListNode * listHead, tListNode ** node ); + +void list_remove_tail (tListNode * listHead, tListNode ** node ); + +void list_insert_node_after (tListNode * node, tListNode * ref_node); + +void list_insert_node_before (tListNode * node, tListNode * ref_node); + +int list_get_size (tListNode * listHead); + +void list_get_next_node (tListNode * ref_node, tListNode ** node); + +void list_get_prev_node (tListNode * ref_node, tListNode ** node); + +#endif /* _BLE_LIST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_OSAL_H__ +#define __BLE_OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __BLE_OSAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,158 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_sm.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's security manager. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_SM_H__ +#define __BLE_SM_H__ + +/****************************************************************************** +* Macros +*****************************************************************************/ + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/* IO capabilities */ +/** + * @anchor IO_capabilities + * @name IO capabilities + * @{ + */ +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define IO_CAP_KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) +/** + * @} + */ + +/** + * @anchor Auth_req + * @name Authentication requirements + * @{ + */ +#define BONDING (0x01) +#define NO_BONDING (0x00) +/** + * @} + */ + +/** + * @anchor MITM_req + * @name MITM protection requirements + * @{ + */ +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor OOB_Data + * @name Out-Of-Band data + * @{ + */ +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) +/** + * @} + */ + +/** + * @anchor Author_req + * @name Authorization requirements + * @{ + */ +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor Conn_authorization + * @name Connection authorization + * @{ + */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) +/** + * @} + */ + +/** + * @anchor Use_fixed_pin + * @name Use fixed pin + * @{ + */ +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +/** + * @} + */ + +/** + * @anchor link_security_status + * @name Link security status + * @{ + */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) +/** + * @} + */ + +/** + * @anchor SMP_pairing_failed_codes + * @name SMP pairing failed reason codes + * @{ + */ +#define PASSKEY_ENTRY_FAILED (0x01) +#define OOB_NOT_AVAILABLE (0x02) +#define AUTH_REQ_CANNOT_BE_MET (0x03) +#define CONFIRM_VALUE_FAILED (0x04) +#define PAIRING_NOT_SUPPORTED (0x05) +#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) +#define CMD_NOT_SUPPORTED (0x07) +#define UNSPECIFIED_REASON (0x08) +#define VERY_EARLY_NEXT_ATTEMPT (0x09) +#define SM_INVALID_PARAMS (0x0A) +/** + * @} + */ + +/** + * @anchor pairing_failed_codes + * @name Pairing failed error codes + * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event + * @{ + */ +#define SM_PAIRING_SUCCESS (0x00) +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,188 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_status.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file with BLE Stack status codes. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_STATUS_H__ +#define __BLE_STATUS_H__ + +#include <ble_hal_types.h> + +/** @addtogroup Middlewares + * @{ + */ + +/** @defgroup ST + * @{ + */ + +/** @defgroup SimpleBlueNRG_HCI + * @{ + */ + +/** @defgroup ble_status Bluetooth Status/Error Codes + * @{ + */ + +typedef uint8_t tBleStatus; + +/* Error Codes as specified by the specification + * according to the spec the error codes range + * from 0x00 to 0x3F + */ +/** + * @name Standard error codes + * @brief Standard error codes. See Core v 4.1, Vol. 2, part D. + * @{ + */ +#define ERR_CMD_SUCCESS (0x00) +#define BLE_STATUS_SUCCESS (0x00) +#define ERR_UNKNOWN_HCI_COMMAND (0x01) +#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) + +#define ERR_AUTH_FAILURE (0x05) +#define ERR_PIN_OR_KEY_MISSING (0x06) +#define ERR_MEM_CAPACITY_EXCEEDED (0x07) +#define ERR_CONNECTION_TIMEOUT (0x08) + +#define ERR_COMMAND_DISALLOWED (0x0C) + +#define ERR_UNSUPPORTED_FEATURE (0x11) +#define ERR_INVALID_HCI_CMD_PARAMS (0x12) +#define ERR_RMT_USR_TERM_CONN (0x13) +#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) +#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) +#define ERR_LOCAL_HOST_TERM_CONN (0x16) + +#define ERR_UNSUPP_RMT_FEATURE (0x1A) + +#define ERR_INVALID_LMP_PARAM (0x1E) +#define ERR_UNSPECIFIED_ERROR (0x1F) + +#define ERR_LL_RESP_TIMEOUT (0x22) +#define ERR_LMP_PDU_NOT_ALLOWED (0x24) + +#define ERR_INSTANT_PASSED (0x28) + +#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) +#define ERR_CONTROLLER_BUSY (0x3A) + +#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) + +#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) + +#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) + + +/** + * @} + */ +/** + * @name Vendor-specific error codes + * @brief Error codes defined by ST related to BlueNRG stack + * @{ + */ +/** + * The command cannot be executed due to the current state of the device. + */ +#define BLE_STATUS_FAILED (0x41) +/** + * Some parameters are invalid. + */ +#define BLE_STATUS_INVALID_PARAMS (0x42) +/** + * It is not allowed to start the procedure (e.g. another the procedure is ongoing + * or cannot be started on the given handle). + */ +#define BLE_STATUS_NOT_ALLOWED (0x46) +/** + * Unexpected error. + */ +#define BLE_STATUS_ERROR (0x47) +#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) + +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +#define BLE_STATUS_INVALID_CID (0x50) + +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) +#define BLE_STATUS_IRK_NOT_FOUND (0x5B) +#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) +#define BLE_STATUS_SEC_DB_FULL (0x5D) +#define BLE_STATUS_DEV_NOT_BONDED (0x5E) +#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) + +#define BLE_STATUS_INVALID_HANDLE (0x60) +#define BLE_STATUS_INVALID_PARAMETER (0x61) +#define BLE_STATUS_OUT_OF_HANDLE (0x62) +#define BLE_STATUS_INVALID_OPERATION (0x63) +#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) +#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) +#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) + +/** + * Returned when no valid slots are available (e.g. when there are no available state machines). + */ +#define BLE_STATUS_NO_VALID_SLOT (0x82) + +/** + * Returned when a scan window shorter than minimum allowed value has been requested (i.e. 2ms) + */ + +#define BLE_STATUS_SCAN_WINDOW_SHORT (0x83) +/** + * Returned when the maximum requested interval to be allocated is shorter then the current + * anchor period and a there is no submultiple for the current anchor period that is between + * the minimum and the maximum requested intervals. + */ + +#define BLE_STATUS_NEW_INTERVAL_FAILED (0x84) +/** + * Returned when the maximum requested interval to be allocated is greater than the current anchor + * period and there is no multiple of the anchor period that is between the minimum and the maximum + * requested intervals. + */ + +#define BLE_STATUS_INTERVAL_TOO_LARGE (0x85) +/** + * Returned when the current anchor period or a new one can be found that is compatible to the + * interval range requested by the new slot but the maximum available length that can be allocated is + * less than the minimum requested slot length. + */ + +#define BLE_STATUS_LENGTH_FAILED (0x86) +/** + * @} + */ + +/** + * @name Library Error Codes + * @brief Error codes defined by ST related to MCU library. + * @{ + */ +#define BLE_STATUS_TIMEOUT (0xFF) +#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) +#define BLE_STATUS_NULL_PARAM (0xF1) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,813 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci_const.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with ACI definitions for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_CONST_H_ +#define __BLUENRG_ACI_CONST_H_ + +#include "ble_compiler.h" +#include "ble_link_layer.h" +#include "ble_hci_const.h" +#include "bluenrg_gatt_server.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define OCF_HAL_GET_FW_BUILD_NUMBER 0x0000 +typedef __packed struct _hal_get_fw_build_number_rp{ + uint8_t status; + uint16_t build_number; +} PACKED hal_get_fw_build_number_rp; +#define HAL_GET_FW_BUILD_NUMBER_RP_SIZE 3 +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +#define OCF_HAL_READ_CONFIG_DATA 0x000D +typedef __packed struct _hal_read_config_data_cp{ + uint8_t offset; +} PACKED hal_read_config_data_cp; +#define HAL_READ_CONFIG_DATA_RP_SIZE 1 +typedef __packed struct _hal_read_config_data_rp{ + uint8_t status; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE]; +} PACKED hal_read_config_data_rp; + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef __packed struct _hal_set_tx_power_level_cp{ + uint8_t en_high_power; + uint8_t pa_level; +} PACKED hal_set_tx_power_level_cp; +#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 + +#define OCF_HAL_DEVICE_STANDBY 0x0013 + +#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014 +typedef __packed struct _hal_le_tx_test_packet_number_rp{ + uint8_t status; + uint32_t number_of_packets; +} PACKED hal_le_tx_test_packet_number_rp; + +#define OCF_HAL_TONE_START 0x0015 +typedef __packed struct _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_HAL_TONE_STOP 0x0016 +#define OCF_HAL_GET_LINK_STATUS 0x0017 +typedef __packed struct _hal_get_link_status_rp{ + uint8_t status; + uint8_t link_status[8]; + uint16_t conn_handle[8]; +} PACKED hal_get_link_status_rp; + +#define OCF_HAL_GET_ANCHOR_PERIOD 0x0019 +typedef __packed struct _hal_get_anchor_period_rp{ + uint8_t status; + uint32_t anchor_period; + uint32_t max_free_slot; +} PACKED hal_get_anchor_period_rp; + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef __packed struct _get_updater_version_rp{ + uint8_t status; + uint8_t version; +} PACKED get_updater_version_rp; +#define GET_UPDATER_VERSION_RP_SIZE 2 + +#define OCF_GET_UPDATER_BUFSIZE 0x0023 +typedef __packed struct _get_updater_bufsize_rp{ + uint8_t status; + uint8_t buffer_size; +} PACKED get_updater_bufsize_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 + +#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 + +#define OCF_UPDATER_ERASE_SECTOR 0x0026 +typedef __packed struct _updater_erase_sector_cp{ + uint32_t address; +} PACKED updater_erase_sector_cp; +#define UPDATER_ERASE_SECTOR_CP_SIZE 4 + +#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 +#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_prog_data_block_cp{ + uint32_t address; + uint16_t data_len; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; +} PACKED updater_prog_data_block_cp; + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef __packed struct _updater_read_data_block_cp{ + uint32_t address; + uint16_t data_len; +} PACKED updater_read_data_block_cp; +#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[VARIABLE_SIZE]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef __packed struct _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef __packed struct _updater_calc_crc_rp{ + uint8_t status; + uint32_t crc; +} PACKED updater_calc_crc_rp; +#define UPDATER_CALC_CRC_RP_SIZE 5 + +#define OCF_UPDATER_HW_VERSION 0x002A +typedef __packed struct _updater_hw_version_rp{ + uint8_t status; + uint8_t version; +} PACKED updater_hw_version_rp; +#define UPDATER_HW_VERSION_RP_SIZE 2 + +#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 + +#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 + +#define OCF_GAP_SET_DISCOVERABLE 0x0083 + +#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 +typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ + uint8_t own_bdaddr_type; + uint8_t directed_adv_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint16_t adv_interv_min; + uint16_t adv_interv_max; +} PACKED gap_set_direct_conectable_cp_IDB05A1; + +typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB04A1; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef __packed struct _gap_set_io_capability_cp{ + uint8_t io_capability; +} PACKED gap_set_io_capability_cp; +#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 + +#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 +typedef __packed struct _gap_set_auth_requirement_cp{ + uint8_t mitm_mode; + uint8_t oob_enable; + uint8_t oob_data[16]; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t bonding_mode; +} PACKED gap_set_auth_requirement_cp; +#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 + +#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 +typedef __packed struct _gap_set_author_requirement_cp{ + uint16_t conn_handle; + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef __packed struct _gap_passkey_response_cp{ + uint16_t conn_handle; + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef __packed struct _gap_authorization_response_cp{ + uint16_t conn_handle; + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 + +#define OCF_GAP_INIT 0x008A +typedef __packed struct _gap_init_cp_IDB05A1{ + uint8_t role; + uint8_t privacy_enabled; + uint8_t device_name_char_len; +} PACKED gap_init_cp_IDB05A1; +#define GAP_INIT_CP_SIZE_IDB05A1 3 + +typedef __packed struct _gap_init_cp_IDB04A1{ + uint8_t role; +} PACKED gap_init_cp_IDB04A1; +#define GAP_INIT_CP_SIZE_IDB04A1 1 +typedef __packed struct _gap_init_rp{ + uint8_t status; + uint16_t service_handle; + uint16_t dev_name_char_handle; + uint16_t appearance_char_handle; +} PACKED gap_init_rp; +#define GAP_INIT_RP_SIZE 7 + +#define OCF_GAP_SET_NON_CONNECTABLE 0x008B +typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ + uint8_t advertising_event_type; + uint8_t own_address_type; +#endif +} PACKED gap_set_non_connectable_cp_IDB05A1; + +typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp_IDB04A1; + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef __packed struct _gap_set_undirected_connectable_cp{ + uint8_t adv_filter_policy; + uint8_t own_addr_type; +} PACKED gap_set_undirected_connectable_cp; +#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 + +#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D +typedef __packed struct _gap_slave_security_request_cp{ + uint16_t conn_handle; + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef __packed struct _gap_delete_ad_type_cp{ + uint8_t ad_type; +} PACKED gap_delete_ad_type_cp; +#define GAP_DELETE_AD_TYPE_CP_SIZE 1 + +#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 +typedef __packed struct _gap_get_security_level_rp{ + uint8_t status; + uint8_t mitm_protection; + uint8_t bonding; + uint8_t oob_data; + uint8_t passkey_required; +} PACKED gap_get_security_level_rp; +#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 + +#define OCF_GAP_SET_EVT_MASK 0x0091 +typedef __packed struct _gap_set_evt_mask_cp{ + uint16_t evt_mask; +} PACKED gap_set_evt_mask_cp; +#define GAP_SET_EVT_MASK_CP_SIZE 2 + +#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 + +#define OCF_GAP_TERMINATE 0x0093 +typedef __packed struct _gap_terminate_cp{ + uint16_t handle; + uint8_t reason; +} PACKED gap_terminate_cp; +#define GAP_TERMINATE_CP_SIZE 3 + +#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 + +#define OCF_GAP_ALLOW_REBOND_DB 0x0095 + +typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ + uint16_t conn_handle; +} PACKED gap_allow_rebond_cp_IDB05A1; + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef __packed struct _gap_start_limited_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_limited_discovery_proc_cp; +#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 +typedef __packed struct _gap_start_general_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_general_discovery_proc_cp; +#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 +typedef __packed struct _gap_start_name_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_name_discovery_proc_cp; +#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 + +#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 + +#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; + +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t use_reconn_addr; + tBDAddr reconn_addr; +} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; + +#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B +#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 +typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t num_whitelist_entries; + uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; +} PACKED gap_start_selective_conn_establish_proc_cp; + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef __packed struct _gap_create_connection_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_create_connection_cp; +#define GAP_CREATE_CONNECTION_CP_SIZE 24 + +#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D + +#define OCF_GAP_START_CONNECTION_UPDATE 0x009E +typedef __packed struct _gap_start_connection_update_cp{ + uint16_t conn_handle; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_connection_update_cp; +#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 + +#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F +typedef __packed struct _gap_send_pairing_request_cp{ + uint16_t conn_handle; + uint8_t force_rebond; +} PACKED gap_send_pairing_request_cp; +#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 + +#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 +typedef __packed struct _gap_resolve_private_address_cp{ + tBDAddr address; +} PACKED gap_resolve_private_address_cp; +#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 +typedef __packed struct _gap_resolve_private_address_rp{ + uint8_t status; + tBDAddr address; +} PACKED gap_resolve_private_address_rp; + +#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 +#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 +typedef __packed struct _gap_set_broadcast_mode_cp{ + uint16_t adv_interv_min; + uint16_t adv_interv_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; +} PACKED gap_set_broadcast_mode_cp; + +#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 +typedef __packed struct _gap_start_observation_proc_cp{ + uint16_t scan_interval; + uint16_t scan_window; + uint8_t scan_type; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_observation_proc_cp; + +#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 +typedef __packed struct _gap_get_bonded_devices_rp{ + uint8_t status; + uint8_t num_addr; + uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; +} PACKED gap_get_bonded_devices_rp; + +#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 +typedef __packed struct _gap_is_device_bonded_cp{ + uint8_t peer_address_type; + tBDAddr peer_address; +} PACKED gap_is_device_bonded_cp; + + +#define OCF_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef __packed struct _gatt_add_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_serv_rp; +#define GATT_ADD_SERV_RP_SIZE 3 + +#define OCF_GATT_INCLUDE_SERV 0x0103 +typedef __packed struct _gatt_include_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_include_serv_rp; +#define GATT_INCLUDE_SERV_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR 0x0104 +typedef __packed struct _gatt_add_char_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_rp; +#define GATT_ADD_CHAR_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR_DESC 0x0105 +typedef __packed struct _gatt_add_char_desc_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_desc_rp; +#define GATT_ADD_CHAR_DESC_RP_SIZE 3 + +#define OCF_GATT_UPD_CHAR_VAL 0x0106 + +#define OCF_GATT_DEL_CHAR 0x0107 +typedef __packed struct _gatt_del_char_cp{ + uint16_t service_handle; + uint16_t char_handle; +} PACKED gatt_del_char_cp; +#define GATT_DEL_CHAR_CP_SIZE 4 + +#define OCF_GATT_DEL_SERV 0x0108 +typedef __packed struct _gatt_del_serv_cp{ + uint16_t service_handle; +} PACKED gatt_del_serv_cp; +#define GATT_DEL_SERV_CP_SIZE 2 + +#define OCF_GATT_DEL_INC_SERV 0x0109 +typedef __packed struct _gatt_del_inc_serv_cp{ + uint16_t service_handle; + uint16_t inc_serv_handle; +} PACKED gatt_del_inc_serv_cp; +#define GATT_DEL_INC_SERV_CP_SIZE 4 + +#define OCF_GATT_SET_EVT_MASK 0x010A +typedef __packed struct _gatt_set_evt_mask_cp{ + uint32_t evt_mask; +} PACKED gatt_set_evt_mask_cp; +#define GATT_SET_EVT_MASK_CP_SIZE 4 + +#define OCF_GATT_EXCHANGE_CONFIG 0x010B +typedef __packed struct _gatt_exchange_config_cp{ + uint16_t conn_handle; +} PACKED gatt_exchange_config_cp; +#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 + +#define OCF_ATT_FIND_INFO_REQ 0x010C +typedef __packed struct _att_find_info_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED att_find_info_req_cp; +#define ATT_FIND_INFO_REQ_CP_SIZE 6 + +#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D +#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 +typedef __packed struct _att_find_by_type_value_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[2]; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU - 7]; +} PACKED att_find_by_type_value_req_cp; + +#define OCF_ATT_READ_BY_TYPE_REQ 0x010E +#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_type_req_cp; + +#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F +#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_group_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_group_type_req_cp; + +#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 +#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val +typedef __packed struct _att_prepare_write_req_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t value_offset; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU-5]; +} PACKED att_prepare_write_req_cp; + +#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 +typedef __packed struct _att_execute_write_req_cp{ + uint16_t conn_handle; + uint8_t execute; +} PACKED att_execute_write_req_cp; +#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 + +#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 +typedef __packed struct _gatt_disc_all_prim_serivces_cp{ + uint16_t conn_handle; +} PACKED gatt_disc_all_prim_services_cp; +#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 + +#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 +typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ + uint16_t conn_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_disc_prim_service_by_uuid_cp; +#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid + +#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 +typedef __packed struct _gatt_disc_find_included_services_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED gatt_find_included_services_cp; +#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 + +#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 +typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ + uint16_t conn_handle; + uint16_t start_attr_handle; + uint16_t end_attr_handle; +} PACKED gatt_disc_all_charac_of_serv_cp; +#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 + +#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 + +#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ + uint16_t conn_handle; + uint16_t char_val_handle; + uint16_t char_end_handle; +} PACKED gatt_disc_all_charac_descriptors_cp; +#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 + +#define OCF_GATT_READ_CHARAC_VAL 0x0118 +typedef __packed struct _gatt_read_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_val_cp; +#define GATT_READ_CHARAC_VAL_CP_SIZE 4 + +#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 +typedef __packed struct _gatt_read_using_charac_uuid_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_read_using_charac_uuid_cp; +#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID + +#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A +typedef __packed struct _gatt_read_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_val_cp; +#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 + +#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B +#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles +typedef __packed struct _gatt_read_multiple_charac_val_cp{ + uint16_t conn_handle; + uint8_t num_handles; + uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_read_multiple_charac_val_cp; + +#define OCF_GATT_WRITE_CHAR_VALUE 0x011C + +#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D +#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_write_long_charac_val_cp; + +#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E +#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_charac_reliable_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; +} PACKED gatt_write_charac_reliable_cp; + +#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F +#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; +} PACKED gatt_write_long_charac_desc_cp; + +#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 +typedef __packed struct _gatt_read_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_desc_cp; +#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 + +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 +typedef __packed struct _gatt_read_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_desc_cp; +#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 +#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 3]; +} PACKED gatt_write_without_resp_cp; + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 +#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_signed_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 13]; +} PACKED gatt_signed_write_without_resp_cp; + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 +typedef __packed struct _gatt_confirm_indication_cp{ + uint16_t conn_handle; +} PACKED gatt_confirm_indication_cp; +#define GATT_CONFIRM_INDICATION_CP_SIZE 2 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef __packed struct _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 +typedef __packed struct _gatt_set_security_permission_cp{ + uint16_t service_handle; + uint16_t attr_handle; + uint8_t security_permission; +} PACKED gatt_set_security_permission_cp; +#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_GATT_READ_HANDLE_VALUE 0x012A +typedef __packed struct _gatt_read_handle_val_cp{ + uint16_t attr_handle; +} PACKED gatt_read_handle_val_cp; +#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 +typedef __packed struct _gatt_read_handle_val_rp{ + uint8_t status; + uint16_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; +} PACKED gatt_read_handle_val_rp; + +#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B +typedef __packed struct _gatt_read_handle_val_offset_cp{ + uint16_t attr_handle; + uint8_t offset; +} PACKED gatt_read_handle_val_offset_cp; +#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 +typedef __packed struct _gatt_read_handle_val_offset_rp{ + uint8_t status; + uint8_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; +} PACKED gatt_read_handle_val_offset_rp; + +#define OCF_GATT_UPD_CHAR_VAL_EXT 0x012C +#define GATT_UPD_CHAR_VAL_EXT_CP_SIZE 10 // without value +typedef __packed struct _gatt_upd_char_val_ext_cp{ + uint16_t service_handle; + uint16_t char_handle; + uint8_t update_type; + uint16_t char_length; + uint16_t value_offset; + uint8_t value_length; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_UPD_CHAR_VAL_EXT_CP_SIZE]; +} PACKED gatt_upd_char_val_ext_cp; + +#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 +typedef __packed struct _l2cap_conn_param_update_req_cp{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_update_req_cp; +#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 + +#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint16_t min_ce_length; + uint16_t max_ce_length; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; + +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; + +/** + * @defgroup BlueNRG_Events BlueNRG events (vendor specific) + * @{ + */ + +/** + * Vendor specific event for BlueNRG. + */ +typedef __packed struct _evt_blue_aci{ + uint16_t ecode; /**< One of the BlueNRG event codes. */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_blue_aci; + + +/** + * @} + */ + +#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,230 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gap.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GAP layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BNRG_GAP_H__ +#define __BNRG_GAP_H__ + +#include <ble_link_layer.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + * @name GAP UUIDs + * @{ + */ +#define GAP_SERVICE_UUID (0x1800) +#define DEVICE_NAME_UUID (0x2A00) +#define APPEARANCE_UUID (0x2A01) +#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) +#define RECONNECTION_ADDR_UUID (0x2A03) +#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) +/** + * @} + */ + +/** + * @name Characteristic value lengths + * @{ + */ +#define DEVICE_NAME_CHARACTERISTIC_LEN (8) +#define APPEARANCE_CHARACTERISTIC_LEN (2) +#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) +#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) +#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) +/** + * @} + */ + +/*------------- AD types for adv data and scan response data ----------------*/ + +/** + * @defgroup AD_Types AD Types + * @brief AD Types + * @{ + */ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +/** + * @anchor Flags_AD_Type_bits + * @name Flags AD Type bits + * @brief Bits in Flags AD Type + * @{ + */ +#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) +#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) +#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) +#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) +#define FLAG_BIT_LE_BR_EDR_HOST (0x10) +/** + * @} + */ + +/** + * @name Service UUID AD types + * @{ + */ +#define AD_TYPE_16_BIT_SERV_UUID (0x02) +#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) +#define AD_TYPE_32_BIT_SERV_UUID (0x04) +#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) +#define AD_TYPE_128_BIT_SERV_UUID (0x06) +#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) +/** + * @} + */ + +/* LOCAL NAME AD types */ +/** + * @name Local name AD types + * @{ + */ +#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) +#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) +/** + * @} + */ + +/* TX power level AD type*/ +#define AD_TYPE_TX_POWER_LEVEL (0x0A) + +/* Class of device */ +#define AD_TYPE_CLASS_OF_DEVICE (0x0D) + +/* security manager TK value AD type */ +#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) + +/* security manager OOB flags */ +#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) + +/* slave connection interval AD type */ +#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) + +/* service solicitation UUID list Ad types*/ +/** + * @name Service solicitation UUID list AD types + * @{ + */ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) +#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) +/** + * @} + */ + +/* service data AD type */ +#define AD_TYPE_SERVICE_DATA (0x16) + +/* manufaturer specific data AD type */ +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/* appearance AD type */ +#define AD_TYPE_APPEARANCE (0x19) + +/* advertising interval AD type */ +#define AD_TYPE_ADVERTISING_INTERVAL (0x1A) + +/** + * @} + */ + +#define MAX_ADV_DATA_LEN (31) + +#define DEVICE_NAME_LEN (7) +#define BD_ADDR_SIZE (6) + +/** + * @name Privacy flag values + * @{ + */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) +/** + * @} + */ + +/** + * @name Intervals + * Intervals in terms of 625 micro sec + * @{ + */ +#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ +#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ +#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ +#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ +#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ +#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ +#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ +#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ +/** + * @} + */ + +/** + * @name Timeout values + * @{ + */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ +/** + * @} + */ + +/** + * @anchor gap_roles + * @name GAP Roles + * @{ +*/ +#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) +#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) + +#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) +#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) +/** + * @} + */ + +/** + * @anchor gap_procedure_codes + * @name GAP procedure codes + * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event + * and aci_gap_terminate_gap_procedure() command. + * @{ + */ +#define GAP_LIMITED_DISCOVERY_PROC (0x01) +#define GAP_GENERAL_DISCOVERY_PROC (0x02) +#define GAP_NAME_DISCOVERY_PROC (0x04) +#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) +#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) +#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) +#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) +#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1231 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gap_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GAP_ACI_H__ +#define __BLUENRG_GAP_ACI_H__ + +/** + *@addtogroup GAP GAP + *@brief GAP layer. + *@{ + */ + +/** + *@defgroup GAP_Functions GAP functions + *@brief API for GAP layer. + *@{ + */ + +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". + * @param privacy_enabled Enable (1) or disable (0) privacy. + * @param device_name_char_len Length of the device name characteristic + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, + uint8_t device_name_char_len, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Privacy Flag (peripheral role only) + * @li Reconnection Address (peripheral role only) + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB04A1(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); + +/** + * @brief Set the Device in non-discoverable mode. + * @note This command will disable the LL advertising. + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_discoverable(void); + +/** + * @brief Put the device in limited discoverable mode + * (as defined in GAP specification volume 3, section 9.2.3). + * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. + * The advertising can be disabled at any time by issuing + * aci_gap_set_non_discoverable() command. + * The AdvIntervMin and AdvIntervMax parameters are optional. If both + * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). + * Host can set the Local Name, a Service UUID list and the Slave Connection + * Minimum and Maximum. If provided, these data will be inserted into the + * advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() + * separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following + * standard AD types: + * @li AD Flags + * @li TX Power Level + * + * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates + * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. + * + * Example: + * @code + * + * #define ADV_INTERVAL_MIN_MS 100 + * #define ADV_INTERVAL_MAX_MS 200 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, + * (ADV_INTERVAL_MAX_MS*1000)/0.625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * sizeof(serviceUUIDList), serviceUUIDList, + * 0, 0); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 250 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 500 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg NO_WHITE_LIST_USE + * @arg WHITE_LIST_FOR_ONLY_SCAN + * @arg WHITE_LIST_FOR_ONLY_CONN + * @arg WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +/** + * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4). + * @note The device will be discoverable until the Host issue Aci_Gap_Set_Non_Discoverable command. + * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses + * the default values for advertising intervals (1.28 s and 2.56 s respectively for IDB04A1). + * When using connectable undirected advertising events:\n + * @li Adv_Interval_Min = 30 ms + * @li Adv_Interval_Max = 60 ms + * \nWhen using non-connectable advertising events or scannable undirected advertising events:\n + * @li Adv_Interval_Min = 100 ms + * @li Adv_Interval_Max = 150 ms + * Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided, + * these data will be inserted into the advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following standard AD types: + * @li AD Flags + * @li TX Power Level + * + * Usage example: + * + * @code + * + * #define ADV_INTERVAL_MIN_MS 800 + * #define ADV_INTERVAL_MAX_MS 900 + * #define CONN_INTERVAL_MIN_MS 100 + * #define CONN_INTERVAL_MAX_MS 300 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625, + * (ADV_INTERVAL_MAX_MS*1000)/625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * 0, NULL, + * (CONN_INTERVAL_MIN_MS*1000)/1250, + * (CONN_INTERVAL_MAX_MS*1000)/1250); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 1.28 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 2.56 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ONLY_SCAN + * @arg @ref WHITE_LIST_FOR_ONLY_CONN + * @arg @ref WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); + +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @param adv_interv_min Minimum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @param adv_interv_max Maximum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max); +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); + +/** + * @brief Set the IO capabilities of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param io_capability One of the allowed codes for IO Capability: + * @arg @ref IO_CAP_DISPLAY_ONLY + * @arg @ref IO_CAP_DISPLAY_YES_NO + * @arg @ref IO_CAP_KEYBOARD_ONLY + * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT + * @arg @ref IO_CAP_KEYBOARD_DISPLAY + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_io_capability(uint8_t io_capability); + +/** + * @brief Set the authentication requirements for the device. + * @note If the oob_enable is set to 0, oob_data will be ignored. + * This command has to be given only when the device is not in a connected state. + * @param mitm_mode MITM mode: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @param oob_enable If OOB data are present or not: + * @arg @ref OOB_AUTH_DATA_ABSENT + * @arg @ref OOB_AUTH_DATA_PRESENT + * @param oob_data Out-Of-Band data + * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process + * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process + * @param use_fixed_pin If application wants to use a fixed pin or not: + * @arg @ref USE_FIXED_PIN_FOR_PAIRING + * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING + * If a fixed pin is not used, it has to be provided by the application with + * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will + * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is + * accepted. + * @param bonding_mode One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode); + /** + * @brief Set the authorization requirements of the device. + * @note This command has to be given when connected to a device if authorization is required to access services + * which require authorization. + * @param conn_handle Handle of the connection. + * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required + * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables + * the authorization requirement in the device and when a remote device + * tries to read/write a characeristic with authorization requirements, the stack will + * send back an error response with "Insufficient authorization" error code. + * After pairing is complete a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event + * will be sent to the Host. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); + +/** + * @brief Provide the pass key that will be used during pairing. + * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param conn_handle Connection handle + * @param passkey Pass key that will be used during the pairing process. Must be a number between + * 0 and 999999. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); + +/** + * @brief Authorize a device to access attributes. + * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. + * + * @param conn_handle Connection handle + * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) + * @arg @ref CONNECTION_REJECTED : Reject (reject connection) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); + +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @param own_address_type If Privacy is disabled, then the peripheral address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the peripheral address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); + +/** + * @brief Put the device into undirected connectable mode. + * @note If privacy is enabled in the device, a resolvable private address is generated and used + * as the advertiser's address. If not, the address of the type specified in own_addr_type + * is used for advertising. + * @param own_addr_type Type of our address used during advertising: + * if BLUENRG (IDB04A1) + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * else if BLUENRG_MS (IDB05A1) + * If Privacy is disabled: + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled: + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_filter_policy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ALL + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); + +/** + * @brief Send a slave security request to the master. + * @note This command has to be issued to notify the master of the security requirements of the slave. + * The master may encrypt the link, initiate the pairing procedure, or reject the request. + * @param conn_handle Connection handle + * @param bonding One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @param mitm_protection If MITM protection is required or not: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); + +/** + * @brief Update advertising data. + * @note This command can be used to update the advertising data for a particular AD type. + * If the AD type specified does not exist, then it is added to the advertising data. + * If the overall advertising data length is more than 31 octets after the update, then + * the command is rejected and the old data is retained. + * @param AdvLen Length of AdvData array + * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification + * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. + * Example + * @code + * tBleStatus ret; + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; + * + * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * 8, local_name, 3, serviceUUIDList, 0, 0); + * ret = aci_gap_update_adv_data(5, manuf_data); + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); + +/** + * @brief Delete an AD Type + * @note This command can be used to delete the specified AD type from the advertisement data if + * present. + * @param ad_type One of the allowed AD types (see @ref AD_Types) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); + +/** + * @brief Get the current security settings + * @note This command can be used to get the current security settings of the device. + * @param mitm_protection @arg 0: Not required + * @arg 1: Required + * @param bonding @arg 0: No bonding mode + * @arg 1: Bonding mode + * @param oob_data @arg 0: Data absent + * @arg 1: Data present + * @param passkey_required @arg 0: Not required + * @arg 1: Fixed pin is present which is being used + * @arg 2: Passkey required for pairing. An event will be generated + * when required. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required); + +/** + * @brief Add addresses of bonded devices into the controller's whitelist. + * @note The command will return an error if there are no devices in the database or if it was unable + * to add the device into the whitelist. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_configure_whitelist(void); + +/** + * @brief Terminate a connection. + * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. + * @param conn_handle Connection handle + * @param reason Reason for requesting disconnection. The error code can be any of ones as specified + * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); + +/** + * @brief Clear the security database. + * @note All the devices in the security database will be removed. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_clear_security_database(void); + +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @param conn_handle + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB04A1(void); + +/** + * @brief Start the limited discovery procedure. + * @note The controller is commanded to start active scanning. When this procedure is started, + * only the devices in limited discoverable mode are returned to the upper layers. + * The procedure is terminated when either the upper layers issue a command to terminate the + * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code + * set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated + * due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC. + * The device found when the procedure is ongoing is returned to the upper layers through the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the general discovery procedure. + * @note The controller is commanded to start active scanning. The procedure is terminated when + * either the upper layers issue a command to terminate the procedure by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC + * or a timeout happens. When the procedure is terminated due to any of the above reasons, + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to + * @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to + * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the name discovery procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. Once a connection is established, GATT procedure is started to read the + * device name characteristic. When the read is completed (successfully or unsuccessfully), + * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also + * contains the name of the device if the device name was read successfully. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Start the auto connection establishment procedure. + * @note The devices specified are added to the white list of the controller and a LE_Create_Connection + * call will be made to the controller by GAP with the initiator filter policy set to + * use whitelist to determine which advertiser to connect to. When a command is issued to + * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the + * controller by GAP. + * The procedure is terminated when either a connection is successfully established with one of + * the specified devices in the white list or the procedure is explicitly terminated by issuing + * the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start a general connection establishment procedure. + * @note The host enables scanning in the controller with the scanner filter policy set + * to accept all advertising packets and from the scanning results all the devices + * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * The upper layer then has to select one of the devices to which it wants to connect + * by issuing the command aci_gap_create_connection(). The procedure is terminated + * when a connection is established or the upper layer terminates the procedure by + * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates); +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); + +/** + * @brief Start a selective connection establishment procedure. + * @note The GAP adds the specified device addresses into white list and enables scanning in + * the controller with the scanner filter policy set to accept packets only from + * devices in whitelist. All the devices found are sent to the upper layer by the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the + * devices to which it wants to connect by issuing the command aci_gap_create_connection(). + * On completion of the procedure a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated + * with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * The procedure is terminated when a connection is established or the upper layer terminates + * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure + * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start the direct connection establishment procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. The procedure can be terminated explicitly by the upper layer by issuing + * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the + * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller + * by GAP. + * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can + * be explicitly terminated by the upper layer by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is + * returned with the procedure code set to the corresponding procedure. + * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes"). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); + +/** + * @brief Start the connection parameter update procedure. + * @note Allowed by the Central to update the connection parameter of the specified connection. + * A Link Layer Connection Update procedure is started on the controller. + * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to + * the upper layer. + * @param conn_handle Handle of the connection for which the update procedure has to be started. + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Send a pairing request. + * @note Send the SM pairing request to start a pairing process from a Central. The authentication + * requirements and IO capabilities should be set before issuing this command using + * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). + * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. + * @param conn_handle Handle of the connection for which the pairing request has to be sent. + * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded + * @arg 0x01: Pairing request will be sent even if the device was previously bonded + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param[in] address Address to be resolved. + * @param[out] actual_address The public or static random address of the peer device, distributed during pairing phase. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); + +/** + * @brief This command gets the list of bonded devices. + * @note It returns the number of addresses and the corresponding address types and values. + * Example: + * @code + * tBleStatus ret; + * uint8_t num_devices = 0; + * uint8_t device_list[12*7]; + * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); + * for(int i = 0; i < num_devices; i+=7){ + * uint8_t addr_type = device_list[i]; + * uint8_t addr = device_list[i+1]; + * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); + * } + * @endcode + * + * @param[out] num_devices The number of bonded devices. + * @param[out] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address + * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. + * @param device_list_size Maximum size of the device_list buffer used to return the device list. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); + +/** + * @brief Puts the device into broadcast mode + * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address + * as specified in the own_addr_type parameter of the command. + * @param adv_interv_min Minimum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_interv_max Maximum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param own_addr_type If Privacy is disabled, the broadcaster address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the broadcaster address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_data_length Length of the advertising data in the advertising packet + * @param adv_data Advertising data used by the device while advertising + * @param num_whitelist_entries Number of devices to be added to whitelist + * @param addr_array It will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Starts an observation procedure, when the device is in Observer role. + * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer + * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth + * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. + * The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. + * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param own_address_type If Privacy is disabled, then the scanner address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the scanner address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates); + +/** + * @brief The command finds whether a device is bonded. + * @note If the device is using a resolvable private address and it has been bonded, then the command will return + * BLE_STATUS_SUCCESS. + * @param peer_address_type The address type of the peer device + * @arg @ref PUBLIC_ADDR. + * @arg @ref RANDOM_ADDR. + * @param peer_address Address used by the peer device while advertising. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address); + + +/** + * @} + */ + +/** + * @defgroup GAP_Events GAP events + * @{ + */ + +/** + * This event is generated by the controller when the limited discoverable + * mode ends due to timeout (180 seconds). No parameters in the event. + */ +#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) + + +/** + * This event is generated when the pairing process has completed successfully + * or a pairing procedure timeout has occurred or the pairing has failed. + * This is to notify the application that we have paired with a remote device + * so that it can take further actions or to notify that a timeout has occurred + * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. + */ +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +typedef __packed struct _evt_gap_pairing_cmplt{ + uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ + /** + * 0x00: Pairing Success. Pairing with a remote device was successful\n + * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n + * 0x02: Pairing Failed. The pairing failed with the remote device. + */ + uint8_t status; +} PACKED evt_gap_pairing_cmplt; + + +/** + * This event is generated by the Security manager to the application when a pass key is required for pairing. + * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. + * See @ref _evt_gap_pass_key_req. + */ +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +typedef __packed struct _evt_gap_pass_key_req{ + uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ +} PACKED evt_gap_pass_key_req; + + +/** + * This event is generated by the Security manager to the application when the application + * has set that authorization is required for reading/writing of attributes. This event will + * be generated as soon as the pairing is complete. When this event is received, + * aci_gap_authorization_response() command should be used by the application. + * See @ref _evt_gap_author_req. + */ +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +typedef __packed struct _evt_gap_author_req{ + uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ +} PACKED evt_gap_author_req; + +/** + * This event is generated when the slave security request is successfully sent to the master. + * No parameters for this event. + */ +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) + +/** + * This event is generated on the slave when a aci_gap_slave_security_request() is called to reestablish the bond + * with a master but the master has lost the bond. When this event is received, the upper layer has to issue the + * command aci_gap_allow_rebond() in order to allow the slave to continue the pairing process with the master. + * On the master this event is raised when aci_gap_send_pairing_request() is called to reestablish a bond with a slave + * but the slave has lost the bond. In order to create a new bond the master has to launch aci_gap_send_pairing_request() + * with force_rebond set to 1. + * No parameters for this event + */ +#define EVT_BLUE_GAP_BOND_LOST (0X0405) + +/** + * The event is given by the GAP layer to the upper layers when a device is discovered during scanning + * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. + */ +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef __packed struct _evt_gap_device_found{ + uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ + uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ + tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ + uint8_t data_length; /**< Length of advertising or scan response data. */ + uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ +} PACKED evt_gap_device_found; + +/** + * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated + * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. + */ +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef __packed struct _evt_gap_procedure_complete{ + uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ + /** + * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed + * due to authentication requirements). + */ + uint8_t status; + /** + * Procedure specific data.\n + * @li For Name Discovery Procedure:\n + * the name of the peer device if the procedure completed successfully. + * @li For General Connection Establishment Procedure:\n + * The reconnection address written to the peripheral device if the peripheral is privacy enabled + */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_gap_procedure_complete; + +/** + * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral + * is not able to resolve the private address of the peer device after connecting to it. + */ +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) +typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ + uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ +} PACKED evt_gap_addr_not_resolved_IDB05A1; +/** + * This event is raised when the reconnection address is generated during the general connection + * establishment procedure. The same address is set into the peer device also as a part of the general + * connection establishment procedure. In order to make use of the reconnection address the next time + * while connecting to the bonded peripheral, the application needs to use this reconnection address + * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() + * and aci_gap_start_auto_conn_establish_proc(). + */ +#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) +typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ + uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ +} PACKED evt_gap_reconnection_addr_IDB04A1; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1128 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GATT_ACI_H__ +#define __BLUENRG_GATT_ACI_H__ + +#include "bluenrg_gatt_server.h" + +/** + *@addtogroup GATT GATT + *@brief GATT layer. + *@{ + */ + +/** + *@defgroup GATT_Functions GATT functions + *@brief API for GATT layer. + *@{ + */ + +/** + * @brief Initialize the GATT layer for server and client roles. + * @note It adds also the GATT service with Service Changed Characteristic. + * Until this command is issued the GATT channel will not process any commands + * even if the connection is opened. This command has to be given + * before using any of the GAP features. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_init(void); + +/** + * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs + * to reserve the handle ranges for this service using max_attr_records parameter. This + * parameter specifies the maximum number of attribute records that can be added to this + * service (including the service attribute, include attribute, characteristic attribute, + * characteristic value attribute and characteristic descriptor attribute). Handle of the + * created service is returned. + * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors + * are allocated from the attribute pool. + * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field + * @param service_type Primary or secondary service. See @ref Service_type "Service Type". + * @param max_attr_records Maximum number of attribute records that can be added to this service + * (including the service declaration itself) + * @param[out] serviceHandle Handle of the Service. When this service is added to the service, + * a handle is allocated by the server to this service. Server also + * allocates a range of handles for this service from serviceHandle to + * <serviceHandle + max_attr_records>. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, + const uint8_t* service_uuid, + uint8_t service_type, + uint8_t max_attr_records, + uint16_t *serviceHandle); + +/** + * @brief Include a service given by included_start_handle and included_end_handle to another service + * given by service_handle. Attribute server creates an INCLUDE definition attribute and return + * the handle of this attribute in included_handle. + * @param service_handle Handle of the service to which another service has to be included + * @param included_start_handle Start Handle of the service which has to be included in service + * @param included_end_handle End Handle of the service which has to be included in service + * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". + * @param[in] included_uuid 16-bit or 128-bit UUID. + * @param[out] included_handle Handle of the include declaration. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle); + +/** + * @brief Add a characteristic to a service. + * @param serviceHandle Handle of the service to which the characteristic has to be added. + * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param charUuid 16-bit or 128-bit UUID. + * @param charValueLen Maximum length of the characteristic value. + * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, + * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". + * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @arg GATT_DONT_NOTIFY_EVENTS + * @arg GATT_NOTIFY_ATTRIBUTE_WRITE + * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP + * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. + * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client + * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE + * properties. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle); + +/** + * Add a characteristic descriptor to a service. + * @param serviceHandle Handle of the service to which the characteristic belongs + * @param charHandle Handle of the characteristic to which description has to be added. + * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG + * (Well_known_UUIDs) or a user-defined one. + * @param descValueMaxLen The maximum length of the descriptor value + * @param descValueLen Current Length of the characteristic descriptor value + * @param[in] descValue Value of the characteristic description + * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". + * @arg ATTR_NO_ACCESS + * @arg ATTR_ACCESS_READ_ONLY + * @arg ATTR_ACCESS_WRITE_REQ_ONLY + * @arg ATTR_ACCESS_READ_WRITE + * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE + * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param[out] descHandle Handle of the Characteristic Descriptor. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle); + +/** + * @brief Update a characteristic value in a service. + * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. The command is queued into the + * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, + * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or + * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate + * than what is allowed by the link. Throughput on BLE link depends on connection interval and + * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() + * for more info on how to suggest new connection parameters from a slave). If the application does not + * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function + * returns @ref BLE_STATUS_SUCCESS or any other error code.\n + * Example:\n + * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some + * notifications will be lost. + * @code + * tBleStatus Free_Fall_Notify(void) + * { + * uint8_t val; + * tBleStatus ret; + * + * val = 0x01; + * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); + * + * if (ret != BLE_STATUS_SUCCESS){ + * PRINTF("Error while updating FFall characteristic.\n") ; + * return BLE_STATUS_ERROR ; + * } + * return BLE_STATUS_SUCCESS; + * } + * @endcode + * Here if BlueNRG buffer become full, the application try again to send the notification. + * @code + * struct timer t; + * Timer_Set(&t, CLOCK_SECOND*10); + * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ + * // Radio is busy (buffer full). + * if(Timer_Expired(&t)) + * break; + * } + * @endcode + * + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic + * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, + * and the attribute value is of variable length, then the length of the attribute will + * be set to the charValueLen. If the charValOffset is set to a value greater than 0, + * then the length of the attribute will be set to the maximum length as specified for + * the attribute while adding the characteristic. + * @param charValueLen Length of the characteristic value in octets + * @param[in] charValue Characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue); +/** + * @brief Delete the specified characteristic from the service. + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); + +/** + * @brief Delete the specified service from the GATT server database. + * @param servHandle Handle of the service to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_service(uint16_t servHandle); + +/** + * @brief Delete the Include definition from the service. + * @param servHandle Handle of the service to which Include definition belongs + * @param includeServHandle Handle of the Included definition to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); + +/** + * @brief Perform an ATT MTU exchange procedure. + * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP + * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated + * to indicate the end of the procedure. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); + +/** + * @brief Send a @a Find @a Information @a Request. + * @note This command is used to obtain the mapping of attribute handles with their associated + * types. The responses of the procedure are given through the + * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by + * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range of attributes to be discovered on the server + * @param end_handle Ending handle of the range of attributes to be discovered on the server + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send a @a Find @a By @a Type @a Value @a Request + * @note The Find By Type Value Request is used to obtain the handles of attributes that + * have a given 16-bit UUID attribute type and a given attribute value. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid 2 octet UUID to find (little-endian) + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). + * @param attr_val Attribute value to find + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send a @a Read @a By @a Type @a Request + * @note The Read By Type Request is used to obtain the values of attributes where the attribute type + * is known but the handle is not known. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Read @a By @a Group @a Type @a Request + * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute + * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping + * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Prepare @a Write @a Request + * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param attr_handle The handle of the attribute to be written + * @param value_offset The offset of the first octet to be written + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). + * @param attr_val The value of the attribute to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send an @a Execute @a Write @a Request + * @note The Execute Write Request is used to request the server to write or cancel the write of all the + * prepared values currently held in the prepare queue from this client. + * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param execute @arg 0x00 Cancel all prepared writes + * @arg 0x01 Immediately write all pending prepared values. + * @return Value indicating success or error code. + */ +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); + +/** + * @brief This command will start the GATT client procedure to discover all primary services on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +/** + * @brief Start the procedure to discover the primary services of the specified UUID on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to find all included services. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle Start handle of the service + * @param end_handle End handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Start the procedure to discover all the characteristics of a given service. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_attr_handle Start attribute handle of the service + * @param end_attr_handle End attribute handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +/** + * @brief Start the procedure to discover all the characteristics specified by a UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Start attribute handle of the service + * @param end_handle End attribute handle of the service + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); + +/** + * @brief Start the procedure to discover all characteristic descriptors on the server. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. + * @param conn_handle Connection handle for which the command is given. + * @param char_val_handle Starting handle of the characteristic + * @param char_end_handle End handle of the characteristic + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +/** + * @brief Start the procedure to read the attribute value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to read all the characteristics specified by the UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range to be searched + * @param end_handle End handle of the range to be searched + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start a procedure to read multiple characteristic values from a server. + * @note This sub-procedure is used to read multiple Characteristic Values from a server when the + * client knows the Characteristic Value Handles. + * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param num_handles The number of handles for which the value has to be read + * @param set_of_handles The handles for which the attribute value has to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles); + +/** + * @brief Start the procedure to write a characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to write a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start the procedure to write a characteristic reliably. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to write a long characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP + * event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic descriptor + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start the procedure to write a characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to read the descriptor specified. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the descriptor to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to write a characteristic value without waiting for any response from the server. + * @note No events are generated after this command is executed. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 3) + * @param[in] attr_val Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start a signed write without response from the server. + * @note The procedure i used to write a characteristic value with an authentication signature without waiting + * for any response from the server. It cannot be used when the link is encrypted. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 13). + * @param attr_val Value to be written + * @return Value indicating success or error code + */ +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Confirm an indication + * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); + +/** + * @brief Allow or reject a write request from a client. + * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, + * then the status has to be set to 1 and the error code has to be set to the error code that has to be + * passed to the client. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n + * 0x01: The value cannot be written to the attribute specified by the attr_handle. + * @param err_code The error code that has to be passed to the client in case the write has to be rejected. + * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val); + +/** + * @brief Allow the GATT server to send a response to a read request from a client. + * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ + * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response + * can be sent to the client. So if the application wishes to update any of the attributes before + * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value + * and then give this command. The application should perform the required operations within 30 seconds, + * otherwise the GATT procedure will go to timeout. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_allow_read(uint16_t conn_handle); + +/** + * @brief Set the security permission for the attribute handle specified. + * @note Currently the setting of security permission is allowed only for client configuration descriptor. + * @param service_handle Handle of the service which contains the attribute whose security + * permission has to be modified. + * @param attr_handle Handle of the attribute whose security permission has to be modified. + * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission); + +/** + * @brief This command sets the value of the descriptor specified by charDescHandle. + * @param servHandle Handle of the service which contains the descriptor. + * @param charHandle Handle of the characteristic which contains the descriptor. + * @param charDescHandle Handle of the descriptor whose value has to be set. + * @param charDescValOffset Offset from which the descriptor value has to be updated. + * @param charDescValueLen Length of the descriptor value + * @param[in] charDescValue descriptor value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue); + +/** + * @brief Reads the value of the attribute handle specified from the local GATT database. + * @param attr_handle Handle of the attribute to read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + + /** + * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. + * @param attr_handle Handle of the attribute to read + * @param offset Offset from which the value needs to be read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); +/** + * @brief Update the value of a characteristic and sends notifications or indications. + * @note This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute + * up to 512 bytes and indicate selectively the generation of indications and notifications. + * @param service_handle Handle of the service to which the characteristic belongs. + * @param char_handle Handle of the characteristic + * @param update_type Bitmask that controls generation of notifications and indications. It can be a combination + * @arg @ref NOTIFICATION (0x01): send notification, if enabled. + * @arg @ref INDICATION (0x02): send indication, if enabled. + * If set to 0 no notifications or indications are sent. + * @param char_length Total length of the characteristic value. In case of a variable size characteristic, + * this field specifies the new length of the characteristic value after the update; + * in case of fixed length characteristic this field is ignored. + * @param value_offset The offset from which the attribute value has to be updated + * @param value_length Length of the value to be updated + * @param[out] value Updated characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value); + +/** + * @} + */ + + +/** + * @defgroup GATT_Events GATT events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** + * This event (if enabled, see @ref Gatt_Event_Mask "Gatt Event Mask") is raised to the application + * by the GATT server when a client modifies any attribute on the server, as consequence of one of + * the following GATT procedures: + * @li write without response + * @li signed write without response + * @li write characteristic value + * @li write long characteristic value + * @li reliable write. + * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. + */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint16_t offset; /**< Offset from which the write has been performed by the peer device */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB05A1; + +typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB04A1; + +/** + * This event is generated by the client/server to the application on a GATT timeout (30 seconds). + * See @ref _evt_gatt_procedure_timeout. + */ +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +typedef __packed struct _evt_gatt_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ +} PACKED evt_gatt_procedure_timeout; + +/** + * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). + * See @ref _evt_att_exchange_mtu_resp. + */ +#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) +typedef __packed struct _evt_att_exchange_mtu_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data (always 1). */ + uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ +} PACKED evt_att_exchange_mtu_resp; + +/** + * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and + * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. + */ +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef __packed struct _evt_att_find_information_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ + /** + * A sequence of handle-uuid pairs.\n + * @li if format=1, each pair is:\n + * [2 octets for handle, 2 octets for UUIDs] \n + * @li if format=2, each pair is:\n + * [2 octets for handle, 16 octets for UUIDs] + */ + uint8_t handle_uuid_pair[VARIABLE_SIZE]; +} PACKED evt_att_find_information_resp; + +/** + * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See + * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. + */ +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +typedef __packed struct _evt_att_find_by_type_val_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + /** + * Handles Information List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] + */ + uint8_t handles_info_list[VARIABLE_SIZE]; +} PACKED evt_att_find_by_type_val_resp; + +/** + * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and + * aci_gatt_disc_all_charac_of_serv(). + * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. + */ +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef __packed struct _evt_att_read_by_type_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ + /** + * Attribute Data List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] + */ + uint8_t handle_value_pair[VARIABLE_SIZE]; +} PACKED evt_att_read_by_type_resp; + +/** + * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). + * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. + */ +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +typedef __packed struct _evt_att_read_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ +} PACKED evt_att_read_resp; + +/** + * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). + * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. + */ +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +typedef __packed struct _evt_att_read_blob_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ +} PACKED evt_att_read_blob_resp; + +/** + * This event is generated in response to a @a Read @a Multiple @a Request. + * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. + */ +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +typedef __packed struct _evt_att_read_mult_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ +} PACKED evt_att_read_mult_resp; + +/** + * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). + * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. + */ +#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) +typedef __packed struct _evt_att_read_by_group_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_data_length; /**< The size of each Attribute Data. */ + /** + * A list of Attribute Data where the attribute data is composed by: + * @li 2 octets for Attribute Handle + * @li 2 octets for End Group Handle + * @li (attribute_data_length - 4) octets for Attribute Value + */ + uint8_t attribute_data_list[VARIABLE_SIZE]; +} PACKED evt_att_read_by_group_resp; + +/** + * This event is generated in response to a @a Prepare @a Write @a Request. + * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. + */ +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +typedef __packed struct _evt_att_prepare_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attribute_handle; /**< The handle of the attribute to be written. */ + uint16_t offset; /**< The offset of the first octet to be written. */ + uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ +} PACKED evt_att_prepare_write_resp; + +/** + * This event is generated in response to an @a Execute @a Write @a Request. + * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. + */ +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +typedef __packed struct _evt_att_exec_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Always 0. */ +} PACKED evt_att_exec_write_resp; + +/** + * This event is generated when an indication is received from the server. + * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. + */ +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +typedef __packed struct _evt_gatt_indication{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_indication; + +/** + * This event is generated when a notification is received from the server. + * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. + */ +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef __packed struct _evt_gatt_notification{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_attr_notification; + +/** + * This event is generated when a GATT client procedure completes either with error or successfully. + * See @ref _evt_gatt_procedure_complete. + */ +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef __packed struct _evt_gatt_procedure_complete{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ + uint8_t data_length; /**< Length of error_code field (always 1). */ + /** + * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). + */ + uint8_t error_code; +} PACKED evt_gatt_procedure_complete; + +/** + * This event is generated when an Error Response is received from the server. The error response can be given + * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended + * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. + */ +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +typedef __packed struct _evt_gatt_error_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t req_opcode; /**< The request that generated this error response. */ + uint16_t attr_handle; /**< The attribute handle that generated this error response. */ + uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ +} PACKED evt_gatt_error_resp; + +/** + * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using + * Characteristic UUID" procedure. + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. + */ +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + /** + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. + */ + uint8_t attr_value[VARIABLE_SIZE]; +} PACKED evt_gatt_disc_read_char_by_uuid_resp; + +/** + * This event is given to the application when a write request, write command or signed write command + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * If the write is rejected by the application, then the value of the attribute will not be modified. + * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. + * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef __packed struct _evt_gatt_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_write_permit_req; + +/** + * This event is given to the application when a read request or read blob request is received by the server + * from the client. This event will be given to the application only if the event bit for this event generation + * is set when the characteristic was added. + * On receiving this event, the application can update the value of the handle if it desires and when done + * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef __packed struct _evt_gatt_read_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ + uint8_t data_length; /**< Length of offset field. */ + uint16_t offset; /**< Contains the offset from which the read has been requested */ +} PACKED evt_gatt_read_permit_req; + +/** + * This event is given to the application when a read multiple request or read by type request is received + * by the server from the client. This event will be given to the application only if the event bit for this + * event generation is set when the characteristic was added. + * On receiving this event, the application can update the values of the handles if it desires and when done + * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_multi_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) +typedef __packed struct _evt_gatt_read_multi_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ +} PACKED evt_gatt_read_multi_permit_req; + +/** + * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2). + * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES. + * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value(). + * See @ref evt_gatt_tx_pool_vailable. + * + */ +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE (0x0C16) +typedef __packed struct _evt_gatt_tx_pool_available{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t available_buffers; /**< Length of data field. */ +} PACKED evt_gatt_tx_pool_available; + +/** + * This event is raised on the server when the client confirms the reception of an indication. + */ +#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT (0x0C17) +typedef __packed struct _evt_gatt_server_confirmation{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ +} PACKED evt_gatt_server_confirmation; +/** + * This event is given to the application when a prepare write request + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * Based on the response from the application, the attribute value will be modified by the stack. + * If the write is rejected by the application, then the value of the attribute will not be modified + * and an error response will be sent to the client, with the error code as specified by the application. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ (0x0C18) +typedef __packed struct _evt_gatt_prepare_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint16_t offset; /**< The offset from which the prepare write has been requested */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_prepare_write_permit_req; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,229 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gatt_server.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GATT server layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BNRG_GATT_SERVER_H__ +#define __BNRG_GATT_SERVER_H__ + +#include "ble_compiler.h" +#include "ble_status.h" + +/** + *@addtogroup GATT GATT + *@{ + */ + +/** + * @anchor Well-Known_UUIDs + * @name Well-Known UUIDs + * @{ + */ +#define PRIMARY_SERVICE_UUID (0x2800) +#define SECONDARY_SERVICE_UUID (0x2801) +#define INCLUDE_SERVICE_UUID (0x2802) +#define CHARACTERISTIC_UUID (0x2803) +#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) +#define CHAR_USER_DESC_UUID (0x2901) +#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) +#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) +#define CHAR_FORMAT_DESC_UUID (0x2904) +#define CHAR_AGGR_FMT_DESC_UUID (0x2905) +#define GATT_SERVICE_UUID (0x1801) +#define GAP_SERVICE_UUID (0x1800) +#define SERVICE_CHANGED_UUID (0x2A05) +/** + * @} + */ + +/** + * @anchor Access_permissions + * @name Access permissions + * Access permissions for an attribute + * @{ + */ +#define ATTR_NO_ACCESS (0x00) +#define ATTR_ACCESS_READ_ONLY (0x01) +#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) +#define ATTR_ACCESS_READ_WRITE (0x03) +#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) +#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) +/** + * Allows all write procedures + */ +#define ATTR_ACCESS_WRITE_ANY (0x0E) +/** + * @} + */ + +/** + * @anchor Char_properties + * @name Characteristic properties. + * @{ + */ +#define CHAR_PROP_BROADCAST (0x01) +#define CHAR_PROP_READ (0x02) +#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) +#define CHAR_PROP_WRITE (0x08) +#define CHAR_PROP_NOTIFY (0x10) +#define CHAR_PROP_INDICATE (0x20) +#define CHAR_PROP_SIGNED_WRITE (0x40) +#define CHAR_PROP_EXT (0x80) +/** + * @} + */ + + +/** + * @anchor Security_permissions + * @name Security permissions for an attribute. + * @{ + */ +#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ +#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ +#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ +#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ +/** + * @} + */ + +/** + * @anchor UUID_Types + * @name Type of UUID (16 bit or 128 bit). + * @{ + */ +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) +/** + * @} + */ + +/** + * @anchor Service_type + * @name Type of service (primary or secondary) + * @{ + */ +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) +/** + * @} + */ + +/** + * @anchor Gatt_Event_Mask + * @name Gatt Event Mask + * Type of event generated by GATT server + * @{ + */ +#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ +#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. + An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ +#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd + or a signed write cmd are received by the server for this attribute. + An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ +#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is + received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ +/** + * @} + */ + +/** + * @name Type of characteristic length + * See aci_gatt_add_char() + * @{ + */ +#define CHAR_VALUE_LEN_CONSTANT (0x00) +#define CHAR_VALUE_LEN_VARIABLE (0x01) +/** + * @} + */ + + +/** + * @name Encryption key size + * @{ + */ +/** + * Minimum encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Maximum encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) +/** + * @} + */ + +/** + * @name Characteristic Presentation Format + * @{ + */ +typedef __packed struct _charactFormat { + uint8_t format; + int8_t exp; + uint16_t unit; + uint8_t name_space; + uint16_t desc; +} PACKED charactFormat; + +/** + * @} + */ + +/** + * @name Format + * @{ + */ +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F +/** + * @} + */ + +/** + * @name Unit + * @{ + */ +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 +/** + * @} + */ + + +/** + * ATT MTU size + */ +#define ATT_MTU (23) + +/** + * @} + */ + + /** + * @name Update type of aci_gatt_upd_char_val_ext(). + * @{ + */ + +#define NOTIFICATION 1 +#define INDICATION 2 + +#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,385 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hal_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with HCI commands for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_HAL_ACI_H__ +#define __BLUENRG_HAL_ACI_H__ + +/** + *@addtogroup HAL HAL + *@brief Hardware Abstraction Layer. + *@{ + */ + +/** + * @defgroup HAL_Functions HAL functions + * @brief API for BlueNRG HAL layer. + * @{ + */ + +/** + * @brief This command retrieves the buid number of the firmware. + * @param[out] build_number Build number identifying the firmware release. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number); + +/** + * @brief This command writes a value to a low level configure data structure. + * @note It is useful to setup directly some low level parameters for the system at runtime. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * + * @param len Length of data to be written + * @param[out] val Data to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val); + +/** + * @brief This command requests the value in the low level configure data structure. + * The number of read bytes changes for different Offset. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * @param data_len Length of the data buffer + * @param[out] data_len_out_p length of the data returned by the read. + * @param[out] data Read data + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data); + +/** + * @brief This command sets the TX power level of the BlueNRG. + * @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines + * the output power level (dBm). + * When the system starts up or reboots, the default TX power level will be used, which is + * the maximum value of 8dBm. Once this command is given, the output power will be changed + * instantly, regardless if there is Bluetooth communication going on or not. For example, + * for debugging purpose, the BlueNRG can be set to advertise all the time and use this + * command to observe the signal strength changing. The system will keep the last received + * TX power level from the command, i.e. the 2nd command overwrites the previous TX power + * level. The new TX power level remains until another Set TX Power command, or the system + * reboots.\n + * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the + * right value, depending on the selected hardware configuration for the RF network: + * normal mode or high power mode. + * @param pa_level Can be from 0 to 7. Set the PA level value. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +/** + * @brief This command returns the number of packets sent in Direct Test Mode. + * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets + * have been transmitted. This command can be used to check how many packets have been sent + * during the Direct TX test.\n + * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again. + * The counter is not cleared until the next Direct TX test starts. + * @param[out] number_of_packets Number of packets sent during the last Direct TX test. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets); + +/** + * @brief Put the device in standby mode. + * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the + * device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode, + * the device can still wake up itself with the internal timer. But in standby mode, this timer is + * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command + * sent via SPI bus. + * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code + * ERR_COMMAND_DISALLOWED will be returned. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_device_standby(void); + +/** + * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. + * @note The frequency sine wave at the specific channel may be used for test purpose only. + * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. + * This command shouldn't be used when normal Bluetooth activities are ongoing. + * The tone should be stopped by aci_hal_tone_stop() command. + * + * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the + * channel central frequency minus 250 kHz. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +/** + * This command is used to stop the previously started aci_hal_tone_start() command. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_stop(void); + +/** + * @brief This command returns the status of all the connections. + * @note This command returns the status of the 8 Bluetooth low energy links managed by the device. + * @param[out] link_status Array of link status (8 links). See @ref Link_Status. + * @param[out] conn_handle Array of connection handles for each link. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]); + +/** + * @brief This command returns the anchor period and the largest available slot. + * @note This command returns information about the anchor period to help application in selecting + * slot timings when operating in multi-link scenarios. + * @param anchor_period Current anchor period (multiple of 0.625 ms). + * @param max_free_slot Maximum available time (multiple of 0.625 ms) that can be allocated for a new slot. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot); + +/** + * @} + */ + +/** + * @defgroup HAL_Events HAL events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_HAL_INITIALIZED (0x0001) +typedef __packed struct _evt_hal_initialized{ + uint8_t reason_code; /**< Reset reason. See @ref Reset_Reasons */ +} PACKED evt_hal_initialized; + +/** + * This event is generated when an overflow occurs in the event queue read by the external microcontroller. + * This is normally caused when the external microcontroller does not read pending events. + * The returned bitmap indicates which event has been lost. Please note that one bit set to 1 indicates one or + * more occurrences of the particular events. The event EVT_BLUE_HAL_EVENTS_LOST cannot be lost and it will + * be inserted in the event queue as soon as a position is freed in the event queue. This event should not + * happen under normal operating condition where external microcontroller promptly reads events signaled by + * IRQ pin. It is provided to detected unexpected behavior of the external microcontroller or to allow + * application to recover situations where critical events are lost. + */ +#define EVT_BLUE_HAL_EVENTS_LOST_IDB05A1 (0x0002) +typedef __packed struct _evt_hal_events_lost{ + uint8_t lost_events[8]; /**< Bitmap of lost events. Each bit indicates one or more occurrences of the specific event. See @ref Lost_Events */ +} PACKED evt_hal_events_lost_IDB05A1; + + +/** + * This event is given to the application after the @ref ACI_BLUE_INITIALIZED_EVENT + * when a system crash is detected. This events returns system crash information for debugging purposes. + * Information reported are useful to understand the root cause of the crash. + */ +#define EVT_BLUE_HAL_CRASH_INFO_IDB05A1 (0x0003) +typedef __packed struct _evt_hal_crash_info{ + uint8_t crash_type; /**< Type of crash: Assert failed (0), NMI Fault (1), Hard Fault (2) */ + uint32_t sp; /**< SP register */ + uint32_t r0; /**< R0 register */ + uint32_t r1; /**< R1 register */ + uint32_t r2; /**< R2 register */ + uint32_t r3; /**< R3 register */ + uint32_t r12; /**< R12 register */ + uint32_t lr; /**< LR register */ + uint32_t pc; /**< PC register */ + uint32_t xpsr; /**< xPSR register */ + uint8_t debug_data_len; /**< length of debug_data field */ + uint8_t debug_data[VARIABLE_SIZE]; /**< Debug data */ +} PACKED evt_hal_crash_info_IDB05A1; + + +/** + * @} + */ + + +/** + * @anchor Reset_Reasons + * @name Reset Reasons + * See @ref EVT_BLUE_HAL_INITIALIZED. + * @{ + */ +#define RESET_NORMAL 1 /**< Normal startup. */ +#define RESET_UPDATER_ACI 2 /**< Updater mode entered with ACI command */ +#define RESET_UPDATER_BAD_FLAG 3 /**< Updater mode entered due to a bad BLUE flag */ +#define RESET_UPDATER_PIN 4 /**< Updater mode entered with IRQ pin */ +#define RESET_WATCHDOG 5 /**< Reset caused by watchdog */ +#define RESET_LOCKUP 6 /**< Reset due to lockup */ +#define RESET_BROWNOUT 7 /**< Brownout reset */ +#define RESET_CRASH 8 /**< Reset caused by a crash (NMI or Hard Fault) */ +#define RESET_ECC_ERR 9 /**< Reset caused by an ECC error */ +/** + * @} + */ + + +/** + * @defgroup Config_vals Offsets and lengths for configuration values. + * @brief Offsets and lengths for configuration values. + * See aci_hal_write_config_data(). + * @{ + */ + +/** + * @name Configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ +#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ +#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ +#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ +#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. + It can be written only if aci_hal_write_config_data() is the first command after reset. */ +#define CONFIG_DATA_RANDOM_ADDRESS (0x80) /**< Stored static random address. Read-only. */ + +/** + * Select the BlueNRG mode configurations.\n + * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) + * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) + * @li Mode 3: master/slave, 8 connections, RAM1 and RAM2. + * @li Mode 4: master/slave, 4 connections, RAM1 and RAM2 simultaneous scanning and advertising. + */ +#define CONFIG_DATA_MODE_OFFSET (0x2D) + +#define CONFIG_DATA_WATCHDOG_DISABLE (0x2F) /**< Set to 1 to disable watchdog. It is enabled by default. */ +/** + * @} + */ + +/** + * @name Length for configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_LEN (6) +#define CONFIG_DATA_DIV_LEN (2) +#define CONFIG_DATA_ER_LEN (16) +#define CONFIG_DATA_IR_LEN (16) +#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) +#define CONFIG_DATA_MODE_LEN (1) +#define CONFIG_DATA_WATCHDOG_DISABLE_LEN (1) +/** + * @} + */ + +/** + * @anchor Link_Status + * @name Status of the link + * See @ref aci_hal_get_link_status(). + * @{ + */ +#define STATUS_IDLE 0 +#define STATUS_ADVERTISING 1 +#define STATUS_CONNECTED_AS_SLAVE 2 +#define STATUS_SCANNING 3 +#define STATUS_CONNECTED_AS_MASTER 5 +#define STATUS_TX_TEST 6 +#define STATUS_RX_TEST 7 +/** + * @} + */ + +/** + * @} + */ + + /** + * @anchor Lost_Events + * @name Lost events bitmap + * See @ref EVT_BLUE_HAL_EVENTS_LOST. + * @{ + */ +#define EVT_DISCONN_COMPLETE_BIT 0 +#define EVT_ENCRYPT_CHANGE_BIT 1 +#define EVT_READ_REMOTE_VERSION_COMPLETE_BIT 2 +#define EVT_CMD_COMPLETE_BIT 3 +#define EVT_CMD_STATUS_BIT 4 +#define EVT_HARDWARE_ERROR_BIT 5 +#define EVT_NUM_COMP_PKTS_BIT 6 +#define EVT_ENCRYPTION_KEY_REFRESH_BIT 7 +#define EVT_BLUE_HAL_INITIALIZED_BIT 8 +#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE_BIT 9 +#define EVT_BLUE_GAP_PAIRING_CMPLT_BIT 10 +#define EVT_BLUE_GAP_PASS_KEY_REQUEST_BIT 11 +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST_BIT 12 +#define EVT_BLUE_GAP_SECURITY_REQ_INITIATED_BIT 13 +#define EVT_BLUE_GAP_BOND_LOST_BIT 14 +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE_BIT 15 +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_BIT 16 +#define EVT_BLUE_L2CAP_CONN_UPDATE_RESP_BIT 17 +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT_BIT 18 +#define EVT_BLUE_L2CAP_CONN_UPDATE_REQ_BIT 19 +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_BIT 20 +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT_BIT 21 +#define EVT_BLUE_EXCHANGE_MTU_RESP_BIT 22 +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP_BIT 23 +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP_BIT 24 +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP_BIT 25 +#define EVT_BLUE_ATT_READ_RESP_BIT 26 +#define EVT_BLUE_ATT_READ_BLOB_RESP_BIT 27 +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP_BIT 28 +#define EVT_BLUE_ATT_READ_BY_GROUP_RESP_BIT 29 +#define EVT_BLUE_ATT_WRITE_RESP_BIT 30 +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP_BIT 31 +#define EVT_BLUE_ATT_EXEC_WRITE_RESP_BIT 32 +#define EVT_BLUE_GATT_INDICATION_BIT 33 +#define EVT_BLUE_GATT_NOTIFICATION_BIT 34 +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE_BIT 35 +#define EVT_BLUE_GATT_ERROR_RESP_BIT 36 +#define EVT_BLUE_GATT_DISC_READ_CHARAC_BY_UUID_RESP_BIT 37 +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ_BIT 38 +#define EVT_BLUE_GATT_READ_PERMIT_REQ_BIT 39 +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ_BIT 40 +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_BIT 41 +#define EVT_BLUE_GATT_SERVER_RX_CONFIRMATION_BIT 42 +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ_BIT 43 +#define EVT_LL_CONNECTION_COMPLETE_BIT 44 +#define EVT_LL_ADVERTISING_REPORT_BIT 45 +#define EVT_LL_CONNECTION_UPDATE_COMPLETE_BIT 46 +#define EVT_LL_READ_REMOTE_USED_FEATURES_BIT 47 +#define EVT_LL_LTK_REQUEST_BIT 48 +/** + * @} + */ + +/** + * @name Hardware error event codes + * See @ref EVT_HARDWARE_ERROR. + * @{ + */ +/** + * Error on the SPI bus has been detected, most likely caused by incorrect SPI configuration on the external micro-controller. + */ +#define SPI_FRAMING_ERROR 0 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define RADIO_STATE_ERROR 1 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define TIMER_OVERRUN_ERROR 2 + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,166 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_l2cap_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with L2CAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_L2CAP_ACI_H__ +#define __BLUENRG_L2CAP_ACI_H__ + +/** + *@addtogroup L2CAP L2CAP + *@brief L2CAP layer. + *@{ + */ + +/** + *@defgroup L2CAP_Functions L2CAP functions + *@brief API for L2CAP layer. + *@{ + */ + +/** + * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. + * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request + * (accepts or rejects). + * @param conn_handle Connection handle on which the connection parameter update request has to be sent. + * @param interval_min Defines minimum value for the connection event interval in the following manner: + * connIntervalMin = interval_min x 1.25ms + * @param interval_max Defines maximum value for the connection event interval in the following manner: + * connIntervalMax = interval_max x 1.25ms + * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). + * @param timeout_multiplier Defines connection timeout parameter in the following manner: + * timeout_multiplier x 10ms. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier); +/** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param min_ce_length Minimum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_ce_length Maximum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept); + /** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept); + +/** + * @} + */ + +/** + * @defgroup L2CAP_Events L2CAP events + * @{ + */ + +/** + * This event is generated when the master responds to the L2CAP connection update request packet. + * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. + */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef __packed struct _evt_l2cap_conn_upd_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ +/** + * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. + * @li 0x01 in case of Command Reject. + */ + uint8_t code; + uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ + uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ +/** + * Result code (parameters accepted or rejected) in case of Connection Parameter Update + * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). + */ + uint16_t result; +} PACKED evt_l2cap_conn_upd_resp; + +/** + * This event is generated when the master does not respond to the connection update request + * within 30 seconds. + */ +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) +typedef __packed struct _evt_l2cap_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */ +} PACKED evt_l2cap_procedure_timeout; + +/** + * The event is given by the L2CAP layer when a connection update request is received from the slave. + * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). + */ +#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) +typedef __packed struct _evt_l2cap_conn_upd_req{ +/** + * Handle of the connection for which the connection update request has been received. + * The same handle has to be returned while responding to the event with the command + * aci_l2cap_connection_parameter_update_response(). + */ + uint16_t conn_handle; + uint8_t event_data_length; /**< Length of following data. */ +/** + * This is the identifier which associates the request to the + * response. The same identifier has to be returned by the upper + * layer in the command aci_l2cap_connection_parameter_update_response(). + */ + uint8_t identifier; + uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ + uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ +} PACKED evt_l2cap_conn_upd_req; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_updater_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with updater commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_UPDATER_ACI_H__ +#define __BLUENRG_UPDATER_ACI_H__ + +#include <ble_compiler.h> + +/** + * @defgroup Updater Updater + * @brief Updater. + * @{ + */ + +/** + * @defgroup Updater_Functions Updater functions + * @brief API for BlueNRG Updater. + * @{ + */ + +tBleStatus aci_updater_start(void); + +tBleStatus aci_updater_reboot(void); + +tBleStatus aci_get_updater_version(uint8_t *version); + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); + +tBleStatus aci_erase_blue_flag(void); + +tBleStatus aci_reset_blue_flag(void); + +tBleStatus aci_updater_erase_sector(uint32_t address); + +tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); + +tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); + +tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); + +tBleStatus aci_updater_hw_version(uint8_t *version); + +/** + * @} + */ + +/** + * @defgroup Updater_Events Updater events + * @{ + */ +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_INITIALIZED (0x0001) +typedef __packed struct _evt_blue_initialized{ + uint8_t reason_code; +} PACKED evt_blue_initialized; +/** + * @} + */ + +/** + * @} + */ + + + +#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,204 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_utils.h +* Author : AMS - VMA, RF Application Team +* Version : V1.0.1 +* Date : 03-October-2014 +* Description : Header file for BlueNRG utility functions +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + * @file bluenrg_utils.h + * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description + * + * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> +**/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLUENRG_UTILS_H +#define __BLUENRG_UTILS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ble_hal_types.h" +#include "ble_compiler.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct{ + uint8_t stack_mode; + uint8_t day; + uint8_t month; + uint8_t year; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint16_t hs_startup_time; /* In system time units*/ +} IFR_config2_TypeDef; + +/** + * Structure inside IFR for configuration options. + */ +typedef __packed struct{ + uint8_t cold_ana_act_config_table[64]; + uint8_t hot_ana_config_table[64]; + uint8_t stack_mode; + uint8_t gpio_config; + uint8_t rsrvd1[2]; + uint32_t rsrvd2[3]; + uint32_t max_conn_event_time; + uint32_t ls_crystal_period; + uint32_t ls_crystal_freq; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint8_t rsrvd3; + uint16_t hs_startup_time; /* In system time units*/ + uint8_t rsrvd4[2]; + uint32_t uid; + uint8_t rsrvd5; + uint8_t year; + uint8_t month; + uint8_t day; + uint32_t unused[5]; +} PACKED IFR_config_TypeDef; + +/* Exported constants --------------------------------------------------------*/ +extern const IFR_config_TypeDef IFR_config; + +/* Exported macros -----------------------------------------------------------*/ +#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)+1) +#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) + +/* Convert 2 digit BCD number to an integer */ +#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) + +/* Convert 2 digit number to a BCD number */ +#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) + +/** + * Return values + */ +#define BLE_UTIL_SUCCESS 0 +#define BLE_UTIL_UNSUPPORTED_VERSION 1 +#define BLE_UTIL_WRONG_IMAGE_SIZE 2 +#define BLE_UTIL_ACI_ERROR 3 +#define BLE_UTIL_CRC_ERROR 4 +#define BLE_UTIL_PARSE_ERROR 5 +#define BLE_UTIL_WRONG_VERIFY 6 + +/* Exported functions ------------------------------------------------------- */ +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int program_device(const uint8_t *fw_image, uint32_t fw_size); + +/** + * @brief Read raw data from IFR (3 64-bytes blocks). + * @param data Pointer to the buffer that will contain the read data. + * Its size must be 192 bytes. This data can be parsed by + * parse_IFR_data_config(). + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION) + */ +int read_IFR(uint8_t data[192]); + +/** + * @brief Verify raw data from IFR (3 64-bytes blocks). + * @param ifr_data Pointer to the buffer that will contain the data to verify. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) + */ +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); + +/** + * @brief Program raw data to IFR (3 64-bytes blocks). + * @param ifr_image Pointer to the buffer that will contain the data to program. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful + */ +int program_IFR(const IFR_config_TypeDef *ifr_image); + +/** + * @brief Parse IFR raw data. + * @param data Pointer to the raw data: last 64 bytes read from IFR sector. + * @param IFR_config Data structure that will be filled with parsed data. + * @retval None + */ +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); + +/** + * @brief Check for the correctness of parsed data. + * @param IFR_config Data structure filled with parsed data. + * @retval int It returns 0 if successful, or PARSE_ERROR in case data is + * not correct. + */ +int IFR_validate(IFR_config2_TypeDef *IFR_config); + +/** + * @brief Modify IFR data. (Last 64-bytes block). + * @param IFR_config Structure that contains the new parameters inside the + * IFR configuration data. + * @note It is highly recommended to parse the IFR configuration from + * a working IFR block (this should be done with parse_IFR_data_config()). + * Then it is possible to write the new parameters inside the IFR_config + * structure. + * @param data Pointer to the buffer that contains the original data. It + * will be modified according to the new data in the IFR_config + * structure. Then this data must be written in the last + * 64-byte block in the IFR. + * Its size must be 64 bytes. + * @retval None + */ +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); + +/** + * @brief Get BlueNRG hardware and firmware version + * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). + * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN + * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. + * @retval Status of the call + */ +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); + +/** + * @brief Get BlueNRG updater version + * @param version This parameter returns the updater version. If the updadter version is 0x03 + * the chip has the updater old, needs to update the bootloader. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterVersion(uint8_t *version); + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version); + +/** + * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on + * the HW bootloader related to the 32 MHz external crystal oscillator. + * @retval TRUE if the HW bootloader is already patched, FALSE otherwise + */ +uint8_t isHWBootloader_Patched(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__BLUENRG_UTILS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file bluenrg_targets.h + * @author AST / EST + * @version V0.0.1 + * @date 24-July-2015 + * @brief This header file is intended to manage the differences between + * the different supported base-boards which might mount the + * X_NUCLEO_IDB0XA1 BlueNRG BLE Expansion Board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent from recursive inclusion --------------------------------*/ +#ifndef _BLUENRG_TARGETS_H_ +#define _BLUENRG_TARGETS_H_ + +#if !defined(BLUENRG_PIN_SPI_MOSI) +#define BLUENRG_PIN_SPI_MOSI (D11) +#endif +#if !defined(BLUENRG_PIN_SPI_MISO) +#define BLUENRG_PIN_SPI_MISO (D12) +#endif +#if !defined(BLUENRG_PIN_SPI_nCS) +#define BLUENRG_PIN_SPI_nCS (A1) +#endif +#if !defined(BLUENRG_PIN_SPI_RESET) +#define BLUENRG_PIN_SPI_RESET (D7) +#endif +#if !defined(BLUENRG_PIN_SPI_IRQ) +#define BLUENRG_PIN_SPI_IRQ (A0) +#endif + +/* NOTE: Refer to README for further details regarding BLUENRG_PIN_SPI_SCK */ +#if !defined(BLUENRG_PIN_SPI_SCK) +#define BLUENRG_PIN_SPI_SCK (D3) +#endif + +/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv) + * Mode 0x01: slave or master, 1 connection + * Mode 0x02: slave or master, 1 connection + * Mode 0x03: master/slave, 8 connections + * Mode 0x04: master/slave, 4 connections (simultaneous scanning and advertising) + * Check Table 285 of + * BlueNRG-MS Bluetooth LE stack application command interface (ACI) User Manual (UM1865) at st.com + */ +#if !defined(BLUENRG_STACK_MODE) +#define BLUENRG_STACK_MODE (0x04) +#endif + +#endif // _BLUENRG_TARGTES_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef _BTLE_H_ +#define _BTLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "bluenrg_aci.h" +#include "ble_hci_const.h" +#include "bluenrg_hal_aci.h" +#include "stm32_bluenrg_ble.h" +#include "bluenrg_gap.h" +#include "bluenrg_gatt_server.h" + +extern uint16_t g_gap_service_handle; +extern uint16_t g_appearance_char_handle; +extern uint16_t g_device_name_char_handle; +extern uint16_t g_preferred_connection_parameters_char_handle; + +void btleInit(void); +void SPI_Poll(void); +void User_Process(void); +void setConnectable(void); +void setVersionString(uint8_t hwVersion, uint16_t fwVersion); +const char* getVersionString(void); +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type); + + +extern int btle_handler_pending; +extern void btle_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.h + * @author CL + * @version V1.0.1 + * @date 15-June-2014 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_BLUENRG_BLE_H +#define __STM32_BLUENRG_BLE_H + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdint.h> +#include "ble_gp_timer.h" +#include "ble_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup X-NUCLEO-IDB04A1 + * @{ + */ + +/** @addtogroup STM32_BLUENRG_BLE + * @{ + */ + +/** @defgroup STM32_BLUENRG_BLE_Exported_Functions + * @{ + */ + +// FIXME: add prototypes for BlueNRG here +void BlueNRG_RST(void); +uint8_t BlueNRG_DataPresent(void); +void BlueNRG_HW_Bootloader(void); +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size); +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, + uint8_t Nb_bytes1, + uint8_t Nb_bytes2); +void Clear_SPI_EXTI_Flag(void); + +void print_csv_time(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_BLUENRG_BLE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_debug.h" + +#ifndef __PAYLOAD_H__ +#define __PAYLOAD_H__ + +class UnitPayload +{ +public: + uint8_t length; + uint8_t id; + uint8_t *data; + uint8_t *idptr; + + + + void set_length(uint8_t l) { + length=l; + } + + void set_id(uint8_t i) { + id=i; + } + + void set_data(uint8_t* data1) { + for(int j=0;j<length;j++) + { + data[j]=data1[j]; + } + } + + uint8_t get_length() { + return length; + } + + uint8_t get_id() { + return id; + } + + uint8_t* get_data() { + return data; + } + +}; + +class Payload { + UnitPayload *payload; + int stringLength; + int payloadUnitCount; + +public: + Payload(const uint8_t *tokenString, uint8_t string_ength); + Payload(); + ~Payload(); + uint8_t getPayloadUnitCount(); + + uint8_t getIDAtIndex(int index); + uint8_t getLengthAtIndex(int index); + uint8_t* getDataAtIndex(int index); + int8_t getInt8AtIndex(int index); + uint16_t getUint16AtIndex(int index); + uint8_t* getSerializedAdDataAtIndex(int index); +}; + + +class PayloadUnit { +private: + uint8_t* lenPtr; + uint8_t* adTypePtr; + uint8_t* dataPtr; + +public: + PayloadUnit() { + lenPtr = NULL; + adTypePtr = NULL; + dataPtr = NULL; + } + + PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { + lenPtr = len; + adTypePtr = adType; + dataPtr = data; + } + + void setLenPtr(uint8_t *len) { + lenPtr = len; + } + + void setAdTypePtr(uint8_t *adType) { + adTypePtr = adType; + } + + void setDataPtr(uint8_t *data) { + dataPtr = data; + } + + uint8_t* getLenPtr() { + return lenPtr; + } + + uint8_t* getAdTypePtr() { + return adTypePtr; + } + + uint8_t* getDataPtr() { + return dataPtr; + } + + void printDataAsHex() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("0x%x ", dataPtr[i]); + } + PRINTF("\n"); + } + + void printDataAsString() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("%c", dataPtr[i]); + } + PRINTF("\n"); + } + +}; + +class PayloadPtr { +private: + PayloadUnit *unit; + int payloadUnitCount; +public: + PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + int stringLength = string_ength; + payloadUnitCount = 0; + + int index = 0; + while(index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + // allocate memory to unit + unit = new PayloadUnit[payloadUnitCount]; + int i = 0; + int nextUnitOffset = 0; + + while(i<payloadUnitCount) { + unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); + unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); + unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); + + nextUnitOffset += *unit[i].getLenPtr()+1; + i++; + + } + } + + PayloadUnit getUnitAtIndex(int index) { + return unit[index]; + } + + int getPayloadUnitCount() { return payloadUnitCount; } + + ~PayloadPtr() { + if(unit) delete[] unit; + + unit = NULL; + } +}; + +#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include "ble_status.h" +#include "ble_hal_types.h" + +#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do {\ + uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ + }while(0) + + +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); + +#endif // __UTIL_H__ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/mbed_lib.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,16 @@ +{ + "name": "bluenrg", + "target_overrides": { + "K64F": { + "target.macros_add": ["BLUENRG_PIN_SPI_SCK=D13"] + }, + "DISCO_L475VG_IOT01A": { + "target.macros_add": ["BLUENRG_PIN_SPI_MOSI=PC_12", + "BLUENRG_PIN_SPI_MISO=PC_11", + "BLUENRG_PIN_SPI_nCS=PD_13", + "BLUENRG_PIN_SPI_RESET=PA_8", + "BLUENRG_PIN_SPI_IRQ=PE_6", + "BLUENRG_PIN_SPI_SCK=PC_10"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/module.json Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,37 @@ +{ + "name": "x-nucleo-idb0xa1", + "version": "2.2.0", + "description": "ST driver for the mbed BLE API.", + "keywords": [ + "expansion", + "board", + "x-nucleo", + "nucleo", + "ST", + "STM", + "Bluetooth", + "BLE" + ], + "author": "Andrea Palmieri", + "repository": { + "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git", + "type": "git" + }, + "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "extraIncludes": [ + "x-nucleo-idb0xa1", + "x-nucleo-idb0xa1/utils", + "x-nucleo-idb0xa1/platform", + "x-nucleo-idb0xa1/bluenrg-hci" + ], + "dependencies": { + "mbed-drivers": ">=0.11.3", + "ble": "^2.7.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,474 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + ****************************************************************************** + * @file BlueNRGDevice.cpp + * @author STMicroelectronics + * @brief Implementation of BLEDeviceInstanceBase + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGDevice + * @brief BlueNRG BLE_API Device Adaptation + * @{ + */ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGDevice.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" + +#include "btle.h" +#include "ble_utils.h" +#include "ble_osal.h" + +#include "ble_debug.h" +#include "stm32_bluenrg_ble.h" + +extern "C" { + #include "ble_hci.h" + #include "bluenrg_utils.h" +} + +#define HEADER_SIZE 5 +#define MAX_BUFFER_SIZE 255 + +/** + * The singleton which represents the BlueNRG transport for the BLEDevice. + * + * See file 'bluenrg_targets.h' for details regarding the peripheral pins used! + */ +#include "bluenrg_targets.h" + +BlueNRGDevice bluenrgDeviceInstance(BLUENRG_PIN_SPI_MOSI, + BLUENRG_PIN_SPI_MISO, + BLUENRG_PIN_SPI_SCK, + BLUENRG_PIN_SPI_nCS, + BLUENRG_PIN_SPI_RESET, + BLUENRG_PIN_SPI_IRQ); + +/** +* BLE-API requires an implementation of the following function in order to +* obtain its transport handle. +*/ +BLEInstanceBase * +createBLEInstance(void) +{ + return (&bluenrgDeviceInstance); +} + +/**************************************************************************/ +/** + @brief Constructor + * @param mosi mbed pin to use for MOSI line of SPI interface + * @param miso mbed pin to use for MISO line of SPI interface + * @param sck mbed pin to use for SCK line of SPI interface + * @param cs mbed pin to use for not chip select line of SPI interface + * @param rst mbed pin to use for BlueNRG reset + * @param irq mbed pin for BlueNRG IRQ +*/ +/**************************************************************************/ +BlueNRGDevice::BlueNRGDevice(PinName mosi, + PinName miso, + PinName sck, + PinName cs, + PinName rst, + PinName irq) : + isInitialized(false), spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq) +{ + // Setup the spi for 8 bit data, low clock polarity, + // 1-edge phase, with an 8MHz clock rate + spi_.format(8, 0); + spi_.frequency(8000000); + + // Deselect the BlueNRG chip by keeping its nCS signal high + nCS_ = 1; + + wait_us(500); + + // Prepare communication between the host and the BlueNRG SPI interface + HCI_Init(); + + // Set the interrupt handler for the device + irq_.mode(PullDown); // set irq mode + irq_.rise(&HCI_Isr); +} + +/**************************************************************************/ +/** + @brief Destructor +*/ +/**************************************************************************/ +BlueNRGDevice::~BlueNRGDevice(void) +{ +} + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param hw_version The HW version is written to this parameter + * @retval It returns BLE_STATUS_SUCCESS on success or an error code otherwise + */ +uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *hw_version) +{ + uint8_t status; + + status = getBlueNRGUpdaterHWVersion(hw_version); + + return (status); +} + +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns BLE_STATUS_SUCCESS on success, or a number + * not equal to 0 in case of error + * (ACI_ERROR, UNSUPPORTED_VERSION, WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size) +{ + int status = program_device(fw_image, fw_size); + + return (status); +} + + +/** + * @brief Initialises anything required to start using BLE + * @param[in] instanceID + * The ID of the instance to initialize. + * @param[in] callback + * A callback for when initialization completes for a BLE + * instance. This is an optional parameter set to NULL when not + * supplied. + * + * @return BLE_ERROR_NONE if the initialization procedure was started + * successfully. + */ +ble_error_t BlueNRGDevice::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> callback) +{ + if (isInitialized) { + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_ALREADY_INITIALIZED + }; + callback.call(&context); + return BLE_ERROR_ALREADY_INITIALIZED; + } + + // Init the BlueNRG/BlueNRG-MS stack + btleInit(); + + isInitialized = true; + BLE::InitializationCompleteCallbackContext context = { + BLE::Instance(instanceID), + BLE_ERROR_NONE + }; + callback.call(&context); + + return BLE_ERROR_NONE; +} + + +/** + @brief Resets the BLE HW, removing any existing services and + characteristics + @param[in] void + @returns void +*/ +void BlueNRGDevice::reset(void) +{ + /* Reset BlueNRG SPI interface. Hold reset line to 0 for 1500us */ + rst_ = 0; + wait_us(1500); + rst_ = 1; + + /* Wait for the radio to come back up */ + wait_us(5000); +} + +/*! + @brief Wait for any BLE Event like BLE Connection, Read Request etc. + @param[in] void + @returns char * +*/ +void BlueNRGDevice::waitForEvent(void) +{ + bool must_return = false; + + do { + bluenrgDeviceInstance.processEvents(); + + if(must_return) return; + + __WFE(); /* it is recommended that SEVONPEND in the + System Control Register is NOT set */ + must_return = true; /* after returning from WFE we must guarantee + that conrol is given back to main loop before next WFE */ + } while(true); + +} + +/*! + @brief get GAP version + @brief Get the BLE stack version information + @param[in] void + @returns char * + @returns char * +*/ +const char *BlueNRGDevice::getVersion(void) +{ + return getVersionString(); +} + +/**************************************************************************/ +/*! + @brief get reference to GAP object + @param[in] void + @returns Gap& +*/ +/**************************************************************************/ +Gap &BlueNRGDevice::getGap() +{ + return BlueNRGGap::getInstance(); +} + +const Gap &BlueNRGDevice::getGap() const +{ + return BlueNRGGap::getInstance(); +} + +/**************************************************************************/ +/*! + @brief get reference to GATT server object + @param[in] void + @returns GattServer& +*/ +/**************************************************************************/ +GattServer &BlueNRGDevice::getGattServer() +{ + return BlueNRGGattServer::getInstance(); +} + +const GattServer &BlueNRGDevice::getGattServer() const +{ + return BlueNRGGattServer::getInstance(); +} + +/**************************************************************************/ +/*! + @brief shut down the BLE device + @param[out] error if any +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::shutdown(void) { + PRINTF("BlueNRGDevice::reset\n"); + + if (!isInitialized) { + return BLE_ERROR_INITIALIZATION_INCOMPLETE; + } + + /* Reset the BlueNRG device first */ + reset(); + + /* Shutdown the BLE API and BlueNRG glue code */ + ble_error_t error; + + /* GattServer instance */ + error = BlueNRGGattServer::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* GattClient instance */ + error = BlueNRGGattClient::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + /* Gap instance */ + error = BlueNRGGap::getInstance().reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + + isInitialized = false; + + PRINTF("BlueNRGDevice::reset complete\n"); + return BLE_ERROR_NONE; + +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size) +{ + uint16_t byte_count; + uint8_t len = 0; + uint8_t char_ff = 0xff; + volatile uint8_t read_char; + + uint8_t i = 0; + volatile uint8_t tmpreg; + + uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00}; + uint8_t header_slave[HEADER_SIZE]; + + /* Select the chip */ + nCS_ = 0; + + /* Read the header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = (uint8_t)(tmpreg); + } + + if (header_slave[0] == 0x02) { + /* device is ready */ + byte_count = (header_slave[4]<<8)|header_slave[3]; + + if (byte_count > 0) { + + /* avoid to read more data that size of the buffer */ + if (byte_count > buff_size){ + byte_count = buff_size; + } + + for (len = 0; len < byte_count; len++){ + read_char = spi_.write(char_ff); + buffer[len] = read_char; + } + } + } + /* Release CS line to deselect the chip */ + nCS_ = 1; + + // Add a small delay to give time to the BlueNRG to set the IRQ pin low + // to avoid a useless SPI read at the end of the transaction + for(volatile int i = 0; i < 2; i++)__NOP(); + +#ifdef PRINT_CSV_FORMAT + if (len > 0) { + print_csv_time(); + for (int i=0; i<len; i++) { + PRINT_CSV(" %02x", buffer[i]); + } + PRINT_CSV("\n"); + } +#endif + + return len; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRGDevice::spiWrite(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t result = 0; + uint32_t i; + volatile uint8_t tmpreg; + + unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + unsigned char header_slave[HEADER_SIZE] = {0xaa, 0x00, 0x00, 0x00, 0x00}; + + disable_irq(); + + /* CS reset */ + nCS_ = 0; + + /* Exchange header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_.write(header_master[i]); + header_slave[i] = tmpreg; + } + + if (header_slave[0] == 0x02) { + /* SPI is ready */ + if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { + + /* Buffer is big enough */ + for (i = 0; i < Nb_bytes1; i++) { + spi_.write(*(data1 + i)); + } + for (i = 0; i < Nb_bytes2; i++) { + spi_.write(*(data2 + i)); + } + } else { + /* Buffer is too small */ + result = -2; + } + } else { + /* SPI is not ready */ + result = -1; + } + + /* Release CS line */ + //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); + nCS_ = 1; + + enable_irq(); + + return result; +} + +bool BlueNRGDevice::dataPresent() +{ + return (irq_ == 1); +} + +void BlueNRGDevice::disable_irq() +{ + irq_.disable_irq(); +} + +void BlueNRGDevice::enable_irq() +{ + irq_.enable_irq(); +} + +void BlueNRGDevice::processEvents() { + btle_handler(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,68 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattClient.h" + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + uuid = uuidIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + + void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) { + lastHandle = lastHandleIn; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1477 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file BlueNRGGap.cpp + * @author STMicroelectronics + * @brief Implementation of BLE_API Gap Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGap + * @brief BlueNRG BLE_API GAP Adaptation + * @{ + */ + +#include "BlueNRGDevice.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_payload.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/* + * Utility to process GAP specific events (e.g., Advertising timeout) + */ +void BlueNRGGap::Process(void) +{ + if(AdvToFlag) { + AdvToFlag = false; + stopAdvertising(); + } + + if(ScanToFlag) { + ScanToFlag = false; + stopScan(); + } +} + +/**************************************************************************/ +/*! + @brief Sets the advertising parameters and payload for the device. + Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API + + @params[in] advData + The primary advertising data payload + @params[in] scanResponse + The optional Scan Response payload if the advertising + type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED + in \ref GapAdveritinngParams + + @returns \ref ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @retval BLE_ERROR_BUFFER_OVERFLOW + The proposed action would cause a buffer overflow. All + advertising payloads must be <= 31 bytes, for example. + + @retval BLE_ERROR_NOT_IMPLEMENTED + A feature was requested that is not yet supported in the + nRF51 firmware or hardware. + + @retval BLE_ERROR_PARAM_OUT_OF_RANGE + One of the proposed values is outside the valid range. + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) +{ + PRINTF("BlueNRGGap::setAdvertisingData\n\r"); + /* Make sure we don't exceed the advertising payload length */ + if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + PRINTF("Exceeded the advertising payload length\n\r"); + return BLE_ERROR_BUFFER_OVERFLOW; + } + + /* Make sure we have a payload! */ + if (advData.getPayloadLen() != 0) { + PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); + + /* Align the GAP Service Appearance Char value coherently + This setting is duplicate (see below GapAdvertisingData::APPEARANCE) + since BLE API has an overloaded function for appearance + */ + STORE_LE_16(deviceAppearance, advData.getAppearance()); + setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0])); + + + for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { + loadPtr.getUnitAtIndex(index); + + PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); + PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); + + switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { + /**< TX Power Level (in dBm) */ + case GapAdvertisingData::TX_POWER_LEVEL: + { + PRINTF("Advertising type: TX_POWER_LEVEL\n\r"); + int8_t enHighPower = 0; + int8_t paLevel = 0; + + int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); + tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); +#ifdef DEBUG + PRINTF("dbm=%d, ret=%d\n\r", dbm, ret); + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); +#endif + if(ret == BLE_STATUS_SUCCESS) { + aci_hal_set_tx_power_level(enHighPower, paLevel); + } + break; + } + /**< Appearance */ + case GapAdvertisingData::APPEARANCE: + { + PRINTF("Advertising type: APPEARANCE\n\r"); + + GapAdvertisingData::Appearance appearanceP; + memcpy(deviceAppearance, loadPtr.getUnitAtIndex(index).getDataPtr(), 2); + + PRINTF("input: deviceAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + appearanceP = (GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]); + /* Align the GAP Service Appearance Char value coherently */ + setAppearance(appearanceP); + break; + } + + } // end switch + + } //end for + + } + + // update the advertising data in the shield if advertising is running + if (state.advertising == 1) { + tBleStatus ret = hci_le_set_scan_resp_data(scanResponse.getPayloadLen(), scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS != ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + ret = hci_le_set_advertising_data(advData.getPayloadLen(), advData.getPayload()); + if (ret) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + } + + _advData = advData; + _scanResponse = scanResponse; + + return BLE_ERROR_NONE; +} + +/* + * Utility to set ADV timeout flag + */ +void BlueNRGGap::setAdvToFlag(void) { + AdvToFlag = true; + signalEventsToProcess(); +} + +/* + * ADV timeout callback + */ +#ifdef AST_FOR_MBED_OS +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().stopAdvertising(); +} +#else +static void advTimeoutCB(void) +{ + BlueNRGGap::getInstance().setAdvToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getAdvTimeout(); + t.detach(); /* disable the callback from the timeout */ +} +#endif /* AST_FOR_MBED_OS */ + +/* + * Utility to set SCAN timeout flag + */ +void BlueNRGGap::setScanToFlag(void) { + ScanToFlag = true; + signalEventsToProcess(); +} + +static void scanTimeoutCB(void) +{ + BlueNRGGap::getInstance().setScanToFlag(); + + Timeout& t = BlueNRGGap::getInstance().getScanTimeout(); + t.detach(); /* disable the callback from the timeout */ +} + +/**************************************************************************/ +/*! + @brief Starts the BLE HW, initialising any services that were + added before this function was called. + + @param[in] params + Basic advertising details, including the advertising + delay, timeout and how the device should be advertised + + @note All services must be added before calling this function! + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ + +ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) +{ + tBleStatus ret; + int err; + + /* Make sure we support the advertising type */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { + /* ToDo: This requires a proper security implementation, etc. */ + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /* Check interval range */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { + /* Min delay is slightly longer for unconnectable devices */ + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } else { + if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || + (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } + + /* Check timeout is zero for Connectable Directed */ + if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { + /* Timeout must be 0 with this type, although we'll never get here */ + /* since this isn't implemented yet anyway */ + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* Check timeout for other advertising types */ + if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && + (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* + * Advertising filter policy setting + * FIXME: the Security Manager should be implemented + */ + AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode(); + if(mode != ADV_POLICY_IGNORE_WHITELIST) { + ret = aci_gap_configure_whitelist(); + if(ret != BLE_STATUS_SUCCESS) { + PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret); + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } + + uint8_t advFilterPolicy = NO_WHITE_LIST_USE; + switch(mode) { + case ADV_POLICY_FILTER_SCAN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN; + break; + case ADV_POLICY_FILTER_CONN_REQS: + advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN; + break; + case ADV_POLICY_FILTER_ALL_REQS: + advFilterPolicy = WHITE_LIST_FOR_ALL; + break; + default: + advFilterPolicy = NO_WHITE_LIST_USE; + break; + } + + /* Check the ADV type before setting scan response data */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED || + params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) { + + /* set scan response data */ + PRINTF(" setting scan response data (_scanResponseLen=%u)\n", _scanResponse.getPayloadLen()); + ret = hci_le_set_scan_resp_data(_scanResponse.getPayloadLen(), _scanResponse.getPayload()); + + if(BLE_STATUS_SUCCESS!=ret) { + PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); + switch (ret) { + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + } else { + hci_le_set_scan_resp_data(0, NULL); + } + + setAdvParameters(); + PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType()); + + err = hci_le_set_advertising_data(_advData.getPayloadLen(), _advData.getPayload()); + + if (err) { + PRINTF("error while setting the payload\r\n"); + return BLE_ERROR_UNSPECIFIED; + } + + tBDAddr dummy_addr = { 0 }; + uint16_t advIntervalMin = advInterval == GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX ? advInterval - 1 : advInterval; + uint16_t advIntervalMax = advIntervalMin + 1; + + err = hci_le_set_advertising_parameters( + advIntervalMin, + advIntervalMax, + params.getAdvertisingType(), + addr_type, + 0x00, + dummy_addr, + /* all channels */ 7, + advFilterPolicy + ); + + if (err) { + PRINTF("impossible to set advertising parameters\n\r"); + PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1); + PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy); + return BLE_ERROR_INVALID_PARAM; + } + + err = hci_le_set_advertise_enable(0x01); + if (err) { + PRINTF("impossible to start advertising\n\r"); + return BLE_ERROR_UNSPECIFIED; + } + + if(params.getTimeout() != 0) { + PRINTF("!!! attaching adv to!!!\n"); +#ifdef AST_FOR_MBED_OS + minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000)); +#else + advTimeout.attach(advTimeoutCB, params.getTimeout()); +#endif + } + + return BLE_ERROR_NONE; + +} + + +/**************************************************************************/ +/*! + @brief Stops the BLE HW and disconnects from any devices + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::stopAdvertising(void) +{ + if(state.advertising == 1) { + + int err = hci_le_set_advertise_enable(0); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + PRINTF("Advertisement stopped!!\n\r") ; + //Set GapState_t::advertising state + state.advertising = 0; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason) +{ + tBleStatus ret; + + ret = aci_gap_terminate(connectionHandle, reason); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_COMMAND_DISALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @param[in] reason + Disconnection Reason + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason) +{ + return disconnect(m_connectionHandle, reason); +} + +/**************************************************************************/ +/*! + @brief Sets the 16-bit connection handle + + @param[in] conn_handle + Connection Handle which is set in the Gap Instance + + @returns void +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionHandle(uint16_t conn_handle) +{ + m_connectionHandle = conn_handle; +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit connection handle + + @param[in] void + + @returns uint16_t + Connection Handle of the Gap Instance +*/ +/**************************************************************************/ +uint16_t BlueNRGGap::getConnectionHandle(void) +{ + return m_connectionHandle; +} + +/**************************************************************************/ +/*! + @brief Sets the BLE device address. SetAddress will reset the BLE + device and re-initialize BTLE. Will not start advertising. + + @param[in] type + Type of Address + + @param[in] address[6] + Value of the Address to be set + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address) +{ + if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if(type == BLEProtocol::AddressType::PUBLIC){ + tBleStatus ret = aci_hal_write_config_data( + CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + address + ); + if(ret != BLE_STATUS_SUCCESS) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + } else if (type == BLEProtocol::AddressType::RANDOM_STATIC) { + // ensure that the random static address is well formed + if ((address[5] & 0xC0) != 0xC0) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // thanks to const correctness of the API ... + tBDAddr random_address = { 0 }; + memcpy(random_address, address, sizeof(random_address)); + int err = hci_le_set_random_address(random_address); + if (err) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // It is not possible to get the bluetooth address when it is set + // store it locally in class data member + memcpy(bdaddr, address, sizeof(bdaddr)); + } else { + // FIXME random addresses are not supported yet + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + // if we're here then the address was correctly set + // commit it inside the addr_type + addr_type = type; + isSetAddress = true; + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Returns boolean if the address of the device has been set + or not + + @returns bool + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +bool BlueNRGGap::getIsSetAddress() +{ + return isSetAddress; +} + +/**************************************************************************/ +/*! + @brief Returns the address of the device if set + + @returns Pointer to the address if Address is set else NULL + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) +{ + uint8_t bdaddr[BDADDR_SIZE]; + uint8_t data_len_out; + + // precondition, check that pointers in input are valid + if (typeP == NULL || address == NULL) { + return BLE_ERROR_INVALID_PARAM; + } + + if (addr_type == BLEProtocol::AddressType::PUBLIC) { + tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_PUBADDR_OFFSET, BDADDR_SIZE, &data_len_out, bdaddr); + if(ret != BLE_STATUS_SUCCESS || data_len_out != BDADDR_SIZE) { + return BLE_ERROR_UNSPECIFIED; + } + } else if (addr_type == BLEProtocol::AddressType::RANDOM_STATIC) { + // FIXME hci_read_bd_addr and + // aci_hal_read_config_data CONFIG_DATA_RANDOM_ADDRESS_IDB05A1 + // does not work, use the address stored in class data member + memcpy(bdaddr, this->bdaddr, sizeof(bdaddr)); + } else { + // FIXME: should be implemented with privacy features + // BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE + // BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE + return BLE_ERROR_NOT_IMPLEMENTED; + } + + *typeP = addr_type; + memcpy(address, bdaddr, BDADDR_SIZE); + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief obtains preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + + if (!g_preferred_connection_parameters_char_handle) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + // Peripheral preferred connection parameters are an array of 4 uint16_t + uint8_t parameters_packed[parameter_size * 4]; + uint16_t bytes_read = 0; + + tBleStatus err = aci_gatt_read_handle_value( + g_preferred_connection_parameters_char_handle + BlueNRGGattServer::CHAR_VALUE_HANDLE, + sizeof(parameters_packed), + &bytes_read, + parameters_packed + ); + + PRINTF("getPreferredConnectionParams err=0x%02x (bytes_read=%u)\n\r", err, bytes_read); + + // check that the read succeed and the result have the expected length + if (err || bytes_read != sizeof(parameters_packed)) { + return BLE_ERROR_UNSPECIFIED; + } + + // memcpy field by field + memcpy(¶ms->minConnectionInterval, parameters_packed, parameter_size); + memcpy(¶ms->maxConnectionInterval, ¶meters_packed[parameter_size], parameter_size); + memcpy(¶ms->slaveLatency, ¶meters_packed[2 * parameter_size], parameter_size); + memcpy(¶ms->connectionSupervisionTimeout, ¶meters_packed[3 * parameter_size], parameter_size); + + return BLE_ERROR_NONE; +} + + +/**************************************************************************/ +/*! + @brief sets preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) +{ + static const size_t parameter_size = 2; + uint8_t parameters_packed[parameter_size * 4]; + + // ensure that parameters are correct + // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + // section 12.3 PERIPHERAL PREFERRED CONNECTION PARAMETERS CHARACTERISTIC + if (((0x0006 > params->minConnectionInterval) || (params->minConnectionInterval > 0x0C80)) && + params->minConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((params->minConnectionInterval > params->maxConnectionInterval) || (params->maxConnectionInterval > 0x0C80)) && + params->maxConnectionInterval != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (params->slaveLatency > 0x01F3) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + if (((0x000A > params->connectionSupervisionTimeout) || (params->connectionSupervisionTimeout > 0x0C80)) && + params->connectionSupervisionTimeout != 0xFFFF) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + // copy the parameters inside the byte array + memcpy(parameters_packed, ¶ms->minConnectionInterval, parameter_size); + memcpy(¶meters_packed[parameter_size], ¶ms->maxConnectionInterval, parameter_size); + memcpy(¶meters_packed[2 * parameter_size], ¶ms->slaveLatency, parameter_size); + memcpy(¶meters_packed[3 * parameter_size], ¶ms->connectionSupervisionTimeout, parameter_size); + + tBleStatus err = aci_gatt_update_char_value( + g_gap_service_handle, + g_preferred_connection_parameters_char_handle, + /* offset */ 0, + sizeof(parameters_packed), + parameters_packed + ); + + if (err) { + PRINTF("setPreferredConnectionParams failed (err=0x%x)!!\n\r", err) ; + switch (err) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief updates preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) +{ + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(gapRole == Gap::CENTRAL) { + ret = aci_gap_start_connection_update(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout, + CONN_L1, CONN_L2); + } else { + ret = aci_l2cap_connection_parameter_update_request(handle, + params->minConnectionInterval, + params->maxConnectionInterval, + params->slaveLatency, + params->connectionSupervisionTimeout); + } + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("updateConnectionParams failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case ERR_COMMAND_DISALLOWED: + case BLE_STATUS_NOT_ALLOWED: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sets the Device Name Characteristic + + @param[in] deviceName + pointer to device name to be set + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) +{ + tBleStatus ret; + uint8_t nameLen = 0; + + nameLen = strlen((const char*)deviceName); + PRINTF("DeviceName Size=%d\n\r", nameLen); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_device_name_char_handle, + 0, + nameLen, + deviceName); + + if (BLE_STATUS_SUCCESS != ret){ + PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ; + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Gets the Device Name Characteristic + + @param[in] deviceName + pointer to device name + + @param[in] lengthP + pointer to device name length + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) +{ + tBleStatus ret; + + ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + *lengthP, + (uint16_t *)lengthP, + deviceName); + PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } +} + +/**************************************************************************/ +/*! + @brief Sets the Device Appearance Characteristic + + @param[in] appearance + device appearance + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance) +{ + tBleStatus ret; + uint8_t deviceAppearance[2]; + + STORE_LE_16(deviceAppearance, appearance); + PRINTF("setAppearance= 0x%x 0x%x\n\r", deviceAppearance[1], deviceAppearance[0]); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_appearance_char_handle, + 0, 2, (uint8_t *)deviceAppearance); + if (BLE_STATUS_SUCCESS == ret){ + return BLE_ERROR_NONE; + } + + PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + case BLE_STATUS_INSUFFICIENT_RESOURCES: + return BLE_ERROR_NO_MEM; + case BLE_STATUS_TIMEOUT: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Gets the Device Appearance Characteristic + + @param[in] appearance + pointer to device appearance value + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) +{ + tBleStatus ret; + uint16_t lengthP = 2; + + ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, + lengthP, + &lengthP, + (uint8_t*)appearanceP); + PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP); + if (ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } else { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + +} + +GapScanningParams* BlueNRGGap::getScanningParams(void) +{ + return &_scanningParams; +} + +static void makeConnection(void) +{ + BlueNRGGap::getInstance().createConnection(); +} + +void BlueNRGGap::Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI) +{ + switch (reason) { + case DEVICE_FOUND: + { + GapAdvertisingParams::AdvertisingType_t type; + bool isScanResponse = false; + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * Private Random Address + * => scan_results = FALSE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type); + if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV || + (addr_type == RESOLVABLE_PRIVATE_ADDR || + addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) { + return; + } + + switch(adv_type) { + case ADV_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + break; + case ADV_DIRECT_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED; + break; + case ADV_SCAN_IND: + case SCAN_RSP: + type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED; + isScanResponse = true; + break; + case ADV_NONCONN_IND: + type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED; + break; + default: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + } + + PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n", + *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + if(!_connecting) { + processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data); + } + PRINTF("!!!After processAdvertisementReport\n\r"); + } + break; + + case DISCOVERY_COMPLETE: + // The discovery is complete. If this is due to a stop scanning (i.e., the device + // we are interested in has been found) and a connection has been requested + // then we start the device connection. + PRINTF("DISCOVERY_COMPLETE\n\r"); + _scanning = false; + + // Since the DISCOVERY_COMPLETE event can be received during the scanning interval, + // we need to delay the starting of connection + uint16_t delay = (_scanningParams.getInterval()*0.625); + +#ifdef AST_FOR_MBED_OS + if(_connecting) { + minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay)); + } +#else + Clock_Wait(delay); + if(_connecting) { + makeConnection(); + } +#endif /* AST_FOR_MBED_OS */ + + break; + } +} + +ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) +{ + + tBleStatus ret = BLE_STATUS_SUCCESS; + + // Stop ADV before scanning + /* + if (state.advertising == 1) { + stopAdvertising(); + } + */ + + /* + * Whitelisting (scan policy): + * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && + * White List is empty + * => scan operation = FAILURE + * FIXME: the Security Manager should be implemented + */ + ScanningPolicyMode_t mode = getScanningPolicyMode(); + uint8_t whiteListSize = whitelistAddresses.size; + if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + ret = btleStartRadioScan(scanningParams.getActiveScanning(), + scanningParams.getInterval(), + scanningParams.getWindow(), + addr_type); + + PRINTF("Scanning...\n\r"); + PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000); + PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000); + //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval()); + //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1); + //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2); + if (BLE_STATUS_SUCCESS == ret){ + PRINTF("Observation Procedure Started\n"); + _scanning = true; + + if(scanningParams.getTimeout() != 0) { + PRINTF("!!! attaching scan to!!!\n"); + scanTimeout.attach(scanTimeoutCB, scanningParams.getTimeout()); + } + + return BLE_ERROR_NONE; + } + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + switch (ret) { + case BLE_STATUS_INVALID_CID: + PRINTF("Observation Procedure not implemented!!!\n\r"); + return BLE_ERROR_NOT_IMPLEMENTED; + default: + PRINTF("Observation Procedure failed (0x%02X)\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } + +} + +ble_error_t BlueNRGGap::stopScan() { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(_scanning) { + ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC); + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Discovery Procedure Terminated\n"); + return BLE_ERROR_NONE; + } + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief set Tx power level + @param[in] txPower Transmission Power level + @returns ble_error_t +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setTxPower(int8_t txPower) +{ + tBleStatus ret; + + int8_t enHighPower = 0; + int8_t paLevel = 0; + + ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + ret = aci_hal_set_tx_power_level(enHighPower, paLevel); + if(ret!=BLE_STATUS_SUCCESS) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief get permitted Tx power values + @param[in] values pointer to pointer to permitted power values + @param[in] num number of values +*/ +/**************************************************************************/ +void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { + static const int8_t permittedTxValues[] = { + -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8 + }; + + *valueArrayPP = permittedTxValues; + *countP = sizeof(permittedTxValues) / sizeof(int8_t); +} + +/**************************************************************************/ +/*! + @brief Set advertising parameters according to the current state + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setAdvParameters(void) +{ + uint32_t advIntMS; + + if(state.connected == 1) { + advIntMS = (conn_min_interval*1.25)-GUARD_INT; + advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS); + + PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval); + } else { + advInterval = _advParams.getIntervalInADVUnits(); + } +} + +/**************************************************************************/ +/*! + @brief Set connection parameters according to the current state (ADV and/or SCAN) + Parameters value is set taking into account guidelines of the BlueNRG + time slots allocation +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionParameters(void) +{ + if (state.connected == 1) { + + PRINTF("state.connected=1\r\n"); + scanInterval = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(conn_min_interval*1.25); + scanWindow = _scanningParams.MSEC_TO_SCAN_DURATION_UNITS(((conn_min_interval*1.25)/100)*60); // scanWin ~= 60%(scanInt) + + } else if (state.advertising == 1) { + + if (_scanningParams.getInterval() < advInterval) { + PRINTF("state.adv=1 scanInterval<advInterval\r\n"); + scanInterval = advInterval; + scanWindow = advInterval; + } else { + PRINTF("state.adv=1 scanInterval>=advInterval\r\n"); + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + } + + if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms + conn_min_interval = MAX_INT_CONN; + conn_max_interval = MAX_INT_CONN; + } else { + conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; + } + + } else { + + PRINTF("state.adv = 0\r\n"); + + scanInterval = _scanningParams.getInterval(); + scanWindow = _scanningParams.getWindow(); + if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) || + SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms + conn_min_interval = DEF_INT_CONN; + conn_max_interval = DEF_INT_CONN; + } else { + conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; + } + } + PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval)); + PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow)); + PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25)); + PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25)); + +} + +ble_error_t BlueNRGGap::createConnection () +{ + tBleStatus ret; + + /* + Before creating connection, set parameters according + to previous or current procedure (ADV and/or SCAN) + */ + setConnectionParameters(); + + /* + Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, + Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max + */ + ret = aci_gap_create_connection(scanInterval, + scanWindow, + _peerAddrType, + (unsigned char*)_peerAddr, + addr_type, + conn_min_interval, conn_max_interval, 0, + SUPERV_TIMEOUT, CONN_L1, CONN_L1); + + //_connecting = false; + + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Connection started.\n"); + _connecting = false; + return BLE_ERROR_NONE; + } +} + +ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) +{ + /* avoid compiler warnings about unused variables */ + (void)connectionParams; + + setScanParams(scanParams->getInterval(), + scanParams->getWindow(), + scanParams->getTimeout(), + scanParams->getActiveScanning() + ); + + // Save the peer address + for(int i=0; i<BDADDR_SIZE; i++) { + _peerAddr[i] = peerAddr[i]; + } + _peerAddrType = peerAddrType; + + _connecting = true; + + if(_scanning) { + stopScan(); + } else { + PRINTF("Calling createConnection from connect()\n\r"); + return createConnection(); + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the advertising policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode) +{ + advertisingPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Set the scanning policy filter mode that will be used in + the next call to startAdvertising(). + + @returns \ref ble_errror_t + + @retval BLE_ERROR_NONE + Everything executed properly. + + BLE_ERROR_NOT_IMPLEMENTED + This feature is currently note implemented. +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode) +{ + scanningPolicyMode = mode; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Get the current advertising policy filter mode. + + @returns The advertising policy filter mode. +*/ +/**************************************************************************/ +Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const +{ + return advertisingPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Get the current scanning policy filter mode. + + @returns The scanning policy filter mode. + +*/ +/**************************************************************************/ +Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const +{ + return scanningPolicyMode; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGap's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::reset(void) +{ + PRINTF("BlueNRGGap::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (Gap::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + AdvToFlag = false; + ScanToFlag = false; + + /* Clear derived class members */ + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + + /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ + advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; + scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; + + return BLE_ERROR_NONE; +} + +void BlueNRGGap::setConnectionInterval(uint16_t interval) { + conn_min_interval = interval; + conn_max_interval = interval; +} + +Gap::Role_t BlueNRGGap::getGapRole(void) +{ + return (gapRole); +} + +void BlueNRGGap::setGapRole(Gap::Role_t role) +{ + gapRole = role; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,403 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTClient + * @brief BlueNRG BLE_API GattClient Adaptation + * @{ + */ + +#include "BlueNRGGattClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +#include <new> +#include <assert.h> + +ble_error_t BlueNRGGattClient::createGattConnectionClient(Gap::Handle_t connectionHandle) +{ + if(MAX_ACTIVE_CONNECTIONS <= _numConnections) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + for(uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + + if(_connectionPool[i] == NULL) { + BlueNRGGattConnectionClient *gattConnectionClient = new(std::nothrow) BlueNRGGattConnectionClient(this, connectionHandle); + + if (gattConnectionClient == NULL) { + return BLE_ERROR_NO_MEM; + } + + _connectionPool[i] = gattConnectionClient; + _connectionPool[i]->onServiceDiscoveryTermination(terminationCallback); + _numConnections++; + + PRINTF("createGattConnectionClient: _connectionPool index=%d\r\n", i); + PRINTF("createGattConnectionClient: succesfully added new gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + break; + } + } + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattClient::removeGattConnectionClient(Gap::Handle_t connectionHandle, uint8_t reason) +{ + + PRINTF("removeGattConnectionClient: connectionHandle=%d reason=0x%x\r\n", connectionHandle, reason); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("removeGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("removeGattConnectionClient: Found gattConnectionClient\r\n"); + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + PRINTF("removeGattConnectionClient: succesfully removed gattConnectionClient (_numConnections=%d)\r\n", _numConnections); + + break; + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + + return BLE_ERROR_NONE; +} + +BlueNRGGattConnectionClient * BlueNRGGattClient::getGattConnectionClient(Gap::Handle_t connectionHandle) { + PRINTF("getGattConnectionClient\r\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + PRINTF("getGattConnectionClient: _connectionPool[%d]->_connectionHandle=%d\r\n", i, _connectionPool[i]->_connectionHandle); + + if(_connectionPool[i]->_connectionHandle == connectionHandle) { + PRINTF("getGattConnectionClient: Found gattConnectionClient\r\n"); + return _connectionPool[i]; + } + } + + return NULL; +} + +void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code) { + + if(error_code != BLE_STATUS_SUCCESS) { + return; + } + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->gattProcedureCompleteCB(error_code); +} + +void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServicesCB(event_data_length, + attribute_data_length, + attribute_data_list); +} + +void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t *handles_info_list) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->primaryServiceCB(event_data_length, + handles_info_list); +} + +ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->findServiceChars(); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharsCB(event_data_length, + handle_value_pair_length, + handle_value_pair); +} + +void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle, + uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->serviceCharByUUIDCB(event_data_length, + attr_handle, + attr_value); +} + +void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->discAllCharacDescCB(event_data_length, + format, + handle_uuid_pair); +} + +void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint8_t* attribute_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charReadCB(event_data_length, + attribute_value); +} + +void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle, + uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWritePrepareCB(event_data_length, + attribute_handle, + offset, + part_attr_value); +} + +void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle, + uint8_t event_data_length) { + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connHandle); + + assert(gattConnectionClient != NULL); + + gattConnectionClient->charWriteExecCB(event_data_length); +} + +ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattClient launchServiceDiscovery\n\r"); + + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + return gattConnectionClient->launchServiceDiscovery(sc, cc, matchingServiceUUID, matchingCharacteristicUUIDIn); + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, matchingServiceUUID); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(connectionHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverServices(callback, startHandle, endHandle); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +bool BlueNRGGattClient::isServiceDiscoveryActive(void) const +{ + bool isSDActive = false; + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + isSDActive |= _connectionPool[i]->isServiceDiscoveryActive(); + } + } + + return isSDActive; +} + +void BlueNRGGattClient::terminateServiceDiscovery(void) +{ + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if (_connectionPool[i]) { + _connectionPool[i]->terminateServiceDiscovery(); + } + } +} + +void BlueNRGGattClient::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + terminationCallback = callback; + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; ++i) { + if (_connectionPool[i]) { + _connectionPool[i]->onServiceDiscoveryTermination(callback); + } + } +} + +ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->read(attributeHandle, offset); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + BlueNRGGattConnectionClient *gattConnectionClient = const_cast<BlueNRGGattClient*>(this)->getGattConnectionClient(connHandle); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->write(cmd, attributeHandle, length, value); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) +{ + BlueNRGGattConnectionClient *gattConnectionClient = getGattConnectionClient(characteristic.getConnectionHandle()); + + if(gattConnectionClient != NULL) { + + return gattConnectionClient->discoverCharacteristicDescriptors(characteristic, discoveryCallback, terminationCallback); + + } else { + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattClient's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattClient::reset(void) +{ + PRINTF("BlueNRGGattClient::reset\n"); + + for (uint8_t i = 0; i < MAX_ACTIVE_CONNECTIONS; i++) { + if(_connectionPool[i] != NULL) { + _connectionPool[i]->reset(); + + delete _connectionPool[i]; + _connectionPool[i] = NULL; + + _numConnections--; + } + } + + return BLE_ERROR_NONE; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,816 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGattConnectionClient + * @brief BlueNRG GattConnectionClient Adaptation + * @{ + */ + +#include "BlueNRGGattConnectionClient.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" +#include "ble_debug.h" + +// #define PRINTF printf + +static uint8_t props_mask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 + }; + +void BlueNRGGattConnectionClient::gattProcedureCompleteCB(uint8_t error_code) +{ + if(error_code != BLE_STATUS_SUCCESS) { + _currentState = GATT_IDLE; + return; + } + + // Service Discovery complete +/* + if(_currentState != GATT_IDLE && + _currentState != GATT_DISCOVERY_TERMINATED && + _currentState != GATT_WRITE_CHAR && + _currentState != GATT_READ_CHAR) { +*/ + if(_currentState == GATT_SERVICE_DISCOVERY) { + findServiceChars(); + return; + } + + if(_currentState == GATT_CHAR_DESC_DISCOVERY) { + _currentState = GATT_IDLE; + if(charDescTerminationCallback != NULL) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { + _characteristic, + BLE_ERROR_NONE + }; + charDescTerminationCallback(¶ms); + } + return; + } + + // Read complete + if(_currentState == GATT_READ_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processReadResponse(&readCBParams); + free((void*)(readCBParams.data)); + readCBParams.data = NULL; + return; + } + + // Write complete + if(_currentState == GATT_WRITE_CHAR) { + _currentState = GATT_IDLE; + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); + return; + } +} + +void BlueNRGGattConnectionClient::primaryServicesCB(uint8_t event_data_length, + uint8_t attribute_data_length, + uint8_t *attribute_data_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numAttr; + + numAttr = (event_data_length - 1) / attribute_data_length; + + offset = 0; + for (i=0; i<numAttr; i++) { + startHandle = attribute_data_list[offset]; + endHandle = attribute_data_list[offset+2]; + + // UUID Type + if (attribute_data_length == 6) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4]; + PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(attribute_data_list+offset+4, UUID::LSB); + +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + + } + + PRINTF("Setup serviceIndex = %d\n\r", _numServices); + discoveredService[_numServices].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += attribute_data_length; + } + + PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr); + +} + +void BlueNRGGattConnectionClient::primaryServiceCB(uint8_t event_data_length, uint8_t *handles_info_list) +{ + GattAttribute::Handle_t startHandle, endHandle; + UUID uuid; + uint8_t i, offset, numHandlePairs; + + numHandlePairs = (event_data_length - 1) / 2; + + offset = 0; + for (i=0; i<numHandlePairs; i++) { + startHandle = handles_info_list[offset]; + endHandle = handles_info_list[offset+2]; + + PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle); + + + if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle); + uuid = _matchingServiceUUID.getShortUUID(); + } else { +#ifdef DEBUG + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02x", longUUIDBytes[i]); + } +#endif + PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle); + uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB); + } + + discoveredService[i].setup(uuid, startHandle, endHandle); + + _numServices++; + + offset += 4; + } +} + +void BlueNRGGattConnectionClient::serviceCharsCB(uint8_t event_data_length, + uint8_t handle_value_pair_length, + uint8_t *handle_value_pair) +{ + // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + uint8_t i, numChar, offset; + + numChar = (event_data_length - 1) / handle_value_pair_length; + + PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar); + + offset = 0; + for (i=0; i<numChar; i++) { + // UUID Type + if (handle_value_pair_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(handle_value_pair+offset+5, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & handle_value_pair[offset+2]); + p._read = (props_mask[1] & handle_value_pair[offset+2])>>1; + p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2; + p._write = (props_mask[3] & handle_value_pair[offset+2])>>3; + p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4; + p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5; + p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = handle_value_pair[offset+2]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = handle_value_pair[offset]; + valueHandle = handle_value_pair[offset+3]; + lastHandle = valueHandle+1; + PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle); + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; + + offset += handle_value_pair_length; + } +} + +void BlueNRGGattConnectionClient::serviceCharByUUIDCB(uint8_t event_data_length, + uint16_t attr_handle, + uint8_t *attr_value) +{ + // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16) + GattAttribute::Handle_t declHandle, valueHandle, lastHandle; + UUID uuid; + + PRINTF("serviceCharByUUIDCB\n\r"); + + // UUID Type + if (event_data_length == 7) { + PRINTF("Char UUID_TYPE_16\n\r"); + uuid = attr_value[4]<<8|attr_value[3]; + PRINTF("C UUID-%X\r\n", uuid.getShortUUID()); + } else { + PRINTF("Char UUID_TYPE_128\n\r"); + uuid.setupLong(attr_value+3, UUID::LSB); +#ifdef DEBUG + PRINTF("C UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); +#endif + } + + // Properties + DiscoveredCharacteristic::Properties_t p; + + p._broadcast = (props_mask[0] & attr_value[0]); + p._read = (props_mask[1] & attr_value[0])>>1; + p._writeWoResp = (props_mask[2] & attr_value[0])>>2; + p._write = (props_mask[3] & attr_value[0])>>3; + p._notify = (props_mask[4] & attr_value[0])>>4; + p._indicate = (props_mask[5] & attr_value[0])>>5; + p._authSignedWrite = (props_mask[6] & attr_value[0])>>6; + PRINTF("p._broadcast=%d\n\r", p._broadcast); + PRINTF("p._read=%d\n\r", p._read); + PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp); + PRINTF("p._write=%d\n\r", p._write); + PRINTF("p._notify=%d\n\r", p._notify); + PRINTF("p._indicate=%d\n\r", p._indicate); + PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite); + + /* + uint8_t props = attr_value[0]; + PRINTF("CHAR PROPS: %d\n\r", props); + */ + + // Handles + declHandle = attr_handle; + valueHandle = attr_value[1]; + lastHandle = valueHandle+1; + + discoveredChar[_numChars].setup(_gattClient, + _connectionHandle, + uuid, + p, + declHandle, + valueHandle, + lastHandle); + + // update the last handle and call the characteristic discovery callback for previous char + if (_numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(declHandle - 1); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars++; +} + +ble_error_t BlueNRGGattConnectionClient::findServiceChars(void) +{ + PRINTF("findServiceChars\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + + DiscoveredService *service; + + // complete the discovery of the last characteristic of the previous service. + // Its last handle wasn't known before this point + // update the handle and call the characteristic discovery callback. + if (_servIndex != 0 && _numChars != 0) { + discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle()); + + if(characteristicDiscoveryCallback) { + characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]); + } + } + + _numChars = 0; + + // We finished chars discovery for all services + if(_servIndex >= _numServices) { + PRINTF("!!!We finished chars discovery for all services!!!\n\r"); + //_currentState = GATT_CHARS_DISCOVERY_COMPLETE; + + terminateServiceDiscovery(); + + return BLE_ERROR_NONE; + } + + service = &discoveredService[_servIndex]; + /* + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID()); + } else { + PRINTF("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); + } + */ + + if(serviceDiscoveryCallback) { + serviceDiscoveryCallback(service); + } + + PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex); + //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle()); + + if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) { + PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r"); + ret = aci_gatt_disc_all_charac_of_serv(_connectionHandle, service->getStartHandle(), service->getEndHandle()); + } else { + + uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID()); + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; +#ifdef DEBUG + PRINTF("findServiceChars C UUID-"); + for(unsigned i = 0; i < 2; i++) { + PRINTF("%02X", short_uuid[i]); + } + PRINTF("\n\r"); +#endif + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID(); +#ifdef DEBUG + PRINTF("(findServiceChars) C UUID-"); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", uuid[i]); + } + PRINTF("\r\n"); +#endif + } + + ret = aci_gatt_disc_charac_by_uuid(_connectionHandle, + service->getStartHandle(), + service->getEndHandle(), + uuid_type, + uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _servIndex++; + } + + PRINTF("findServiceChars ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::launchServiceDiscovery(ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUIDIn) +{ + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery\n\r"); + + tBleStatus ret; + uint8_t uuid_type = UUID_TYPE_16; + uint8_t short_uuid[2]; + uint8_t *uuid = NULL; + unsigned j; + + if(isServiceDiscoveryActive()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if(!sc && !cc) { + // nothing to do + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery: nothing to do\n\r"); + return BLE_ERROR_NONE; + } + + serviceDiscoveryCallback = sc; + characteristicDiscoveryCallback = cc; + _matchingServiceUUID = matchingServiceUUID; + _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn; + + //reset services + _numServices = 0; + _numChars = 0; + _servIndex = 0; + for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) { + discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE); + } + + if(matchingServiceUUID == BLE_UUID_UNKNOWN) { + + // Wildcard: search for all services + PRINTF("Wildcard: search for all services\r\n"); + ret = aci_gatt_disc_all_prim_services((uint16_t)_connectionHandle); + + } else { + PRINTF("search for specific services\r\n"); + + uint8_t type = matchingServiceUUID.shortOrLong(); + + if(type == UUID::UUID_TYPE_SHORT) { + STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID()); +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery short_uuid=0x"); + for(j = 0; j < 2; j++) { + PRINTF("%02X", short_uuid[j]); + } + PRINTF("\n\r"); +#endif + + uuid_type = UUID_TYPE_16; + uuid = short_uuid; + + } else if(type==UUID::UUID_TYPE_LONG) { + + uuid_type = UUID_TYPE_128; + uuid = (unsigned char*)matchingServiceUUID.getBaseUUID(); + +#ifdef DEBUG + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery base_uuid=0x"); + for(j = 0; j < 16; j++) { + PRINTF("%02X", uuid[j]); + } + PRINTF("\n\r"); +#endif + } + + // search for specific service by UUID + ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)_connectionHandle, uuid_type, uuid); + } + + if(ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_SERVICE_DISCOVERY; + } + + PRINTF("BlueNRGGattConnectionClient launchServiceDiscovery ret=%d\n\r", ret); + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)matchingServiceUUID; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +ble_error_t BlueNRGGattConnectionClient::discoverServices(ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) +{ + /* avoid compiler warnings about unused variables */ + (void)callback; + (void)startHandle; + (void)endHandle; + + return BLE_ERROR_NOT_IMPLEMENTED; +} + +bool BlueNRGGattConnectionClient::isServiceDiscoveryActive(void) const +{ + if(_currentState == GATT_SERVICE_DISCOVERY) { + return true; + } + + return false; +} + +void BlueNRGGattConnectionClient::terminateServiceDiscovery(void) +{ + _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED; + + if (terminationCallback) { + terminationCallback(_connectionHandle); + } +} + +void BlueNRGGattConnectionClient::charReadCB(uint8_t event_data_length, uint8_t* attribute_value) +{ + // copy the data read, they will be forwarded to the user once the procedure + // has completed + readCBParams.connHandle = _connectionHandle; + readCBParams.offset = 0; + readCBParams.len = event_data_length; + readCBParams.data = static_cast<uint8_t*>(malloc(event_data_length)); + memcpy((void*)(readCBParams.data), attribute_value, event_data_length); +} + +ble_error_t BlueNRGGattConnectionClient::read(GattAttribute::Handle_t attributeHandle, uint16_t offset) const +{ + /* avoid compiler warnings about unused variables */ + (void)offset; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // Save the attribute_handle not provided by evt_att_read_resp + gattc->readCBParams.handle = attributeHandle; + + ret = aci_gatt_read_charac_val(_connectionHandle, attributeHandle); + + if(ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_READ_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } +} + +void BlueNRGGattConnectionClient::charWritePrepareCB(uint8_t event_data_length, + uint16_t attribute_handle, + uint16_t offset, + uint8_t *part_attr_value) +{ + // Update the write response params + writeCBParams.handle = attribute_handle; + writeCBParams.offset = offset; + writeCBParams.len = event_data_length-4; //(?) + writeCBParams.data = part_attr_value; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +void BlueNRGGattConnectionClient::charWriteExecCB(uint8_t event_data_length) +{ + /* avoid compiler warnings about unused variables */ + (void)event_data_length; + + writeCBParams.connHandle = _connectionHandle; + + BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams); +} + +ble_error_t BlueNRGGattConnectionClient::write(GattClient::WriteOp_t cmd, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const +{ + /* avoid compiler warnings about unused variables */ + (void)cmd; + + tBleStatus ret; + + BlueNRGGattConnectionClient *gattc = const_cast<BlueNRGGattConnectionClient*>(this); + + // We save the write response params (used by the callback) because + // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE + gattc->writeCBParams.connHandle = _connectionHandle; + gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD; + gattc->writeCBParams.handle = attributeHandle; + gattc->writeCBParams.offset = 0; + gattc->writeCBParams.len = length; + gattc->writeCBParams.data = value; + + ret = aci_gatt_write_charac_value(_connectionHandle, attributeHandle, length, const_cast<uint8_t *>(value)); + + if (ret == BLE_STATUS_SUCCESS) { + gattc->_currentState = GATT_WRITE_CHAR; + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_CONTROLLER_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_INVALID_STATE; + } + +} + +void BlueNRGGattConnectionClient::discAllCharacDescCB(uint8_t event_data_length, + uint8_t format, + uint8_t *handle_uuid_pair) { + GattAttribute::Handle_t attHandle; + UUID uuid; + uint8_t i, numCharacDesc, offset, handle_uuid_length; + + handle_uuid_length = 4; //Handle + UUID_16 + if (format == 2) + handle_uuid_length = 18; //Handle + UUID_128 + + numCharacDesc = (event_data_length - 1) / handle_uuid_length; + + offset = 0; + + PRINTF("\r\ncharacteristic descriptor discovered: data length %u, format %u\r\n", + event_data_length, format); + + + for (i=0; i<numCharacDesc; i++) { + memcpy(&attHandle, handle_uuid_pair + offset, sizeof(attHandle)); + + // UUID Type + if (handle_uuid_length == 4) { + + PRINTF("UUID_TYPE_16\n\r"); + uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2]; + PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle); + + } else { + + PRINTF("UUID_TYPE_128\n\r"); + uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB); +#ifdef DEBUG + PRINTF("D UUID-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } +#endif + } + + if(charDescDiscoveryCallback != NULL) { + CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { + _characteristic, + DiscoveredCharacteristicDescriptor( + _characteristic.getGattClient(), + _connectionHandle, + attHandle, + uuid + ) + }; + charDescDiscoveryCallback(¶ms); + } + + _numCharDesc++; + + offset += handle_uuid_length; + } +} + +ble_error_t BlueNRGGattConnectionClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { + + tBleStatus ret; + + if(_currentState != GATT_IDLE) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + charDescDiscoveryCallback = discoveryCallback; + charDescTerminationCallback = terminationCallback; + + GattAttribute::Handle_t valueHandle = characteristic.getValueHandle(); + GattAttribute::Handle_t lastHandle = characteristic.getLastHandle(); + + PRINTF("Starting aci_gatt_disc_all_charac_descriptors... [%u : %u]\n\r", valueHandle, lastHandle); + ret = aci_gatt_disc_all_charac_descriptors(_connectionHandle, valueHandle, lastHandle); + + if (ret == BLE_STATUS_SUCCESS) { + _currentState = GATT_CHAR_DESC_DISCOVERY; + _characteristic = characteristic; + return BLE_ERROR_NONE; + } + switch (ret) { + case BLE_STATUS_INVALID_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattConnectionClient::reset(void) { + PRINTF("BlueNRGGattConnectionClient::reset\n"); + + /* Clear all state, including private members */ + + _currentState = GATT_IDLE; + _matchingServiceUUID = BLE_UUID_UNKNOWN; + _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN; + + _numServices = 0; + _servIndex = 0; + _numChars = 0; + _numCharDesc = 0; + + /* Clear class members */ + memset(discoveredService, 0, sizeof(discoveredService)); + memset(discoveredChar, 0, sizeof(discoveredChar)); + + // free response if allocated + if(readCBParams.data) { + free((void*)(readCBParams.data)); + } + + return BLE_ERROR_NONE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,755 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + ****************************************************************************** + * @file BlueNRGGattServer.cpp + * @author STMicroelectronics + * @brief Implementation of BlueNRG BLE_API GattServer Class + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +/** @defgroup BlueNRGGATTSERVER + * @brief BlueNRG BLE_API GattServer Adaptation + * @{ + */ + +#include "BlueNRGGattServer.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "BlueNRGGap.h" +#include "ble_utils.h" +#include "ble_debug.h" + +/**************************************************************************/ +/*! + @brief Adds a new service to the GATT table on the peripheral + + @params[in] service + Pointer to instance of the Gatt Server to add + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::addService(GattService &service) +{ + /* ToDo: Make sure we don't overflow the array, etc. */ + /* ToDo: Make sure this service UUID doesn't already exist (?) */ + /* ToDo: Basic validation */ + + tBleStatus ret; + uint8_t type; + uint16_t short_uuid; + uint8_t primary_short_uuid[2]; + uint8_t primary_base_uuid[16]; + uint8_t char_base_uuid[16]; + const uint8_t *base_uuid; + const uint8_t *base_char_uuid; + + uint8_t charsCount = service.getCharacteristicCount(); + const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount; + + // check that there is enough characteristics left in the + // characteristic array. + if (charsCount > available_characteristics) { + PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics); + return BLE_ERROR_NO_MEM; + } + + const uint16_t maxAttrRecords = computeAttributesRecord(service); + + type = (service.getUUID()).shortOrLong(); + PRINTF("AddService(): Type:%d\n\r", type); + + /* Add the service to the BlueNRG */ + short_uuid = (service.getUUID()).getShortUUID(); + STORE_LE_16(primary_short_uuid, short_uuid); + + if(type==UUID::UUID_TYPE_LONG) { + base_uuid = (service.getUUID()).getBaseUUID(); + + COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]); + } + + ret = BLE_STATUS_SUCCESS; + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_serv(UUID_TYPE_16, + primary_short_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_serv(UUID_TYPE_128, + primary_base_uuid, + PRIMARY_SERVICE, + maxAttrRecords/*7*/, + &servHandle); + PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_OUT_OF_HANDLE: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case ERR_UNSPECIFIED_ERROR: + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_ERROR: + default: + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + + + service.setHandle(servHandle); + //serviceHandleVector.push_back(servHandle); + PRINTF("added servHandle handle =%u\n\r", servHandle); + uint16_t bleCharacteristic; + + //iterate to include all characteristics + for (uint8_t i = 0; i < charsCount; i++) { + GattCharacteristic *p_char = service.getCharacteristic(i); + uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); + + uint8_t int_8_uuid[2]; + STORE_LE_16(int_8_uuid, char_uuid); + + type = (p_char->getValueAttribute().getUUID()).shortOrLong(); + + if(type==UUID::UUID_TYPE_LONG) { + base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); +#ifdef DEBUG + for(uint8_t j=0; j<16; j++) { + PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]); + } + PRINTF("\n\r"); +#endif + COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]); + } + + PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); + /* + * Gatt_Evt_Mask -> HardCoded (0) + * Encryption_Key_Size -> Hardcoded (16) + * isVariable (variable length value field) -> Hardcoded (1) + */ + uint8_t Gatt_Evt_Mask = 0x0; + + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP; + } + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { + PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; + } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_16, + int_8_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + + } else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_char(service.getHandle(), + UUID_TYPE_128, + char_base_uuid, + p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), + ATTR_PERMISSION_NONE, + Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, + 1 /*isVariable*/, + &bleCharacteristic); + + PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", + p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret); + } + + switch (ret) { + case BLE_STATUS_SUCCESS: + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + case BLE_STATUS_CHARAC_ALREADY_EXISTS: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + + bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle)); + + p_characteristics[characteristicCount++] = p_char; + /* Set the characteristic value handle */ + p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE); + PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle()); + + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + ble_error_t err = write(p_char->getValueAttribute().getHandle(), + p_char->getValueAttribute().getValuePtr(), + p_char->getValueAttribute().getLength(), false /* localOnly */); + if (err) { + PRINTF("ERROR HERE !!!!\r\n"); + return err; + } + } + + // add descriptors now + uint16_t descHandle = 0; + PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); + + for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { + GattAttribute *descriptor = p_char->getDescriptor(descIndex); + uint8_t desc_uuid[16] = { 0 }; + + + uint8_t desc_uuid_type = CHAR_DESC_TYPE_16_BIT; + STORE_LE_16(desc_uuid, descriptor->getUUID().getShortUUID()); + + if((descriptor->getUUID()).shortOrLong() == UUID::UUID_TYPE_LONG) { + desc_uuid_type = CHAR_DESC_TYPE_128_BIT; + const uint8_t* base_desc_uuid = descriptor->getUUID().getBaseUUID(); + + COPY_UUID_128(desc_uuid, base_desc_uuid[15], base_desc_uuid[14],base_desc_uuid[13],base_desc_uuid[12], base_desc_uuid[11], base_desc_uuid[10], base_desc_uuid[9], base_desc_uuid[8], base_desc_uuid[7], base_desc_uuid[6], base_desc_uuid[5], base_desc_uuid[4], base_desc_uuid[3], base_desc_uuid[2], base_desc_uuid[1], base_desc_uuid[0]); + } + + ret = aci_gatt_add_char_desc(service.getHandle(), + bleCharacteristic, + desc_uuid_type, + desc_uuid, + descriptor->getMaxLength(), + descriptor->getLength(), + descriptor->getValuePtr(), + CHAR_DESC_SECURITY_PERMISSION, + CHAR_DESC_ACCESS_PERMISSION, + GATT_NOTIFY_ATTRIBUTE_WRITE, + MIN_ENCRY_KEY_SIZE, + CHAR_ATTRIBUTE_LEN_IS_FIXED, + &descHandle); + PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); + + switch (ret) { + case BLE_STATUS_SUCCESS: + PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); + descriptor->setHandle(descHandle); + break; + + case ERR_UNSPECIFIED_ERROR: + case BLE_STATUS_INSUFFICIENT_RESOURCES: + case BLE_STATUS_OUT_OF_HANDLE: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_NO_MEM; + + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INVALID_PARAM; + + case BLE_STATUS_INVALID_OPERATION: + return BLE_ERROR_OPERATION_NOT_PERMITTED; + + case BLE_STATUS_ERROR: + default: + // TODO remove characteristics and the service previously added. + // remove service in the stack by using: Aci_Gatt_Del_Service + // remove characteristics in the stack by using: Aci_Gatt_Del_Char + // update service counter + // destroy registered characteristic and updat echaracteristic counter + return BLE_ERROR_INTERNAL_STACK_FAILURE; + } + } + } + + serviceCount++; + + //FIXME: There is no GattService pointer array in GattServer. + // There should be one? (Only the user is aware of GattServices!) Report to forum. + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on char handle + + @param[in] attributeHandle + The handle of the GattCharacteristic to read from + @param[in] buffer + Buffer to hold the the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes read into the buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) +{ + tBleStatus ret; + uint16_t charHandle = attributeHandle; + + ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer); + + if(ret == BLE_STATUS_SUCCESS) { + return BLE_ERROR_NONE; + } + switch (ret) { + case ERR_INVALID_HCI_CMD_PARAMS: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on the connection + and char handle + + @param[in] connectionHandle + The handle of the connection + @param[in] attributeHandle + The handle of the GattCharacteristic to write to + @param[in] buffer + Data to use when updating the characteristic's value + (raw byte array in LSB format) + @param[in] lengthP + The number of bytes in buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + uint8_t buffer[], + uint16_t *lengthP) { + + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)attributeHandle; + (void)buffer; + (void)lengthP; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t, + const uint8_t[], + uint16_t, bool localOnly) { + /* avoid compiler warnings about unused variables */ + (void)connectionHandle; + (void)localOnly; + + return BLE_ERROR_NONE; +} + +ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly) +{ + /* avoid compiler warnings about unused variables */ + (void)localOnly; + + // check that the len of the data to write are compatible with the characteristic + GattCharacteristic* characteristic = getCharacteristicFromHandle(attributeHandle); + if (!characteristic) { + PRINTF("characteristic not found\r\n"); + return BLE_ERROR_INVALID_PARAM; + } + + // if the attribute handle is the attribute handle of the characteristic value then + // write the value + if (attributeHandle == characteristic->getValueHandle()) { + // assert the len in input is correct for this characteristic + const GattAttribute& value_attribute = characteristic->getValueAttribute(); + + // reject write if the lenght exceed the maximum lenght of this attribute + if (value_attribute.getMaxLength() < len) { + PRINTF("invalid variable length: %u, max length is: %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + // reject write if the attribute size is fixed and the lenght in input is different than the + // length of the attribute. + if (value_attribute.hasVariableLength() == false && value_attribute.getMaxLength() != len) { + PRINTF("invalid fixed length: %u, len should be %u\r\n", len, value_attribute.getMaxLength()); + return BLE_ERROR_INVALID_PARAM; + } + + tBleStatus ret; + + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + + PRINTF("updating bleCharacteristic valueHandle=%u,\ + corresponding serviceHandle=%u len=%d\n\r", + attributeHandle, bleCharHandleMap.find(charHandle)->second, len); + + /* + * If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. + */ + ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } else { + // write this handle has a descriptor handle + uint16_t charHandle = characteristic->getValueHandle() - BlueNRGGattServer::CHAR_VALUE_HANDLE; + uint16_t service_handle = bleCharHandleMap.find(charHandle)->second; + + tBleStatus ret = aci_gatt_set_desc_value( + service_handle, + charHandle, + attributeHandle, + 0, + len, + buffer + ); + + if (ret != BLE_STATUS_SUCCESS){ + PRINTF("Error while updating characteristic descriptor (ret=0x%x).\n\r", ret); + switch (ret) { + case BLE_STATUS_INVALID_HANDLE: + case BLE_STATUS_INVALID_PARAMETER: + return BLE_ERROR_INVALID_PARAM; + default: + return BLE_STACK_BUSY; + } + } + + return BLE_ERROR_NONE; + } +} + +/**************************************************************************/ +/*! + @brief Reads a value according to the handle provided + + @param[in] attributeHandle + The handle of the attribute to read from + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle) +{ + uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); + + GattReadCallbackParams readParams; + readParams.handle = attributeHandle; + + //PRINTF("readParams.handle = %d\n\r", readParams.handle); + HCIDataReadEvent(&readParams); + + //EXIT: + if(gapConnectionHandle != 0){ + //PRINTF("Calling aci_gatt_allow_read\n\r"); + aci_gatt_allow_read(gapConnectionHandle); + } + + return BLE_ERROR_NONE; +} + +// ask if the write request should be accepted of rejected +// return 0 in case of success or an ATT error response in +// case of faillure +uint8_t BlueNRGGattServer::Write_Request_CB( + uint16_t connection_handle, uint16_t attr_handle, uint8_t data_length, + const uint8_t* data) { + + GattCharacteristic* characteristic = getCharacteristicFromHandle(attr_handle); + if(!characteristic) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE & 0xFF; + } + + // check if the data length is in range + if (characteristic->getValueAttribute().getMaxLength() < data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + // if the length of the characteristic value is fixed + // then the data in input should be of that length + if (characteristic->getValueAttribute().hasVariableLength() == false && + characteristic->getValueAttribute().getMaxLength() != data_length) { + return AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH & 0xFF; + } + + GattWriteAuthCallbackParams params = { + connection_handle, + attr_handle, + /* offset */ 0, + data_length, + data, + /* authorizationReply */ AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED + }; + + return characteristic->authorizeWrite(¶ms) & 0xFF; +} + +/**************************************************************************/ +/*! + @brief Returns the GattCharacteristic according to the handle provided + + @param[in] attrHandle + The handle of the attribute + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(uint16_t attrHandle) +{ + GattCharacteristic *p_char = NULL; + int i; + uint16_t handle, handle_1; + + PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle); + for(i=0; i<characteristicCount; i++) + { + handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + PRINTF("handle(%d)=%d\n\r", i, handle); + if(i==characteristicCount-1)//Last Characteristic check + { + if(attrHandle>=handle) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); + break; + } + } + else { + handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + //Testing if attribute handle is between two Characteristic Handles + if(attrHandle>=handle && attrHandle<handle_1) + { + p_char = p_characteristics[i]; + PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); + break; + } else continue; + } + } + + return p_char; +} + +void BlueNRGGattServer::HCIDataWrittenEvent(const GattWriteCallbackParams *params) { + this->handleDataWrittenEvent(params); +} + +void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { + PRINTF("Called HCIDataReadEvent\n\r"); + this->handleDataReadEvent(params); +} + +void BlueNRGGattServer::HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { + this->handleEvent(type, charHandle); +} + +void BlueNRGGattServer::HCIDataSentEvent(unsigned count) { + this->handleDataSentEvent(count); +} + + +ble_error_t BlueNRGGattServer::initializeGATTDatabase(void) { + // <TODO> + return (ble_error_t)0; +} + +/**************************************************************************/ +/*! + @brief Clear BlueNRGGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::reset(void) +{ + PRINTF("BlueNRGGattServer::reset\n"); + + /* Clear all state that is from the parent, including private members */ + if (GattServer::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + /* Clear class members */ + memset(p_characteristics, 0, sizeof(p_characteristics)); + memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles)); + serviceCount = 0; + characteristicCount = 0; + + return BLE_ERROR_NONE; +} + + +/// compute the number of attributes needed by this service. +uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) { + uint16_t attribute_records = 1; + + for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) { + // add two attributes, one for the characteristic declaration + // and the other for the characteristic value. + attribute_records += 2; + + const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index); + const uint8_t properties = characteristic->getProperties(); + // if notify or indicate are present, two attributes are + // needed + if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) || + (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { + attribute_records += 2; + } + + // if broadcast is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) { + attribute_records += 2; + } + + // if extended properties flag is set, two attributes are needed + if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) { + attribute_records += 2; + } + + attribute_records += characteristic->getDescriptorCount(); + } + + // for some reason, if there is just a service, this value should + // be equal to 5 + if (attribute_records == 1) { + attribute_records = 5; + } + + return attribute_records; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,421 @@ +/** + ****************************************************************************** + * @file ble_hci.c + * @author AMS/HESA Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "ble_gp_timer.h" +#include "ble_debug.h" + +#include "stm32_bluenrg_ble.h" + +#if BLE_CONFIG_DBG_ENABLE +#undef PRINTF +#endif + +#define HCI_LOG_ON 0 + +#define HCI_READ_PACKET_NUM_MAX (0x40) + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tListNode hciReadPktPool; +tListNode hciReadPktRxQueue; + +// betzw - DEBUG: +//#define POOL_CNT +#ifdef POOL_CNT +#include <stdio.h> +static unsigned int nr_hciReadPktPool; +static unsigned int lowest_nr_hciReadPktPool; +#endif // POOL_CNT + +/* pool of hci read packets */ +static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; + +static volatile uint8_t hci_timer_id; +static volatile uint8_t hci_timeout; + +void hci_timeout_callback(void) +{ + hci_timeout = 1; + return; +} + +void HCI_Init(void) +{ + uint8_t index; + +#ifdef POOL_CNT + nr_hciReadPktPool = 0; +#endif // POOL_CNT + + /* Initialize list heads of ready and free hci data packet queues */ + list_init_head (&hciReadPktPool); + list_init_head (&hciReadPktRxQueue); + + /* Initialize the queue of free hci data packets */ + for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) + { + list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif // POOL_CNT + } + +#ifdef POOL_CNT + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif // POOL_CNT +} + +#define HCI_PCK_TYPE_OFFSET 0 +#define EVENT_PARAMETER_TOT_LEN_OFFSET 2 + +/** + * Verify if HCI packet is correctly formatted. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * @return 0 if HCI packet is as expected + */ +int HCI_verify(const tHciDataPacket * hciReadPacket) +{ + const uint8_t *hci_pckt = hciReadPacket->dataBuff; + + if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) + return 1; /* Incorrect type. */ + + if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) + return 2; /* Wrong length (packet truncated or too long). */ + + return 0; +} + +void HCI_Process(void) +{ + tHciDataPacket * hciReadPacket = NULL; + +#ifdef POOL_CNT + printf("betzw(%s, %d): nr_hciReadPktPool = %u (lowest = %u)\r\n", __func__, __LINE__, + nr_hciReadPktPool, lowest_nr_hciReadPktPool); +#endif // POOL_CNT + + Disable_SPI_IRQ(); + uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); + /* process any pending events read */ + while(list_empty == FALSE) + { + list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + Enable_SPI_IRQ(); + HCI_Event_CB(hciReadPacket->dataBuff); + Disable_SPI_IRQ(); + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + list_empty = list_is_empty(&hciReadPktRxQueue); + } + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG. */ + HCI_HandleSPI(); + Enable_SPI_IRQ(); +} + +BOOL HCI_Queue_Empty(void) +{ + return list_is_empty(&hciReadPktRxQueue); +} + +/** + * When an interrupt is raised by BlueNRG, + * just signal that a new event (availability of SPI data to be read) + * needs to be processed. + */ +void HCI_Isr(void) +{ + signalEventsToProcess(); +} + +/** + * Now, SPI Data are handled in user space. + * In case it has to be called in ISR, take care to + * call Disable_SPI_IRQ/Enable_SPI_IRQ in a proper way. + * The calls Disable_SPI_IRQ/Enable_SPI_IRQ have not been removed + * from this code for backward compatibility. + */ +void HCI_HandleSPI(void) +{ + tHciDataPacket * hciReadPacket = NULL; + uint8_t data_len; + + Clear_SPI_EXTI_Flag(); + while(BlueNRG_DataPresent()){ + if (list_is_empty (&hciReadPktPool) == FALSE){ + + /* enqueueing a packet for read */ + list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool--; + if(nr_hciReadPktPool < lowest_nr_hciReadPktPool) + lowest_nr_hciReadPktPool = nr_hciReadPktPool; +#endif + + data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); + if(data_len > 0){ + hciReadPacket->data_len = data_len; + if(HCI_verify(hciReadPacket) == 0) { + list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); + } else { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else { + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + } + else{ + // HCI Read Packet Pool is empty, wait for a free packet. + Clear_SPI_EXTI_Flag(); + return; + } + + Clear_SPI_EXTI_Flag(); + } +} + +void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_t n_bytes2){ +#if HCI_LOG_ON + PRINTF("HCI <- "); + for(int i=0; i < n_bytes1; i++) + PRINTF("%02X ", *((uint8_t*)data1 + i)); + for(int i=0; i < n_bytes2; i++) + PRINTF("%02X ", *((uint8_t*)data2 + i)); + PRINTF("\n"); +#endif + + Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); +} + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) +{ + hci_command_hdr hc; + + hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); + hc.plen= plen; + + uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; + header[0] = HCI_COMMAND_PKT; + Osal_MemCpy(header+1, &hc, sizeof(hc)); + + hci_write(header, param, sizeof(header), plen); +} + +static void move_list(tListNode * dest_list, tListNode * src_list) +{ + pListNode tmp_node; + + while(!list_is_empty(src_list)){ + list_remove_tail(src_list, &tmp_node); + list_insert_head(dest_list, tmp_node); + } +} + + /* It ensures that we have at least half of the free buffers in the pool. */ +static void free_event_list(void) +{ + tHciDataPacket * pckt; + + Disable_SPI_IRQ(); + + while(list_get_size(&hciReadPktPool) < HCI_READ_PACKET_NUM_MAX/2){ + list_remove_head(&hciReadPktRxQueue, (tListNode **)&pckt); + list_insert_tail(&hciReadPktPool, (tListNode *)pckt); + /* Explicit call to HCI_HandleSPI(), since it cannot be triggered by ISR if IRQ is kept high by + BlueNRG */ + HCI_HandleSPI(); + } + + Enable_SPI_IRQ(); +} + +int hci_send_req(struct hci_request *r, BOOL async) +{ + uint8_t *ptr; + uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + hci_event_pckt *event_pckt; + hci_uart_pckt *hci_hdr; + int to = DEFAULT_TIMEOUT; + struct timer t; + tHciDataPacket * hciReadPacket = NULL; + tListNode hciTempQueue; + + list_init_head(&hciTempQueue); + + free_event_list(); + + hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); + + if(async){ + return 0; + } + + /* Minimum timeout is 1. */ + if(to == 0) + to = 1; + + Timer_Set(&t, to); + + while(1) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + evt_le_meta_event *me; + int len; + + while(1){ + + Disable_SPI_IRQ(); + HCI_HandleSPI(); + Enable_SPI_IRQ(); + + if(Timer_Expired(&t)){ + goto failed; + } + if(!HCI_Queue_Empty()){ + break; + } + } + + /* Extract packet from HCI event queue. */ + Disable_SPI_IRQ(); + list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + + hci_hdr = (void *)hciReadPacket->dataBuff; + + if(hci_hdr->type == HCI_EVENT_PKT){ + + event_pckt = (void *) (hci_hdr->data); + + ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); + len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); + + switch (event_pckt->evt) { + + case EVT_CMD_STATUS: + cs = (void *) ptr; + + if (cs->opcode != opcode) + goto failed; + + if (r->event != EVT_CMD_STATUS) { + if (cs->status) { + goto failed; + } + break; + } + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_CMD_COMPLETE: + cc = (void *) ptr; + + if (cc->opcode != opcode) + goto failed; + + ptr += EVT_CMD_COMPLETE_SIZE; + len -= EVT_CMD_COMPLETE_SIZE; + + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, ptr, r->rlen); + goto done; + + case EVT_LE_META_EVENT: + me = (void *) ptr; + + if (me->subevent != r->event) + break; + + len -= 1; + r->rlen = MIN(len, r->rlen); + Osal_MemCpy(r->rparam, me->data, r->rlen); + goto done; + + case EVT_HARDWARE_ERROR: + goto failed; + + default: + break; + } + } + + /* If there are no more packets to be processed, be sure there is at list one + packet in the pool to process the expected event. + If no free packets are available, discard the processed event and insert it + into the pool. */ + if(list_is_empty(&hciReadPktPool) && list_is_empty(&hciReadPktRxQueue)){ + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); + hciReadPacket=NULL; + } + else { + /* Insert the packet in a different queue. These packets will be + inserted back in the main queue just before exiting from send_req(), so that + these events can be processed by the application. + */ + list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); + hciReadPacket = NULL; + } + + HCI_HandleSPI(); + + Enable_SPI_IRQ(); + + } + +failed: + if(hciReadPacket != NULL) { + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + } + move_list(&hciReadPktRxQueue, &hciTempQueue); + Enable_SPI_IRQ(); + return -1; + +done: + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); +#ifdef POOL_CNT + nr_hciReadPktPool++; +#endif + move_list(&hciReadPktRxQueue, &hciTempQueue); + + Enable_SPI_IRQ(); + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,837 @@ +/** + ****************************************************************************** + * @file ble_hci_le.c + * @author AMG RF Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +int hci_reset(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_RESET; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_disconnect(uint16_t handle, uint8_t reason) +{ + struct hci_request rq; + disconnect_cp cp; + uint8_t status; + + cp.handle = handle; + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) +{ + struct hci_request rq; + read_local_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + + *hci_version = resp.hci_version; + *hci_revision = btohs(resp.hci_revision); + *lmp_pal_version = resp.lmp_pal_version; + *manufacturer_name = btohs(resp.manufacturer_name); + *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); + + return 0; +} + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) +{ + struct hci_request rq; + le_read_buffer_size_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_BUFFER_SIZE; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *pkt_len = resp.pkt_len; + *max_pkt = resp.max_pkt; + + return 0; +} + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter) +{ + struct hci_request rq; + le_set_adv_parameters_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.min_interval = min_interval; + adv_cp.max_interval = max_interval; + adv_cp.advtype = advtype; + adv_cp.own_bdaddr_type = own_bdaddr_type; + adv_cp.direct_bdaddr_type = direct_bdaddr_type; + if(direct_bdaddr != NULL) + Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); + adv_cp.chan_map = chan_map; + adv_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_PARAMETERS; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_adv_data_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.length = length; + Osal_MemCpy(adv_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADV_DATA; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADV_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_advertise_enable(uint8_t enable) +{ + struct hci_request rq; + le_set_advertise_enable_cp adv_cp; + uint8_t status; + + Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); + adv_cp.enable = enable?1:0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; + rq.cparam = &adv_cp; + rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter) +{ + struct hci_request rq; + le_set_scan_parameters_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.type = type; + scan_cp.interval = interval; + scan_cp.window = window; + scan_cp.own_bdaddr_type = own_bdaddr_type; + scan_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) +{ + struct hci_request rq; + le_set_scan_enable_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.enable = enable?1:0; + scan_cp.filter_dup = filter_dup; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_ENABLE; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_rand(uint8_t random_number[8]) +{ + struct hci_request rq; + le_rand_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_RAND; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + Osal_MemCpy(random_number, resp.random, 8); + + return 0; +} + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) +{ + struct hci_request rq; + le_set_scan_response_data_cp scan_resp_cp; + uint8_t status; + + Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); + scan_resp_cp.length = length; + Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; + rq.cparam = &scan_resp_cp; + rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) +{ + struct hci_request rq; + le_read_adv_channel_tx_power_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = LE_RAND_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *tx_power_level = resp.level; + + return 0; +} + +int hci_le_set_random_address(tBDAddr bdaddr) +{ + struct hci_request rq; + le_set_random_address_cp set_rand_addr_cp; + uint8_t status; + + Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); + Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; + rq.cparam = &set_rand_addr_cp; + rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_read_bd_addr(tBDAddr bdaddr) +{ + struct hci_request rq; + read_bd_addr_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_BD_ADDR; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &resp; + rq.rlen = READ_BD_ADDR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); + + return 0; +} + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) +{ + struct hci_request rq; + le_create_connection_cp create_cp; + uint8_t status; + + Osal_MemSet(&create_cp, 0, sizeof(create_cp)); + create_cp.interval = interval; + create_cp.window = window; + create_cp.initiator_filter = initiator_filter; + create_cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); + create_cp.own_bdaddr_type = own_bdaddr_type; + create_cp.min_interval=min_interval; + create_cp.max_interval=max_interval; + create_cp.latency = latency; + create_cp.supervision_timeout=supervision_timeout; + create_cp.min_ce_length=min_ce_length; + create_cp.max_ce_length=max_ce_length; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN; + rq.cparam = &create_cp; + rq.clen = LE_CREATE_CONN_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_create_connection_cancel(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CREATE_CONN_CANCEL; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) +{ + struct hci_request rq; + le_encrypt_cp params; + le_encrypt_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemCpy(params.key, key, 16); + Osal_MemCpy(params.plaintext, plaintextData, 16); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ENCRYPT; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + le_ltk_neg_reply_cp params; + le_ltk_neg_reply_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + params.handle = 1; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_LTK_NEG_REPLY; + rq.cparam = ¶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(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_CLEAR_WHITE_LIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0){ + return BLE_STATUS_TIMEOUT; + } + + return status; +} + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) +{ + struct hci_request rq; + le_add_device_to_white_list_cp params; + uint8_t status; + + params.bdaddr_type = bdaddr_type; + Osal_MemCpy(params.bdaddr, bdaddr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; + rq.cparam = ¶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/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1309 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB05A1 cp; + gap_init_rp resp; + + cp.role = role; + cp.privacy_enabled = privacy_enabled; + cp.device_name_char_len = device_name_char_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} +tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB04A1 cp; + gap_init_rp resp; + + cp.role = role; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + SlaveConnIntervMin = htobs(SlaveConnIntervMin); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + SlaveConnIntervMax = htobs(SlaveConnIntervMax); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB05A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.directed_adv_type = directed_adv_type; + cp.adv_interv_min = adv_interv_min; + cp.adv_interv_max = adv_interv_max; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB04A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_io_capability(uint8_t io_capability) +{ + struct hci_request rq; + uint8_t status; + gap_set_io_capability_cp cp; + + cp.io_capability = io_capability; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_IO_CAPABILITY; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode) +{ + struct hci_request rq; + gap_set_auth_requirement_cp cp; + uint8_t status; + + cp.mitm_mode = mitm_mode; + cp.oob_enable = oob_enable; + Osal_MemCpy(cp.oob_data, oob_data, 16); + cp.min_encryption_key_size = min_encryption_key_size; + cp.max_encryption_key_size = max_encryption_key_size; + cp.use_fixed_pin = use_fixed_pin; + cp.fixed_pin = htobl(fixed_pin); + cp.bonding_mode = bonding_mode; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) +{ + struct hci_request rq; + gap_set_author_requirement_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorization_enable = authorization_enable; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) +{ + struct hci_request rq; + gap_passkey_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.passkey = htobl(passkey); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_PASSKEY_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) +{ + struct hci_request rq; + gap_authorization_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorize = authorize; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB05A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + cp.own_address_type = own_address_type; + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB04A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) +{ + struct hci_request rq; + gap_set_undirected_connectable_cp cp; + uint8_t status; + + cp.own_addr_type = own_addr_type; + cp.adv_filter_policy = adv_filter_policy; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) +{ + struct hci_request rq; + gap_slave_security_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.bonding = bonding; + cp.mitm_protection = mitm_protection; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[32]; + uint8_t indx = 0; + + if (AdvLen > (sizeof(buffer)-1)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvLen; + indx++; + + Osal_MemCpy(buffer + indx, AdvData, AdvLen); + indx += AdvLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_UPDATE_ADV_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) +{ + struct hci_request rq; + gap_delete_ad_type_cp cp; + uint8_t status; + + cp.ad_type = ad_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_DELETE_AD_TYPE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required) +{ + struct hci_request rq; + gap_get_security_level_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; + rq.rparam = &resp; + rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *mitm_protection = resp.mitm_protection; + *bonding = resp.bonding; + *oob_data = resp.oob_data; + *passkey_required = resp.passkey_required; + + return resp.status; +} + +tBleStatus aci_gap_configure_whitelist(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) +{ + struct hci_request rq; + gap_terminate_cp cp; + uint8_t status; + + cp.handle = htobs(conn_handle); + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_clear_security_database(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) +{ + struct hci_request rq; + gap_allow_rebond_cp_IDB05A1 cp; + uint8_t status; + + cp.conn_handle = conn_handle; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_allow_rebond_IDB04A1(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_limited_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_general_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_name_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = use_reconn_addr; + indx++; + + Osal_MemCpy(buffer + indx, reconn_addr, 6); + indx += 6; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB05A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB04A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.use_reconn_addr = use_reconn_addr; + Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_start_selective_conn_establish_proc_cp cp; + uint8_t status; + + if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.num_whitelist_entries = num_whitelist_entries; + + Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_create_connection_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CREATE_CONNECTION; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; + rq.cparam = &procedure_code; + rq.clen = 1; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_connection_update_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) +{ + struct hci_request rq; + gap_send_pairing_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.force_rebond = force_rebond; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + gap_resolve_private_address_rp rp; + + Osal_MemCpy(cp.address, private_address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); + + return 0; +} +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + uint8_t status; + + Osal_MemCpy(cp.address, address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_set_broadcast_mode_cp cp; + uint8_t status; + uint8_t indx = 0; + uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; + + if (variable_size > sizeof(cp.var_len_data) ) + return BLE_STATUS_INVALID_PARAMS; + + cp.adv_interv_min = htobs(adv_interv_min); + cp.adv_interv_max = htobs(adv_interv_max); + cp.adv_type = adv_type; + cp.own_addr_type = own_addr_type; + + cp.var_len_data[indx] = adv_data_length; + indx++; + Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); + indx += adv_data_length; + cp.var_len_data[indx] = num_whitelist_entries; + indx ++; + Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_BROADCAST_MODE; + rq.cparam = &cp; + rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_observation_proc_cp cp; + uint8_t status; + + cp.scan_interval = scan_interval; + cp.scan_window = scan_window; + cp.scan_type = scan_type; + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_OBSERVATION_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) +{ + struct hci_request rq; + gap_is_device_bonded_cp cp; + uint8_t status; + + cp.peer_address_type = peer_address_type; + Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_IS_DEVICE_BONDED; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) +{ + struct hci_request rq; + gap_get_bonded_devices_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_BONDED_DEVICES; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (rp.status) { + return rp.status; + } + + *num_devices = rp.num_addr; + if(device_list != NULL) + Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1505 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.c +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : File with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_gatt_init(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INIT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[19]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, service_uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = service_type; + indx++; + + buffer[indx] = max_attr_records; + indx++; + + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle) +{ + struct hci_request rq; + gatt_include_serv_rp resp; + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + service_handle = htobs(service_handle); + Osal_MemCpy(buffer, &service_handle, 2); + indx += 2; + + included_start_handle = htobs(included_start_handle); + Osal_MemCpy(buffer+indx, &included_start_handle, 2); + indx += 2; + + included_end_handle = htobs(included_end_handle); + Osal_MemCpy(buffer+indx, &included_end_handle, 2); + indx += 2; + + if(included_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } else { + uuid_len = 16; + } + + buffer[indx] = included_uuid_type; + indx++; + + Osal_MemCpy(buffer + indx, included_uuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INCLUDE_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *included_handle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[25]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + buffer[indx] = charValueLen; + indx++; + + buffer[indx] = charProperties; + indx++; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *charHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle) +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = descValueMaxLen; + indx++; + + buffer[indx] = descValueLen; + indx++; + + if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + Osal_MemCpy(buffer + indx, descValue, descValueLen); + indx += descValueLen; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = accPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR_DESC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *descHandle = btohs(resp.handle); + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = charValOffset; + indx++; + + buffer[indx] = charValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charValue, charValueLen); + indx += charValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_char_cp cp; + + cp.service_handle = htobs(servHandle); + cp.char_handle = htobs(charHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_CHAR; + rq.cparam = &cp; + rq.clen = GATT_DEL_CHAR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_service(uint16_t servHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_serv_cp cp; + + cp.service_handle = htobs(servHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_inc_serv_cp cp; + + cp.service_handle = htobs(servHandle); + cp.inc_serv_handle = htobs(includeServHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_INC_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_INC_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) +{ + struct hci_request rq; + uint8_t status; + gatt_set_evt_mask_cp cp; + + cp.evt_mask = htobs(event_mask); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_EVT_MASK; + rq.cparam = &cp; + rq.clen = GATT_SET_EVT_MASK_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_exchange_config_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_EXCHANGE_CONFIG; + rq.cparam = &cp; + rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) +{ + struct hci_request rq; + uint8_t status; + att_find_info_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_INFO_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_find_by_type_value_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + Osal_MemCpy(cp.uuid, uuid, 2); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_group_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_prepare_write_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.value_offset = htobs(value_offset); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) +{ + struct hci_request rq; + uint8_t status; + att_execute_write_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.execute = execute; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_prim_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_prim_service_by_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; + rq.cparam = &cp; + rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, + uint16_t end_service_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_find_included_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_service_handle); + cp.end_handle = htobs(end_service_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_of_serv_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_attr_handle = htobs(start_attr_handle); + cp.end_attr_handle = htobs(end_attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t charUuidType, + const uint8_t* charUuid) +{ + struct hci_request rq; + uint8_t status; + + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + start_handle = htobs(start_handle); + Osal_MemCpy(buffer + indx, &start_handle, 2); + indx += 2; + + end_handle = htobs(end_handle); + Osal_MemCpy(buffer + indx, &end_handle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == 0x01){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_descriptors_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.char_val_handle = htobs(char_val_handle); + cp.char_end_handle = htobs(char_end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_read_using_charac_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; + rq.cparam = &cp; + rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles) +{ + struct hci_request rq; + uint8_t status; + gatt_read_multiple_charac_val_cp cp; + + if(num_handles*2 > sizeof(cp.set_of_handles)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.num_handles = htobs(num_handles); + Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_long_charac_val_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; + rq.cparam = &cp; + rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_signed_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_confirm_indication_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_CONFIRM_INDICATION; + rq.cparam = &cp; + rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = write_status; + indx += 1; + + buffer[indx] = err_code; + indx += 1; + + buffer[indx] = att_val_len; + indx += 1; + + Osal_MemCpy(buffer + indx, att_val, att_val_len); + indx += att_val_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(uint16_t conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ALLOW_READ; + rq.cparam = &cp; + rq.clen = GATT_ALLOW_READ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission) +{ + struct hci_request rq; + gatt_set_security_permission_cp cp; + uint8_t status; + + cp.service_handle = htobs(service_handle); + cp.attr_handle = htobs(attr_handle); + cp.security_permission = security_permission; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; + rq.cparam = &cp; + rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + charDescHandle = htobs(charDescHandle); + Osal_MemCpy(buffer + indx, &charDescHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charDescValOffset, 2); + indx += 2; + + buffer[indx] = charDescValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); + indx += charDescValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_DESC_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_cp cp; + gatt_read_handle_val_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = btohs(rp.value_len); + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_offset_cp cp; + gatt_read_handle_val_offset_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rp.value_len; + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value) +{ + struct hci_request rq; + uint8_t status; + gatt_upd_char_val_ext_cp cp; + + if(value_length > sizeof(cp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.service_handle = htobs(service_handle); + cp.char_handle = htobs(char_handle); + cp.update_type = update_type; + cp.char_length = htobs(char_length); + cp.value_offset = htobs(value_offset); + cp.value_length = value_length; + Osal_MemCpy(cp.value, value, value_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL_EXT; + rq.cparam = &cp; + rq.clen = GATT_UPD_CHAR_VAL_EXT_CP_SIZE + value_length; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,266 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number) +{ + struct hci_request rq; + hal_get_fw_build_number_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_FW_BUILD_NUMBER; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *build_number = rp.build_number; + + return 0; +} + +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((len+2) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = offset; + indx++; + + buffer[indx] = len; + indx++; + + Osal_MemCpy(buffer + indx, val, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + hal_read_config_data_cp cp; + hal_read_config_data_rp rp; + + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_READ_CONFIG_DATA; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rq.rlen-1; + + Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) +{ + struct hci_request rq; + hal_set_tx_power_level_cp cp; + uint8_t status; + + cp.en_high_power = en_high_power; + cp.pa_level = pa_level; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets) +{ + struct hci_request rq; + hal_le_tx_test_packet_number_rp resp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_LE_TX_TEST_PACKET_NUMBER; + rq.rparam = &resp; + rq.rlen = sizeof(resp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *number_of_packets = btohl(resp.number_of_packets); + + return 0; +} + +tBleStatus aci_hal_device_standby(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_DEVICE_STANDBY; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_start(uint8_t rf_channel) +{ + struct hci_request rq; + hal_tone_start_cp cp; + uint8_t status; + + cp.rf_channel = rf_channel; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_START; + rq.cparam = &cp; + rq.clen = HAL_TONE_START_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_stop(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_STOP; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]) +{ + struct hci_request rq; + hal_get_link_status_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_LINK_STATUS; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(link_status,rp.link_status,sizeof(link_status)); + for(int i = 0; i < 8; i++) + conn_handle[i] = btohs(rp.conn_handle[i]); + + return 0; +} + +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot) +{ + struct hci_request rq; + hal_get_anchor_period_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_ANCHOR_PERIOD; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *anchor_period = btohl(rp.anchor_period); + *max_free_slot = btohl(rp.max_free_slot); + + return 0; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,117 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB05A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.min_ce_length = htobs(min_ce_length); + cp.max_ce_length = htobs(max_ce_length); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB04A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,269 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_updater_aci.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_updater_reboot(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_get_updater_version(uint8_t *version) +{ + struct hci_request rq; + get_updater_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_VERSION; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) +{ + struct hci_request rq; + get_updater_bufsize_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_BUFSIZE; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_reset_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = htobl(address); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_SECTOR; + rq.cparam = &cp; + rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_program_data_block(uint32_t address, + uint16_t len, + const uint8_t *data) +{ + struct hci_request rq; + uint8_t status; + updater_prog_data_block_cp cp; + + if( len > sizeof(cp.data)) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(len); + Osal_MemCpy(cp.data, data, len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_read_data_block(uint32_t address, + uint16_t data_len, + uint8_t *data) +{ + struct hci_request rq; + updater_read_data_block_cp cp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + + if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(data_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; + rq.rparam = buffer; + rq.rlen = data_len + 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + // First byte is status + Osal_MemCpy(data, buffer+1, data_len); + + return buffer[0]; +} + +tBleStatus aci_updater_calc_crc(uint32_t address, + uint8_t num_sectors, + uint32_t *crc) +{ + struct hci_request rq; + updater_calc_crc_cp cp; + updater_calc_crc_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + cp.address = htobl(address); + cp.num_sectors = num_sectors; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_CALC_CRC; + rq.cparam = &cp; + rq.clen = UPDATER_CALC_CRC_CP_SIZE; + rq.rparam = &resp; + rq.rlen = UPDATER_CALC_CRC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *crc = btohl(resp.crc); + + return resp.status; +} + +tBleStatus aci_updater_hw_version(uint8_t *version) +{ + struct hci_request rq; + updater_hw_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_HW_VERSION; + rq.rparam = &resp; + rq.rlen = UPDATER_HW_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,423 @@ + +#include "ble_hal.h" +#include "ble_hal_types.h" +#include "ble_status.h" +#include "bluenrg_aci.h" +#include "bluenrg_utils.h" +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "ble_osal.h" +#include "string.h" +#include "stm32_bluenrg_ble.h" + +#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 +#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 + +#define BASE_ADDRESS 0x10010000 + +#define FW_OFFSET (2*1024) // 2 KB +#define FW_OFFSET_MS 0 +#define FULL_STACK_SIZE (66*1024) // 66 KB +#define BOOTLOADER_SIZE (2*1024) // 2 kB +#define SECTOR_SIZE (2*1024) // 2 KB + +// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + +// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 +#define CRC_POLY 0x04C11DB7 // the poly without the x**32 + +#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC + +#define IFR_SIZE 192 +#define IFR_BASE_ADDRESS 0x10020000 +#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data + +#if BLUENRG_MS +#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET +#else +#define IFR_WRITE_OFFSET_BEGIN 0 +#endif + + +#define BLUE_FLAG_OFFSET 0x8C0 +#define MAX_ERASE_RETRIES 2 +#define MAX_WRITE_RETRIES 2 +#define MIN_WRITE_BLOCK_SIZE 4 +#define MAX_WRITE_BLOCK_SIZE 64 // 64 bytes +#define READ_BLOCK_SIZE 64 // 64 bytes + +#define RETRY_COMMAND(func, num_ret, error) \ +{ \ + uint8_t num_retries; \ + num_retries = 0; \ + error = 0; \ + while (num_retries++ < num_ret) { \ + if (func == BLE_STATUS_SUCCESS) \ + break; \ + if (num_retries == num_ret) \ + error = BLE_UTIL_ACI_ERROR; \ + } \ +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, + they are extended with 0xFF until sector size is reached +*/ +static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) +{ + uint32_t i, j, a1; + uint32_t crc, value; + + crc = 0; + for (i = 0; i < SECTOR_SIZE; i += 4) { + uint8_t *dataw = (uint8_t *) &value; + + dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; + dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; + dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; + dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; + + crc = crc ^ value; + for (j = 0; j < 32; j ++) { + a1 = (crc >> 31) & 0x1; + crc = (crc << 1) ^ (a1 * CRC_POLY); + } + } + + return crc; +} + +int program_device(const uint8_t *fw_image, uint32_t fw_size) +{ + uint8_t version, num_erase_retries, status, write_block_size; + uint32_t address; + uint32_t crc, crc2, crc_size; + uint32_t fw_offset = FW_OFFSET; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + if(aci_updater_hw_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version==0x31){ + // It does not contain bootloader inside first sector. It may contain code. + fw_offset = FW_OFFSET_MS; + } + + if (fw_size != FULL_STACK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + if (fw_size % MIN_WRITE_BLOCK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + + /*********************************************************************** + * Erase BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + /*********************************************************************** + * Erase and Program sectors + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE) { + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(BASE_ADDRESS + i); + for (int j=i; ((j<i+SECTOR_SIZE)&&(j<fw_size)); j += write_block_size) { + + write_block_size = MIN(fw_size-j, MAX_WRITE_BLOCK_SIZE); + + RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, write_block_size, fw_image+j), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + break; + } + if (status == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + } + + /*********************************************************************** + * Verify firmware + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE){ + address = BASE_ADDRESS + i; + if(aci_updater_calc_crc(address, 1, &crc)) + return BLE_UTIL_ACI_ERROR; + + crc_size = MIN(fw_size-i,SECTOR_SIZE); + + crc2 = updater_calc_crc(fw_image+i,crc_size); + if(crc!=crc2) + return BLE_UTIL_CRC_ERROR; + } + + /*********************************************************************** + * Write BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +int read_IFR(uint8_t *data) +{ + uint8_t version, offset; + tBleStatus ret; + + offset = 0; + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + /*********************************************************************** + * Reading last 3 IFR 64-byte blocks + ************************************************************************/ + for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(BASE_ADDRESS+i, READ_BLOCK_SIZE, (data+offset)); + offset += READ_BLOCK_SIZE; + if(ret) return BLE_UTIL_ACI_ERROR; + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; + +} + +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) +{ + IFR_config->stack_mode = data[0]; + IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); + IFR_config->master_sca = data[30]; + IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); + IFR_config->year = BCD_TO_INT(data[41]); + IFR_config->month = BCD_TO_INT(data[42]); + IFR_config->day = BCD_TO_INT(data[43]); +} + +int IFR_validate(IFR_config2_TypeDef *IFR_config) +{ +#if BLUENRG_MS + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) +#else + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) +#endif + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode + if(IFR_config->master_sca > 7) + return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->day > 31 || IFR_config->day < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + + return BLE_STATUS_SUCCESS; +} + +/* TODO: Function to generate data from given options. */ + +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) +{ + data[0] = IFR_config->stack_mode; + HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); + data[30] = IFR_config->master_sca; + HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); + data[41] = INT_TO_BCD(IFR_config->year); + data[42] = INT_TO_BCD(IFR_config->month); + data[43] = INT_TO_BCD(IFR_config->day); +} + + +int program_IFR(const IFR_config_TypeDef *ifr_image) +{ + uint8_t version, num_erase_retries; + tBleStatus ret; +#if BLUENRG_MS + const uint8_t *ifr_data = (uint8_t *)ifr_image; +#else + uint8_t ifr_data[SECTOR_SIZE]; +#endif + uint8_t hwVersion; + uint16_t fwVersion; + + if(getBlueNRGVersion(&hwVersion, &fwVersion)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + +#ifndef BLUENRG_MS + /*********************************************************************** + * READ IFR data + ************************************************************************/ + for(int i = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_data+i); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + } +#endif + + /*********************************************************************** + * Erase & Flashing IFR sectors + ************************************************************************/ +#ifndef BLUENRG_MS + Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); +#endif + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(IFR_BASE_ADDRESS); + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += MAX_WRITE_BLOCK_SIZE, j += MAX_WRITE_BLOCK_SIZE) { + RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, MAX_WRITE_BLOCK_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); + if (ret != BLE_STATUS_SUCCESS) + break; + } + if (ret == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + + /*********************************************************************** + * Verify IFR + ************************************************************************/ + { + uint8_t ifr_updated[READ_BLOCK_SIZE]; + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE, j += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ifr_data+j, READ_BLOCK_SIZE) != 0) + return BLE_UTIL_WRONG_VERIFY; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) +{ + uint8_t ifr_updated[READ_BLOCK_SIZE]; + uint8_t version, ret = BLE_STATUS_SUCCESS; + + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + for(int i = 0; i < IFR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, READ_BLOCK_SIZE) != 0) + { + ret = BLE_UTIL_WRONG_VERIFY; + break; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return ret; +} + +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) +{ + uint8_t status; + uint8_t hci_version, lmp_pal_version; + uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; + + status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, + &manufacturer_name, &lmp_pal_subversion); + + if (status == BLE_STATUS_SUCCESS) { + *hwVersion = hci_revision >> 8; + *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number + *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number + *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number + } + + return status; +} + +uint8_t getBlueNRGUpdaterVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(version)) + return BLE_UTIL_ACI_ERROR; + + if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_updater_hw_version(version)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t isHWBootloader_Patched(void) +{ + uint8_t status, version; + uint32_t crc, address = 0x10010000; + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); + if (status != BLE_STATUS_SUCCESS) + return 0; + + if (crc == BOOTLOADER_CRC_NOT_PATCHED) + return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +#include "ble_gp_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function sets a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * @param[in] t A pointer to the timer + * @param[in] interval The interval before the timer expires. + * + */ +void +Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +Timer_Expired(struct timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + tClockTime diff = (Clock_Time() - t->start) + 1; + return t->interval < diff; + +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +tClockTime +Timer_Remaining(struct timer *t) +{ + return t->start + t->interval - Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +#ifdef __DMA_LP__ + +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID) +{ + TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, + (pf_TIMER_TimerCallBack_t) timercb); + TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); + + return (BLE_STATUS_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) +{ + TIMER_Delete(timerID); + + return (BLE_STATUS_SUCCESS); +} + +#endif /* __DMA_LP__ */ +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,119 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Circular Linked List Implementation. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/****************************************************************************** + * Include Files +******************************************************************************/ +#include <ble_hal_types.h> +#include "ble_list.h" + +/****************************************************************************** + * Function Definitions +******************************************************************************/ +void list_init_head (tListNode * listHead) +{ + listHead->next = listHead; + listHead->prev = listHead; +} + +uint8_t list_is_empty (tListNode * listHead) +{ + return ((listHead->next == listHead)? TRUE:FALSE); +} + +void list_insert_head (tListNode * listHead, tListNode * node) +{ + node->next = listHead->next; + node->prev = listHead; + listHead->next = node; + (node->next)->prev = node; +} + + +void list_insert_tail (tListNode * listHead, tListNode * node) +{ + node->next = listHead; + node->prev = listHead->prev; + listHead->prev = node; + (node->prev)->next = node; +} + + +void list_remove_node (tListNode * node) +{ + (node->prev)->next = node->next; + (node->next)->prev = node->prev; +} + + +void list_remove_head (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->next; + list_remove_node (listHead->next); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_remove_tail (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->prev; + list_remove_node (listHead->prev); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_insert_node_after (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node->next; + node->prev = ref_node; + ref_node->next = node; + (node->next)->prev = node; +} + + +void list_insert_node_before (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node; + node->prev = ref_node->prev; + ref_node->prev = node; + (node->prev)->next = node; +} + + +int list_get_size (tListNode * listHead) +{ + int size = 0; + tListNode * temp = listHead->next; + while (temp != listHead) + { + size++; + temp = temp->next; + } + return (size); +} + +void list_get_next_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->next; +} + + +void list_get_prev_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->prev; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,72 @@ +/** +****************************************************************************** +* @file ble_osal.c +* @author AMS - HEA&RF BU / CL +* @version V1.0.0 +* @date 04-July-2014 +* @brief Implementation of OS abstraction layer functions used by the +* library. +****************************************************************************** +* @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> +#include <ble_osal.h> + + /** + * @brief Osal_MemCpy + * @param dest: Pointer to the destination buffer + * @param src : Pointer to the source buffer + * @param size: Number of bytes to copy from the source to the destination + * buffer + * @retval Pointer to the destination buffer + */ +void* Osal_MemCpy(void *dest, const void *src, unsigned int size) +{ + return(memcpy(dest,src,size)); +} + +/** + * @brief Osal_MemSet + * @param ptr : Pointer to block of memory to fill + * @param value: Value to assign to each byte of the memory block + * @param size : Number of bytes to be set to "value" + * @retval Pointer to the filled block of memory + */ +void* Osal_MemSet(void *ptr, int value, unsigned int size) +{ + return(memset(ptr,value,size)); +} + +/****************************************************************************** + * local Functions + *****************************************************************************/ + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,36 @@ + +#include "ble_clock.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/wait_api.h" + #include "mbed-drivers/rtc_time.h" +#else + #include "wait_api.h" + #include "rtc_time.h" +#endif + +const uint32_t CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + //Not Used +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return clock(); +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,715 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + ****************************************************************************** + * @file btle.cpp + * @author STMicroelectronics + * @brief Implementation BlueNRG Init and helper functions. + ****************************************************************************** + * @copy + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + */ + + +#include "btle.h" +#include "ble/Gap.h" +#include "ble/GapEvents.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" +#include "ble_utils.h" + +#include "bluenrg_targets.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* C File Includes ------------------------------------------------------------------*/ +#include <stdio.h> +#include <string.h> +#include "ble_hci.h" +#include "ble_hci_const.h" +#include "bluenrg_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" +#include "bluenrg_utils.h" + +#include "ble_hal_types.h" +#include "ble_hal.h" +#include "ble_gp_timer.h" +#include "ble_osal.h" +#include "ble_sm.h" +#include "ble_debug.h" + +#ifdef __cplusplus +} +#endif + +#define IDB04A1 0 +#define IDB05A1 1 + +/* See file 'bluenrg_targets.h' for details regarding the BLUENRG_STACK_MODE */ +#define STACK_MODE BLUENRG_STACK_MODE + +void HCI_Input(tHciDataPacket * hciReadPacket); + +uint16_t g_gap_service_handle = 0; +uint16_t g_appearance_char_handle = 0; +uint16_t g_device_name_char_handle = 0; +uint16_t g_preferred_connection_parameters_char_handle = 0; + +/* Private variables ---------------------------------------------------------*/ +volatile uint8_t set_connectable = 1; + +static char versionString[32]; +uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ + +/**************************************************************************/ +/*! + @brief Init the BTLE stack with the specified role + @returns void +*/ +/**************************************************************************/ +void btleInit(void) +{ + PRINTF("btleInit>>\n\r"); + + int ret; + uint8_t hwVersion; + uint16_t fwVersion; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* get the BlueNRG HW and FW versions */ + getBlueNRGVersion(&hwVersion, &fwVersion); + + /* + * Reset BlueNRG again otherwise we won't + * be able to change its MAC address. + * aci_hal_write_config_data() must be the first + * command after reset otherwise it will fail. + */ + BlueNRG_RST(); + + if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ + bnrg_expansion_board = IDB05A1; + } + + /* set BLE version string */ + setVersionString(hwVersion, fwVersion); + + if (bnrg_expansion_board == IDB05A1) { + uint8_t stackMode = STACK_MODE; + ret = aci_hal_write_config_data(CONFIG_DATA_MODE_OFFSET, + CONFIG_DATA_MODE_LEN, + &stackMode); + } + + ret = aci_gatt_init(); + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GATT_Init failed.\n"); + } + if (bnrg_expansion_board == IDB05A1) { + ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1, + 0, + 0x18, + &service_handle, + &dev_name_char_handle, + &appearance_char_handle); + } else { + // IDB04A1 is configured as peripheral by default + ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + } + + // read the default static address and inject it into the GAP object + { + Gap::Address_t BLE_address_BE = { 0 }; + uint8_t data_len_out; + aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS, BDADDR_SIZE, &data_len_out, BLE_address_BE); + // FIXME error handling of this function + BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE); + } + + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GAP_Init failed.\n"); + } + + //FIXME: Security and passkey set by default + ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, + OOB_AUTH_DATA_ABSENT, + NULL, + 7, + 16, + USE_FIXED_PIN_FOR_PAIRING, + 123456, + BONDING); + if (ret != BLE_STATUS_SUCCESS) { + PRINTF("Auth Req set failed.\n"); + } + + aci_hal_set_tx_power_level(1,4); + + g_gap_service_handle = service_handle; + g_appearance_char_handle = appearance_char_handle; + g_device_name_char_handle = dev_name_char_handle; + //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API + /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, + strlen(name), (tHalUint8 *)name);*/ + + signalEventsToProcess(); + // update the peripheral preferred conenction parameters handle + // This value is hardcoded at the moment. + g_preferred_connection_parameters_char_handle = 10; + + return; +} + +/**************************************************************************/ +/*! + @brief mbedOS + + @param[in] void + + @returns +*/ +/**************************************************************************/ +int btle_handler_pending = 0; + +void btle_handler(void) +{ + btle_handler_pending = 0; + BlueNRGGap::getInstance().Process(); + HCI_HandleSPI(); + HCI_Process(); +} + +/* set BLE Version string */ +void setVersionString(uint8_t hwVersion, uint16_t fwVersion) +{ + if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) { + snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u", + hwVersion>>4, (hwVersion&0x0F), + fwVersion>>8, (fwVersion&0x00F0)>>4); + } else { + snprintf(versionString, sizeof(versionString), "ST (unknown spec)"); + } +} + +/* get BLE Version string */ +const char* getVersionString(void) +{ + return versionString; +} + +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type) +{ + tBleStatus ret; + + // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED + if(bnrg_expansion_board == IDB05A1) { + PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window); + PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type); + ret = aci_gap_start_observation_procedure(scan_interval, + scan_window, + scan_type, + own_address_type, + 0); // 1 to filter duplicates + } else { + ret = BLE_STATUS_INVALID_CID; + } + + return ret; + +} + +/*! + @brief Not Used + + @param[in] void + + @returns +*/ +void SPI_Poll(void) +{ + //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); + return; +} + +void Attribute_Modified_CB(evt_blue_aci *blue_evt) +{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t *att_data; + uint8_t offset; + + if (bnrg_expansion_board == IDB05A1) { + evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = evt->offset; + } else { + evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data; + conn_handle = evt->conn_handle; + attr_handle = evt->attr_handle; + data_length = evt->data_length; + att_data = evt->att_data; + offset = 0; + } + + //Extract the GattCharacteristic from p_characteristics[] and find the properties mask + GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle); + if(p_char!=NULL) { + GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE; + BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE; + PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]); + PRINTF("getProperties 0x%x\n\r",p_char->getProperties()); + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; + } + + if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) { + currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; + } + PRINTF("currentHandle %d\n\r", currentHandle); + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && + currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { + + GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1; + + PRINTF("*****NOTIFICATION CASE\n\r"); + //Now Check if data written in Enable or Disable + if((uint16_t)att_data[0]==1) { + //PRINTF("Notify ENABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle); + } else { + //PRINTF("Notify DISABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle); + } + return; + } + + //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) && + currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) { + + PRINTF("*****WRITE CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = p_char->getValueAttribute().getHandle(); + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle); + //Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) { + BlueNRGGattServer::getInstance().write( + p_char->getValueAttribute().getHandle(), + (uint8_t*)att_data, + data_length, + false + ); + } + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } else { + PRINTF("*****WRITE DESCRIPTOR CASE\n\r"); + + GattWriteCallbackParams writeParams; + writeParams.connHandle = conn_handle; + writeParams.handle = attr_handle; + writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG? + writeParams.len = data_length; + writeParams.data = att_data; + writeParams.offset = offset; + + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + } + } + +} + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************************/ + /*! + @brief Handle HCI Stack Event + + @param[in] pckt + Event Packet sent by the stack to be decoded + + @returns + */ + /**************************************************************************/ + extern void HCI_Event_CB(void *pckt) { + hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; + hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; + + if(hci_pckt->type != HCI_EVENT_PKT) + return; + + switch(event_pckt->evt){ + + case EVT_DISCONN_COMPLETE: + { + PRINTF("EVT_DISCONN_COMPLETE\n"); + + evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data; + + if(BlueNRGGap::getInstance().getGapRole() == Gap::CENTRAL) { + BlueNRGGattClient::getInstance().removeGattConnectionClient(evt->handle, evt->reason); + } + + BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason); + } + break; + + case EVT_LE_META_EVENT: + { + PRINTF("EVT_LE_META_EVENT\n"); + + evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; + + switch(evt->subevent){ + + case EVT_LE_CONN_COMPLETE: + { + PRINTF("EVT_LE_CONN_COMPLETE\n"); + Gap::Address_t ownAddr; + Gap::AddressType_t ownAddrType; + BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr); + + Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + Gap::Role_t role; + + evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; + + BlueNRGGap::getInstance().setConnectionHandle(cc->handle); + BlueNRGGap::ConnectionParams_t connectionParams = { + /* minConnectionInterval = */ cc->interval, + /* maxConnectionInterval = */ cc->interval, + /* slaveLatency = */ cc->latency, + /* connectionSupervisionTimeout = */ cc->supervision_timeout + }; + + BlueNRGGap::getInstance().setConnectionInterval(cc->interval); + + switch (cc->peer_bdaddr_type) { + case PUBLIC_ADDR: + peerAddrType = BLEProtocol::AddressType::PUBLIC; + break; + case STATIC_RANDOM_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC; + break; + case RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE; + break; + case NON_RESOLVABLE_PRIVATE_ADDR: + peerAddrType = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE; + break; + } + //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role); + switch (cc->role) { + case 0: //master + role = Gap::CENTRAL; + BlueNRGGattClient::getInstance().createGattConnectionClient(cc->handle); + break; + case 1: + role = Gap::PERIPHERAL; + break; + default: + role = Gap::PERIPHERAL; + break; + } + + BlueNRGGap::getInstance().setGapRole(role); + + BlueNRGGap::getInstance().processConnectionEvent(cc->handle, + role, + peerAddrType, + cc->peer_bdaddr, + ownAddrType, + ownAddr, + &connectionParams); + } + break; + + case EVT_LE_ADVERTISING_REPORT: + PRINTF("EVT_LE_ADVERTISING_REPORT\n\r"); + /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */ + // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT) + // Formally the structure related to both events are identical except that for the ADV REPORT + // there is one more field (number of reports) which is not forwarded to upper layer. + // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT. + le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1); + PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + break; + } + } + break; + + case EVT_VENDOR: + { + evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; + //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode); + + switch(blue_evt->ecode){ + + case EVT_BLUE_GATT_WRITE_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_WRITE_PERMIT_REQ\r\n"); + evt_gatt_write_permit_req* write_req = (evt_gatt_write_permit_req*)blue_evt->data; + + // ask the local server if the write operation is authorized + uint8_t err_code = BlueNRGGattServer::getInstance().Write_Request_CB( + write_req->conn_handle, + write_req->attr_handle, + write_req->data_length, + write_req->data + ); + uint8_t write_status = err_code == 0 ? 0 : 1; + + // reply to the shield + aci_gatt_write_response( + write_req->conn_handle, + write_req->attr_handle, + write_status, + err_code, + write_req->data_length, + write_req->data + ); + } + break; + + case EVT_BLUE_GATT_READ_PERMIT_REQ: + { + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r"); + evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle); + BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle); + } + break; + + case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: + { + PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r"); + /* this callback is invoked when a GATT attribute is modified + extract callback data and pass to suitable handler function */ + Attribute_Modified_CB(blue_evt); + } + break; + + //Any cases for Data Sent Notifications? + case EVT_BLUE_GATT_NOTIFICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_NOTIFICATION"); + break; + case EVT_BLUE_GATT_INDICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_INDICATION"); + break; + + case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r"); + evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_data_length, + pr->attribute_data_list); + } + break; + case EVT_BLUE_ATT_READ_BY_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r"); + evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle, + pr->event_data_length, + pr->handle_value_pair_length, + pr->handle_value_pair); + } + break; + case EVT_BLUE_ATT_READ_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_RESP\n\r"); + evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_value); + } + break; + case EVT_BLUE_ATT_EXEC_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle, + pr->event_data_length); + } + break; + case EVT_BLUE_ATT_PREPARE_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_handle, + pr->offset, + pr->part_attr_value); + } + break; + case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP: + { + PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r"); + evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle, + pr->event_data_length, + pr->attr_handle, + pr->attr_value); + } + break; + case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r"); + evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle, + pr->event_data_length, + pr->handles_info_list); + } + break; + case EVT_BLUE_ATT_FIND_INFORMATION_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r"); + evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle, + pr->event_data_length, + pr->format, + pr->handle_uuid_pair); + } + break; + case EVT_BLUE_GATT_PROCEDURE_COMPLETE: + { + evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code); + BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code); + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_REQ: + { + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_REQ\r\n"); + evt_l2cap_conn_upd_req *evt = (evt_l2cap_conn_upd_req*)blue_evt->data; + if(bnrg_expansion_board == IDB05A1) { + // we assume the application accepts the request from the slave + aci_l2cap_connection_parameter_update_response_IDB05A1(evt->conn_handle, + evt->interval_min, + evt->interval_max, + evt->slave_latency, + evt->timeout_mult, + CONN_L1, CONN_L2, + evt->identifier, + 0x0000); + } + } + break; + + case EVT_BLUE_L2CAP_CONN_UPD_RESP: + { + evt_l2cap_conn_upd_resp *evt = (evt_l2cap_conn_upd_resp*)blue_evt->data; + PRINTF("EVT_BLUE_L2CAP_CONN_UPD_RESP code=0x%x, result=0x%x\r\n", evt->code, evt->result); + } + break; + + case EVT_LE_CONN_UPDATE_COMPLETE: + { + evt_le_connection_update_complete *evt = (evt_le_connection_update_complete*)blue_evt->data; + PRINTF("EVT_LE_CONN_UPDATE_COMPLETE status=0x%x\r\n", evt->status); + } + break; + + case EVT_BLUE_GAP_DEVICE_FOUND: + { + evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data; + PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + } + break; + + case EVT_BLUE_GAP_PROCEDURE_COMPLETE: + { + evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data; + //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code); + + switch(pr->procedure_code) { + case GAP_OBSERVATION_PROC_IDB05A1: + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL); + break; + } + } + break; + } + } + break; + } + return ; + } + + +#ifdef __cplusplus +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,217 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.cpp + * @author CL + * @version V1.0.0 + * @date 15-June-2015 + * @brief + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRGGap.h" +#include "BlueNRGDevice.h" +#include "btle.h" + +// FIXME: find a better way to get the instance of the BlueNRG device +extern BlueNRGDevice bluenrgDeviceInstance; + + +//////////////////////////////////////// +// Start of C function wrappers +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32_bluenrg_ble.h" +#include "ble_debug.h" + + +void BlueNRG_RST(void) +{ + bluenrgDeviceInstance.reset(); +} + +uint8_t BlueNRG_DataPresent(void) +{ + return (bluenrgDeviceInstance.dataPresent()); +} + + +/** + * @brief This function is a utility to print the log time +* in the format HH:MM:SS:MSS (DK GUI time format) + * @param None + * @retval None + */ +void print_csv_time(void){ +#ifdef PRINT_CSV_FORMAT + uint32_t ms = 0;//ms_counter; + PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000); +#endif +} + +/** + * @brief Writes data to a serial interface. + * @param data1 : 1st buffer + * @param data2 : 2nd buffer + * @param n_bytes1: number of bytes in 1st buffer + * @param n_bytes2: number of bytes in 2nd buffer + * @retval None + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, + int32_t n_bytes2) +{ + struct timer t; + + Timer_Set(&t, CLOCK_SECOND/10); + +#ifdef PRINT_CSV_FORMAT + print_csv_time(); + for (int i=0; i<n_bytes1; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data1)[i]); + } + for (int i=0; i<n_bytes2; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data2)[i]); + } + PRINT_CSV("\n"); +#endif + + while(1){ + if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; + if(Timer_Expired(&t)){ + break; + } + } +} + + +/** + * @brief Activate internal bootloader using pin. + * @param None + * @retval None + */ +void BlueNRG_HW_Bootloader(void) +{ + // Reset BlueNRG SPI interface + BlueNRG_RST(); + + // Send an ACI command to reboot BlueNRG in bootloader mode + // The safest way to get in bootloader mode is keeping high + // the interrupt pin during reset, but this would require many + // changes to the current mbed driver + aci_updater_start(); +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size) +{ + int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size); + + return ret; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2); + + return ret; +} + +/** + * @brief Enable SPI IRQ. + * @param None + * @retval None + */ +void Enable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.enable_irq(); +} + +void signalEventsToProcess(void) { + if(btle_handler_pending == 0) { + btle_handler_pending = 1; + bluenrgDeviceInstance.signalEventsToProcess(BLE::DEFAULT_INSTANCE); + } +} + +/** + * @brief Disable SPI IRQ. + * @param None + * @retval None + */ +void Disable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.disable_irq(); +} + +/** + * @brief Clear Pending SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_IRQ(void) +{ +} + +/** + * @brief Clear EXTI (External Interrupt) line for SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_EXTI_Flag(void) +{ +} + + + + +#ifdef __cplusplus +} +#endif +// End of C function wrappers +//////////////////////////////////////// + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <ble_payload.h> + +Payload::Payload() { + stringLength = 0; + payloadUnitCount = 0; + payload = NULL; +} + +Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + stringLength = string_ength; + payloadUnitCount = 0; + payload = NULL; + + int index = 0; + while( index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + UnitPayload *obj = new UnitPayload[payloadUnitCount]; + int i=0; + int c=0; + int j,k; + + while(i<payloadUnitCount) + { + obj[i].length=tokenString[c]; + obj[i].id=tokenString[c+1]; + + obj[i].data = new uint8_t[obj[i].length]; + for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) + { + obj[i].data[k]=tokenString[j]; + + } + + c=c+obj[i].length+1; + i++; + + } + payload = obj; +} + +uint8_t Payload::getPayloadUnitCount() { + return payloadUnitCount; +} + +uint8_t Payload::getIDAtIndex(int index) { + return payload[index].get_id(); +} + +uint8_t Payload::getLengthAtIndex(int index) { + return payload[index].get_length(); +} + +uint8_t* Payload::getDataAtIndex(int index) { + return payload[index].get_data(); +} + +int8_t Payload::getInt8AtIndex(int index) { + uint8_t* str = payload[index].get_data(); + int8_t value = (int8_t)str[0]; + return value; +} + +uint16_t Payload::getUint16AtIndex(int index) { + uint16_t* str = (uint16_t*)payload[index].get_data(); + uint16_t value = str[0]; + return value; +} + +uint8_t* Payload::getSerializedAdDataAtIndex(int index) { + uint8_t length = payload[index].get_length(); + uint8_t* data = payload[index].get_data(); + uint8_t id = payload[index].get_id(); + uint8_t *serializedAdData = new uint8_t[length]; + + serializedAdData[0] = id; + for(int i=0; i<length-1; i++) { + serializedAdData[i+1] = data[i]; + } + return serializedAdData; +} + +Payload::~Payload() { + int i = 0; + + if(payload) { + while(i<payloadUnitCount) { + if(payload->data) { + delete[] payload->data; + payload->data = NULL; + } + } + delete[] payload; + payload = NULL; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,93 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ble_utils.h" + +/**************************************************************************/ +/*! + @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power + +*/ +/**************************************************************************/ +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(dBMLevel==-18) { + EN_HIGH_POWER = 0; + PA_LEVEL = 0; + } + else if(dBMLevel==-15) { + EN_HIGH_POWER = 0; + PA_LEVEL = 1; + } + else if(dBMLevel==-14) { + EN_HIGH_POWER = 1; + PA_LEVEL = 0; + } + else if(dBMLevel==-12) { + EN_HIGH_POWER = 0; + PA_LEVEL = 2; + } + else if(dBMLevel==-11) { + EN_HIGH_POWER = 1; + PA_LEVEL = 1; + } + else if(dBMLevel==-9) { + EN_HIGH_POWER = 0; + PA_LEVEL = 3; + } + else if(dBMLevel==-8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 2; + } + else if(dBMLevel==-6) { + EN_HIGH_POWER = 0; + PA_LEVEL = 4; + } + else if(dBMLevel==-5) { + EN_HIGH_POWER = 1; + PA_LEVEL = 3; + } + else if(dBMLevel==-2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 4; + } + else if(dBMLevel==0) { + EN_HIGH_POWER = 0; + PA_LEVEL = 6; + } + else if(dBMLevel==2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 5; + } + else if(dBMLevel==4) { + EN_HIGH_POWER = 1; + PA_LEVEL = 6; + } + else if(dBMLevel==5) { + EN_HIGH_POWER = 0; + PA_LEVEL = 7; + } + else if(dBMLevel==8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + else { + ret = ERR_INVALID_HCI_CMD_PARAMS; + } + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/BLE_Thermometer/source/main.cpp Fri Jun 29 01:19:08 2018 +0000 @@ -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. + */ + +#include <events/mbed_events.h> +#include "mbed.h" +#include "ble/BLE.h" +#include "ble/services/HealthThermometerService.h" + +DigitalOut led1(LED1, 1); + +const static char DEVICE_NAME[] = "Therm"; +static const uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE}; + +static float currentTemperature = 39.6; +static HealthThermometerService *thermometerServicePtr; + +static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); + +/* Restart Advertising on disconnection*/ +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) +{ + BLE::Instance().gap().startAdvertising(); +} + +void updateSensorValue(void) { + /* Do blocking calls or whatever is necessary for sensor polling. + In our case, we simply update the Temperature measurement. */ + currentTemperature = (currentTemperature + 0.1 > 43.0) ? 39.6 : currentTemperature + 0.1; + thermometerServicePtr->updateTemperature(currentTemperature); +} + +void periodicCallback(void) +{ + led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ + + if (BLE::Instance().gap().getState().connected) { + eventQueue.call(updateSensorValue); + } +} + +void onBleInitError(BLE &ble, ble_error_t error) +{ + /* Initialization error handling should go here */ +} + +void printMacAddress() +{ + /* Print out device MAC address to the console*/ + Gap::AddressType_t addr_type; + Gap::Address_t address; + BLE::Instance().gap().getAddress(&addr_type, address); + printf("DEVICE MAC ADDRESS: "); + for (int i = 5; i >= 1; i--){ + printf("%02x:", address[i]); + } + printf("%02x\r\n", address[0]); +} + +void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) +{ + BLE& ble = params->ble; + ble_error_t error = params->error; + + if (error != BLE_ERROR_NONE) { + onBleInitError(ble, error); + return; + } + + if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { + return; + } + + ble.gap().onDisconnection(disconnectionCallback); + + /* Setup primary service. */ + thermometerServicePtr = new HealthThermometerService(ble, currentTemperature, HealthThermometerService::LOCATION_EAR); + + /* setup advertising */ + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::THERMOMETER_EAR); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.gap().setAdvertisingInterval(1000); /* 1000ms */ + ble.gap().startAdvertising(); + + printMacAddress(); +} + +void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { + BLE &ble = BLE::Instance(); + eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); +} + +int main() +{ + eventQueue.call_every(500, periodicCallback); + + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(scheduleBleEventsProcessing); + ble.init(bleInitComplete); + + eventQueue.dispatch_forever(); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/LICENSE Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os-example-ble-master/README.md Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,127 @@ +# BLE Examples +This repo contains a collection of BLE example applications based on +mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli). Each example subdirectory contains a separate mbed-cli module meant for building an executable. + +Please browse to subdirectories for specific documentation. + +Getting Started +=============== + + +Pre-Requisites +-------------- + +To build these examples, you need to have a computer with software installed as described [here](https://os.mbed.com/docs/latest/tools/setup.html). + +In order to use BLE in mbed OS you need one of the following hardware combinations: + +* A Nordic nRF51-based board such as [nrf51dk](https://www.nordicsemi.com/eng/Products/nRF51-DK) or [mkit](https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822-mKIT). +* A Nordic nRF52-based board such as [nrf52DK](https://os.mbed.com/platforms/Nordic-nRF52-DK/) +* A supported target, such as the [NUCLEO-F401RE](http://www.st.com/en/evaluation-tools/nucleo-f401re.html), with a BLE shield or an external BLE peripheral, such as an [ST shield](http://www.st.com/web/catalog/tools/FM116/SC1075/PF260517). +* A [DISCO_L475VG_IOT01A (ref B-L475E-IOT01A)](http://www.st.com/en/evaluation-tools/b-l475e-iot01a.html) board. + + +The [BLE documentation](https://os.mbed.com/docs/latest/reference/bluetooth.html) describes the BLE APIs on mbed OS. + +Targets for BLE +--------------- + +The following targets have been tested and work with these examples: + +* Nordic: + * NRF51_DK + * NRF52_DK + +* Boards with an ST shield plugged in: + * K64F + * NUCLEO_F401RE + +* STMicroelectronics: + * DISCO_L475VG_IOT01A (ref B-L475E-IOT01A) + + <span> **Important:** if an ST shield is used with the K64F board, an hardware is patch required. Check out https://developer.mbed.org/teams/ST/code/X_NUCLEO_IDB0XA1/ for more information.</span> + +### Using ST Nucleo shield on other targets + +It is possible to use the ST Nucleo shield on boards not directly supported by these examples as long as the board has an Arduino UNO R3 connector. + +To makes the board compatible with the ST shield three things are required: +* Add the BLE feature to your target. +* Add the BLE implementation for the ST shield to the list of modules which have to be compiled. +* Indicate to the BLE implementation that your board use an Arduino connector. + +All these operations can be done in the file `mbed_app.json` present in every example. + +In the section `target_overrides` add a new object named after your target. +In this object two fields are required: +* `"target.features_add": ["BLE"]` Add the BLE feature to the target. +* `"target.extra_labels_add": ["ST_BLUENRG"]`: Add the BLE implementation of the ST shield to the list of the application modules. + +As an example, this is the JSON bit which has to be added in the `target_overrides` section of `mbed_app.json` for a `NUCLEO_F411RE` board. + +```json + "NUCLEO_F411RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, +``` + +<span> **Note:** You can get more information about the configuration system in the [documentation](https://os.mbed.com/docs/latest/reference/configuration.html)</span> + +<span> **Important:** It is required to apply an hardware patch to the ST shield if it is used on a board with an Arduino connector. Check out https://developer.mbed.org/teams/ST/code/X_NUCLEO_IDB0XA1/ for more information.</span> + + +Building and testing the examples +--------------------------------- + +__To build an example:__ + +1. Clone the repository containing the collection of examples: + + ``` + $ git clone https://github.com/ARMmbed/mbed-os-example-ble.git + ``` + + + **Tip:** If you don't have GitHub installed, you can [download a zip file](https://github.com/ARMmbed/mbed-os-example-ble/archive/master.zip) of the repository. + +1. Using a command-line tool, navigate to any of the example directories, like BLE_Beacon: + + ``` + $ cd mbed-os-example-ble + $ cd BLE_Beacon + ``` + +1. Update the source tree: + + ``` + mbed deploy + ``` + +1. Run the build: + + ```mbed compile -t <ARM | GCC_ARM> -m <YOUR_TARGET>``` + +__To run the application on your board:__ + +1. Connect your mbed board to your computer over USB. It appears as removable storage. + +1. When you run the ``mbed compile`` command, as you did above, mbed cli creates a BIN or an HEX file in a ```BUILD/<target-name>/<toolchain>``` directory under the example's directory. Drag and drop the file to the removable storage. + + +Exactly which executables are generated depends on the target that you have +chosen. For Nordic Semiconductor targets, the following .hex files will be present: + + * `<module_name>.hex` is the one which can be flashed to the target. + * `<module_name>.elf` is an ELF binary containing symbols (useful for debugging). + +**Note:** Depending on the build process, the file which has to be flashed on a Nordic target can also be named `<module_name>-combined.hex`. If `<module_name>-combined.hex` and `<module_name>.hex` are present in the build directory, flash `<module_name>-combined.hex. + +**Note:** On non Nordic targets, the file to flash can also be named `<module_name>.bin`. Refer to mbed-cli, mbed-os and your board vendor documentation for more informations. + + +Known issues +============ + +* [NUCLEO_F411RE]: Some BLE examples doesn't work with the X-NUCLEO BLE shield. See [#40](https://github.com/ARMmbed/mbed-os-example-ble/issues/40) +* [NRF5] Impossible to debug or flash the examples with IAR: See [#39](https://github.com/ARMmbed/mbed-os-example-ble/issues/39)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Jun 29 01:19:08 2018 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/a7c7b631e539 \ No newline at end of file