mamont mamont
/
test_ble
nrf52-dk
Revision 0:70ce6da7a141, committed 2020-06-05
- Comitter:
- mamont090671
- Date:
- Fri Jun 05 10:49:10 2020 +0000
- Commit message:
- nrf52840
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.mbed Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,1 @@ +ROOT=.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed_app.json Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,16 @@ +{ + "target_overrides": { + "K64F": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "NUCLEO_F401RE": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + }, + "DISCO_L475VG_IOT01A": { + "target.features_add": ["BLE"], + "target.extra_labels_add": ["ST_BLUENRG"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/module.json Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/.gitignore Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,9 @@ +# vim temporary files +*.sw* + +# yotta files +build +yotta_modules +yotta_targets +.yotta.json +upload.tar.gz
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/README.md Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,34 @@ +# BLE-X-NUCLEO-IDB0XA1 + +BLE_API wrapper Library for X-NUCLEO-IDB05A1 BlueNRG (Bluetooth Low Energy) Expansion Board + +## Introduction + +This firmware package implements the port of BLE_API to STMicroelectronics' [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) Bluetooth Low Energy Nucleo Expansion Board. + +### Arduino Connector Compatibility Warning + +X-NUCLEO-IDB05A1 is Arduino compatible with an exception: instead of using pin **D13** for the SPI clock, pin **D3** is used. +The default configuration for this library is having the SPI clock on pin **D3**. + +To be fully Arduino compatible, X-NUCLEO-IDB05A1 needs a small HW patch. + +For X-NUCLEO-IDB05A1 this patch consists in removing zero resistor **R4** and instead soldering zero resistor **R6**. + +In case you patch your board, then you also have to configure this library to use pin **D13** to drive the SPI clock. To this aim you need to compile this driver with macro `BLUENRG_PIN_SPI_SCK=D13` defined. + +If you use pin **D13** for the SPI clock, please be aware that on STM32 Nucleo boards you may **not** drive the LED, otherwise you will get a conflict: the LED on STM32 Nucleo boards is connected to pin **D13**. + +Referring to the current list of tested platforms (see [X-NUCLEO-IDB05A1](https://developer.mbed.org/components/X-NUCLEO-IDB05A1-Bluetooth-Low-Energy/) page), the patch is required by [ST-Nucleo-F103RB](https://developer.mbed.org/platforms/ST-Nucleo-F103RB/); [ST-Nucleo-F302R8](https://developer.mbed.org/platforms/ST-Nucleo-F302R8/); [ST-Nucleo-F411RE](https://developer.mbed.org/platforms/ST-Nucleo-F411RE/); [ST-Nucleo-F446RE](https://developer.mbed.org/platforms/ST-Nucleo-F446RE/); and [FRDM-K64F](https://developer.mbed.org/platforms/FRDM-K64F/). + +### Firmware update + +For better performance and compatibility with latest mbed API, you should update firmware of X-NUCLEO-IDB05A1 component by using this simple [application](https://developer.mbed.org/teams/ST/code/BlueNRG-MS-Stack-Updater). + +### Driver configuration + +In order to use the BlueNRG-MS module together with other targets, you need to set the macros defined in file [bluenrg_targets.h](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/bluenrg/bluenrg_targets.h). Please, update the [mbed_lib.json](https://github.com/ARMmbed/ble-x-nucleo-idb0xa1/blob/master/mbed_lib.json) to include the list of extra macros that configure the driver for your target. + +## Example Applications + +To run BLE example applications using X-NUCLEO-IDB05A1 Expansion Board based on mbed OS and built with [mbed-cli](https://github.com/ARMmbed/mbed-cli), please refer to section [Using ST shield on other targets](https://github.com/ARMmbed/mbed-os-example-ble#using-st-nucleo-shield-on-other-targets) in the official [mbed-os-example-ble](https://github.com/ARMmbed/mbed-os-example-ble) page.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDevice.h Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGDiscoveredCharacteristic.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ +#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ + +#include "ble/DiscoveredCharacteristic.h" + +class BlueNRGGattClient; /* forward declaration */ + +class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic { +public: + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + void setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn); + + + void setLastHandle(GattAttribute::Handle_t lastHandleIn); +}; + +#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGap.h Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattClient.h Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattConnectionClient.h Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/bluenrg/BlueNRGGattServer.h Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_clock.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_CLOCK_H__ +#define __BLE_CLOCK_H__ + +#include <ble_hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __BLE_CLOCK_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_compiler.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,36 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_debug.h Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_gp_timer.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_gp_timer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : General purpose timer library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_GP_TIMER_H__ +#define __BLE_GP_TIMER_H__ + +#include "ble_clock.h" +#include "ble_status.h" +#ifdef __DMA_LP__ +#include "stm32xx_timerserver.h" +#endif /* __DMA_LP__ */ + +/** + * timer + * + * A structure that represents a timer. Use Timer_Set() to set the timer. + * + */ +struct timer { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + tClockTime start; + tClockTime interval; + +#endif +}; + +typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); + +/** + * Timer_Set + * + * @param[in] t Pointer to a timer structure + * @param[in] interval timeout value + * + * This function sets the timeout value of a timer. + * + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * Timer_Reset + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the time it previously expired. + * + */ +void Timer_Reset(struct timer *t); + +/** + * Timer_Restart + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the current time. + * + */ +void Timer_Restart(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns TRUE if timer is expired, FALSE otherwise. + * + */ +int Timer_Expired(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns the time needed for expiration. + * + * @return Time before timer's expiration. + */ +tClockTime Timer_Remaining(struct timer *t); + +#ifdef __DMA_LP__ +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID); + +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); +#endif /* __DMA_LP__ */ + +#endif /* __BLE_GP_TIMER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,108 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_H__ +#define __BLE_HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void signalEventsToProcess(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __BLE_HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hal_types.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_HAL_TYPES_H__ +#define __BLE_HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __BLE_HAL_TYPES_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,126 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.0, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_H_ +#define __BLE_HCI_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ble_hal_types.h" +#include "ble_link_layer.h" +#include <ble_list.h> + +#define HCI_READ_PACKET_SIZE 128 //71 + +/** + * Maximum payload of HCI commands that can be sent. Change this value if needed. + * This value can be up to 255. + */ +#define HCI_MAX_PAYLOAD_SIZE 128 + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_READ_PACKET_SIZE]; + uint8_t data_len; +} tHciDataPacket; + +struct hci_request { + uint16_t ogf; + uint16_t ocf; + int event; + void *cparam; + int clen; + void *rparam; + int rlen; +}; + +typedef enum +{ + BUSY, + AVAILABLE +} HCI_CMD_STATUS_t; + + +/** + * This function must be used to pass the packet received from the HCI + * interface to the BLE Stack HCI state machine. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * + */ +void HCI_Input(tHciDataPacket *hciReadPacket); + +/** + * Initialization function. Must be done before any data can be received from + * BLE controller. + */ +void HCI_Init(void); + +/** + * Callback used to pass events to application. + * + * @param[in] pckt The event. + * + */ +extern void HCI_Event_CB(void *pckt); + +/** + * Processing function that must be called after an event is received from + * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if + * necessary. +*/ +void HCI_Process(void); + +/** + * @brief Check if queue of HCI event is empty or not. + * @note This funtion can be used to check if the event queue from BlueNRG is empty. This + * is useful when checking if it is safe to go to sleep. + * @return TRUE if event queue is empty. FALSE otherwhise. + */ +BOOL HCI_Queue_Empty(void); +/** + * Iterrupt service routine that must be called when the BlueNRG + * reports a packet received or an event to the host through the + * BlueNRG interrupt line. + */ +#ifdef __DMA_LP__ +void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); +void HCI_Process_Notification_Request(void); +void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); +void HCI_Wait_For_Response(void); +#else +void HCI_Isr(void); +void HCI_HandleSPI(void); + +int hci_send_req(struct hci_request *r, BOOL async); +#endif /* __DMA_LP__ */ + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#ifdef __cplusplus +} +#endif + + +#endif /* __BLE_HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_const.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,548 @@ +/****************************************************************************** +* +* File Description +* --------------------- +* This file defines constants and functions for HCI layer. +* See Bluetooth Core v 4.0, Vol. 2, Part E. +* +*******************************************************************************/ + +#ifndef __HCI_INTERNAL_H_ +#define __HCI_INTERNAL_H_ + +#include "ble_compiler.h" +#include "ble_hal_types.h" +#include "ble_clock.h" +#include "ble_link_layer.h" +#include "ble_hci.h" + +#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) + + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +typedef __packed struct _hci_uart_pckt{ + uint8_t type; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef __packed struct _hci_command_hdr{ + uint16_t opcode; /* OCF & OGF */ + uint8_t plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef __packed struct _hci_event_pckt{ + uint8_t evt; + uint8_t plen; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef __packed struct _hci_acl_hdr{ + uint16_t handle; /* Handle & Flags(PB, BC) */ + uint16_t dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef __packed struct _disconnect_cp{ + uint16_t handle; + uint8_t reason; +} PACKED disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 + +#define OCF_SET_EVENT_MASK 0x0001 +#define OCF_RESET 0x0003 + +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D +typedef __packed struct _read_transmit_power_level_cp{ + uint16_t handle; + uint8_t type; +} PACKED read_transmit_power_level_cp; +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 +typedef __packed struct _read_transmit_power_level_rp{ + uint8_t status; + uint16_t handle; + int8_t level; +} PACKED read_transmit_power_level_rp; +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 + +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 +#define OCF_HOST_BUFFER_SIZE 0x0033 +#define OCF_HOST_NUM_COMP_PKTS 0x0035 + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef __packed struct _read_local_version_rp{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t manufacturer_name; + uint16_t lmp_pal_subversion; +} PACKED read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_COMMANDS 0x0002 +#define OCF_READ_LOCAL_FEATURES 0x0003 + +#define OCF_READ_BD_ADDR 0x0009 +typedef __packed struct _read_bd_addr_rp{ + uint8_t status; + tBDAddr bdaddr; +} PACKED read_bd_addr_rp; +#define READ_BD_ADDR_RP_SIZE 7 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +#define OCF_READ_RSSI 0x0005 +typedef __packed struct _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef __packed struct _read_rssi_rp{ + uint8_t status; + uint16_t handle; + int8_t rssi; +} PACKED read_rssi_rp; +#define READ_RSSI_RP_SIZE 4 + + +/* LE commands */ +#define OGF_LE_CTL 0x08 + +#define OCF_LE_SET_EVENT_MASK 0x0001 +typedef __packed struct _le_set_event_mask_cp{ + uint8_t mask[8]; +} PACKED le_set_event_mask_cp; +#define LE_SET_EVENT_MASK_CP_SIZE 8 + +#define OCF_LE_READ_BUFFER_SIZE 0x0002 +typedef __packed struct _le_read_buffer_size_rp{ + uint8_t status; + uint16_t pkt_len; + uint8_t max_pkt; +} PACKED le_read_buffer_size_rp; +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 + +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 +typedef __packed struct _le_read_local_supported_features_rp{ + uint8_t status; + uint8_t features[8]; +} PACKED le_read_local_supported_features_rp; +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 + +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 +typedef __packed struct _le_set_random_address_cp{ + tBDAddr bdaddr; +} PACKED le_set_random_address_cp; +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 + +#define OCF_LE_SET_ADV_PARAMETERS 0x0006 +typedef __packed struct _le_set_adv_parameters_cp{ + uint16_t min_interval; + uint16_t max_interval; + uint8_t advtype; + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint8_t chan_map; + uint8_t filter; +} PACKED le_set_adv_parameters_cp; +#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 + +#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 +typedef __packed struct _le_read_adv_channel_tx_power_rp{ + uint8_t status; + int8_t level; +} PACKED le_read_adv_channel_tx_power_rp; +#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 + +#define OCF_LE_SET_ADV_DATA 0x0008 +typedef __packed struct _le_set_adv_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_adv_data_cp; +#define LE_SET_ADV_DATA_CP_SIZE 32 + +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 +typedef __packed struct _le_set_scan_response_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_scan_response_data_cp; +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 + +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A +typedef __packed struct _le_set_advertise_enable_cp{ + uint8_t enable; +} PACKED le_set_advertise_enable_cp; +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 + +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B +typedef __packed struct _le_set_scan_parameters_cp{ + uint8_t type; + uint16_t interval; + uint16_t window; + uint8_t own_bdaddr_type; + uint8_t filter; +} PACKED le_set_scan_parameters_cp; +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 + +#define OCF_LE_SET_SCAN_ENABLE 0x000C +typedef __packed struct _le_set_scan_enable_cp{ + uint8_t enable; + uint8_t filter_dup; +} PACKED le_set_scan_enable_cp; +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 + +#define OCF_LE_CREATE_CONN 0x000D +typedef __packed struct _le_create_connection_cp{ + uint16_t interval; + uint16_t window; + uint8_t initiator_filter; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_create_connection_cp; +#define LE_CREATE_CONN_CP_SIZE 25 + +#define OCF_LE_CREATE_CONN_CANCEL 0x000E + +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F +typedef __packed struct _le_read_white_list_size_rp{ + uint8_t status; + uint8_t size; +} PACKED le_read_white_list_size_rp; +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 + +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 +typedef __packed struct _le_add_device_to_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_add_device_to_white_list_cp; +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 +typedef __packed struct _le_remove_device_from_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_remove_device_from_white_list_cp; +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_CONN_UPDATE 0x0013 +typedef __packed struct _le_connection_update_cp{ + uint16_t handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t supervision_timeout; + uint16_t min_ce_length; + uint16_t max_ce_length; +} PACKED le_connection_update_cp; +#define LE_CONN_UPDATE_CP_SIZE 14 + +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 +typedef __packed struct _le_set_host_channel_classification_cp{ + uint8_t map[5]; +} PACKED le_set_host_channel_classification_cp; +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 + +#define OCF_LE_READ_CHANNEL_MAP 0x0015 +typedef __packed struct _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef __packed struct _le_read_channel_map_rp{ + uint8_t status; + uint16_t handle; + uint8_t map[5]; +} PACKED le_read_channel_map_rp; +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 + +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 +typedef __packed struct _le_read_remote_used_features_cp{ + uint16_t handle; +} PACKED le_read_remote_used_features_cp; +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 + +#define OCF_LE_ENCRYPT 0x0017 +typedef __packed struct _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef __packed struct _le_encrypt_rp{ + uint8_t status; + uint8_t encdata[16]; +} PACKED le_encrypt_rp; +#define LE_ENCRYPT_RP_SIZE 17 + +#define OCF_LE_RAND 0x0018 +typedef __packed struct _le_rand_rp{ + uint8_t status; + uint8_t random[8]; +} PACKED le_rand_rp; +#define LE_RAND_RP_SIZE 9 + +#define OCF_LE_START_ENCRYPTION 0x0019 +typedef __packed struct _le_start_encryption_cp{ + uint16_t handle; + uint8_t random[8]; + uint16_t diversifier; + uint8_t key[16]; +} PACKED le_start_encryption_cp; +#define LE_START_ENCRYPTION_CP_SIZE 28 + +#define OCF_LE_LTK_REPLY 0x001A +typedef __packed struct _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef __packed struct _le_ltk_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_reply_rp; +#define LE_LTK_REPLY_RP_SIZE 3 + +#define OCF_LE_LTK_NEG_REPLY 0x001B +typedef __packed struct _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef __packed struct _le_ltk_neg_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_neg_reply_rp; +#define LE_LTK_NEG_REPLY_RP_SIZE 3 + +#define OCF_LE_READ_SUPPORTED_STATES 0x001C +typedef __packed struct _le_read_supported_states_rp{ + uint8_t status; + uint8_t states[8]; +} PACKED le_read_supported_states_rp; +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 + +#define OCF_LE_RECEIVER_TEST 0x001D +typedef __packed struct _le_receiver_test_cp{ + uint8_t frequency; +} PACKED le_receiver_test_cp; +#define LE_RECEIVER_TEST_CP_SIZE 1 + +#define OCF_LE_TRANSMITTER_TEST 0x001E +typedef __packed struct _le_transmitter_test_cp{ + uint8_t frequency; + uint8_t length; + uint8_t payload; +} PACKED le_transmitter_test_cp; +#define LE_TRANSMITTER_TEST_CP_SIZE 3 + +#define OCF_LE_TEST_END 0x001F +typedef __packed struct _le_test_end_rp{ + uint8_t status; + uint16_t num_pkts; +} PACKED le_test_end_rp; +#define LE_TEST_END_RP_SIZE 3 + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3f + + +/*------------- Events -------------*/ +#define EVT_CONN_COMPLETE 0x03 +typedef __packed struct _evt_conn_complete{ + uint8_t status; + uint16_t handle; + tBDAddr bdaddr; + uint8_t link_type; + uint8_t encr_mode; +} PACKED evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef __packed struct _evt_disconn_complete{ + uint8_t status; + uint16_t handle; + uint8_t reason; +} PACKED evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef __packed struct _evt_encrypt_change{ + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} PACKED evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C + +#define EVT_CMD_COMPLETE 0x0E +typedef __packed struct _evt_cmd_complete{ + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef __packed struct _evt_cmd_status{ + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef __packed struct _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef __packed struct _evt_num_comp_pkts{ + uint8_t num_hndl; + /* variable length part */ +} PACKED evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +/* variable length part of evt_num_comp_pkts. */ +typedef __packed struct _evt_num_comp_pkts_param{ + uint16_t hndl; + uint16_t num_comp_pkts; +} PACKED evt_num_comp_pkts_param; +#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 + +#define EVT_DATA_BUFFER_OVERFLOW 0x1A +typedef __packed struct _evt_data_buffer_overflow{ + uint8_t link_type; +} PACKED evt_data_buffer_overflow; +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 + +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef __packed struct _evt_encryption_key_refresh_complete{ + uint8_t status; + uint16_t handle; +} PACKED evt_encryption_key_refresh_complete; +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 + +#define EVT_LE_META_EVENT 0x3E +typedef __packed struct _evt_le_meta_event{ + uint8_t subevent; + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef __packed struct _evt_le_connection_complete{ + uint8_t status; + uint16_t handle; + uint8_t role; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; +} PACKED evt_le_connection_complete; +#define EVT_LE_CONN_COMPLETE_SIZE 18 + +#define EVT_LE_ADVERTISING_REPORT 0x02 +typedef __packed struct _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t data_length; + uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef __packed struct _evt_le_connection_update_complete{ + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; +} PACKED evt_le_connection_update_complete; +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 + +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +typedef __packed struct _evt_le_read_remote_used_features_complete{ + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} PACKED evt_le_read_remote_used_features_complete; +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 + +#define EVT_LE_LTK_REQUEST 0x05 +typedef __packed struct _evt_le_long_term_key_request{ + uint16_t handle; + uint8_t random[8]; + uint16_t ediv; +} PACKED evt_le_long_term_key_request; +#define EVT_LE_LTK_REQUEST_SIZE 12 + +/** +* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, +* application can use @ref evt_blue_aci structure to parse the packet. +*/ +#define EVT_VENDOR 0xFF + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + + + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); + +typedef enum { + WAITING_TYPE, + WAITING_OPCODE1, + WAITING_OPCODE2, + WAITING_EVENT_CODE, + WAITING_HANDLE, + WAITING_HANDLE_FLAG, + WAITING_PARAM_LEN, + WAITING_DATA_LEN1, + WAITING_DATA_LEN2, + WAITING_PAYLOAD +}hci_state; + +typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); + +/* HCI library functions. */ + +int hci_send_req(struct hci_request *r, BOOL async); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_hci_le.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,170 @@ +/******************** (C) COPYRIGHT 2016 STMicroelectronics ******************** +* File Name : ble_hci_le.h +* Author : AMG RF FW team +* Version : V1.1.0 +* Date : 18-July-2016 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.1, Vol. 2, Part E. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_HCI_LE_H_ +#define __BLE_HCI_LE_H_ + +#include "ble_hal_types.h" +#include "ble_link_layer.h" + +/** + * @defgroup HCI_Error_codes HCI Error codes + * @{ + */ +#define HCI_UNKNOWN_COMMAND 0x01 +#define HCI_NO_CONNECTION 0x02 +#define HCI_HARDWARE_FAILURE 0x03 +#define HCI_PAGE_TIMEOUT 0x04 +#define HCI_AUTHENTICATION_FAILURE 0x05 +#define HCI_PIN_OR_KEY_MISSING 0x06 +#define HCI_MEMORY_FULL 0x07 +#define HCI_CONNECTION_TIMEOUT 0x08 +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a +#define HCI_ACL_CONNECTION_EXISTS 0x0b +#define HCI_COMMAND_DISALLOWED 0x0c +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d +#define HCI_REJECTED_SECURITY 0x0e +#define HCI_REJECTED_PERSONAL 0x0f +#define HCI_HOST_TIMEOUT 0x10 +#define HCI_UNSUPPORTED_FEATURE 0x11 +#define HCI_INVALID_PARAMETERS 0x12 +#define HCI_OE_USER_ENDED_CONNECTION 0x13 +#define HCI_OE_LOW_RESOURCES 0x14 +#define HCI_OE_POWER_OFF 0x15 +#define HCI_CONNECTION_TERMINATED 0x16 +#define HCI_REPEATED_ATTEMPTS 0x17 +#define HCI_PAIRING_NOT_ALLOWED 0x18 +#define HCI_UNKNOWN_LMP_PDU 0x19 +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a +#define HCI_SCO_OFFSET_REJECTED 0x1b +#define HCI_SCO_INTERVAL_REJECTED 0x1c +#define HCI_AIR_MODE_REJECTED 0x1d +#define HCI_INVALID_LMP_PARAMETERS 0x1e +#define HCI_UNSPECIFIED_ERROR 0x1f +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 +#define HCI_UNIT_LINK_KEY_USED 0x26 +#define HCI_QOS_NOT_SUPPORTED 0x27 +#define HCI_INSTANT_PASSED 0x28 +#define HCI_PAIRING_NOT_SUPPORTED 0x29 +#define HCI_TRANSACTION_COLLISION 0x2a +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c +#define HCI_QOS_REJECTED 0x2d +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e +#define HCI_INSUFFICIENT_SECURITY 0x2f +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 +#define HCI_ROLE_SWITCH_PENDING 0x32 +#define HCI_SLOT_VIOLATION 0x34 +#define HCI_ROLE_SWITCH_FAILED 0x35 +#define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 +#define HCI_CONN_REJ_NO_CH_FOUND 0x39 +#define HCI_CONTROLLER_BUSY 0x3A +#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B +#define HCI_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_CONN_TERM_MIC_FAIL 0x3D +#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E +#define HCI_MAC_CONN_FAILED 0x3F +/** + * @} + */ + + +/* + * HCI library functions. + * Each function returns 0 in case of success, otherwise one of the error codes. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(uint8_t enable); + +int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, + uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter); + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter); + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); + +int hci_le_rand(uint8_t random_number[8]); + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); + +int hci_acl_data(const uint8_t * data, uint16_t len); + +int hci_le_set_random_address(tBDAddr bdaddr); + +int hci_read_bd_addr(tBDAddr bdaddr); + +int hci_le_read_white_list_size(uint8_t *size); + +int hci_le_clear_white_list(); + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); + +int hci_le_ltk_request_reply(uint8_t key[16]); + +int hci_le_ltk_request_neg_reply(); + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); + +int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, + const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, + uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length); + +int hci_le_create_connection_cancel(void); + +int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level); + +int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi); + +int hci_le_read_local_supported_features(uint8_t *features); + +int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); + +int hci_le_read_supported_states(uint8_t states[8]); + +int hci_le_receiver_test(uint8_t frequency); + +int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); + +int hci_le_test_end(uint16_t *num_pkts); + +int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, + uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion); + + + +#endif /* __BLE_HCI_LE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_link_layer.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,161 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_link_layer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's link layer. It contains +* definition of functions for link layer, most of which are +* mapped to HCI commands. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef _BLE_LINK_LAYER_H +#define _BLE_LINK_LAYER_H + +#include <ble_status.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + *@name Advertising filter + *Advertising policy for filtering (white list related) + *@{ + */ +#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ +#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ +/** + * @} + */ + + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef uint8_t tBDAddr[6]; + + +/** + *@name Bluetooth address types + * Bluetooth address types + *@{ + */ +#define PUBLIC_ADDR (0) +#define RANDOM_ADDR (1) +#define STATIC_RANDOM_ADDR (1) +#define RESOLVABLE_PRIVATE_ADDR (2) +#define NON_RESOLVABLE_PRIVATE_ADDR (3) +/** + * @} + */ + +/** + *@name Directed advertising types + * Type of advertising during directed advertising + *@{ + */ +#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) +#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) +/** + * @} + */ + +/** + * @name Advertising type + * @{ + */ + +/** + * undirected scannable and connectable + */ +#define ADV_IND (0x00) + +/** + * directed non scannable + */ +#define ADV_DIRECT_IND (0x01) + +/** + * scannable non connectable + */ +#define ADV_SCAN_IND (0x02) + +/** + * non-connectable and no scan response + */ +#define ADV_NONCONN_IND (0x03) + +/** + * scan response + */ +#define SCAN_RSP (0x04) + +/** + * @} + */ + +/* 0X05-0XFF RESERVED */ + +/** + * @name Advertising ranges + * @{ + */ + +/** + * lowest allowed interval value for connectable types(20ms)..multiple of 625us + */ +#define ADV_INTERVAL_LOWEST_CONN (0X0020) + +/** + * highest allowed interval value (10.24s)..multiple of 625us. + */ +#define ADV_INTERVAL_HIGHEST (0X4000) + +/** + * lowest allowed interval value for non connectable types + * (100ms)..multiple of 625us. + */ +#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) + +/** + * @} + */ + +/** + * @name Advertising channels + * @{ + */ +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 +/** + * @} + */ + +/** + * @name Scan_types Scan types + * @{ + */ +#define PASSIVE_SCAN 0 +#define ACTIVE_SCAN 1 +/** + * @} + */ + +/** + * @} + */ + + +#endif /* _BLE_LINK_LAYER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_list.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,47 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for linked list library. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef _BLE_LIST_H_ +#define _BLE_LIST_H_ + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +uint8_t list_is_empty (tListNode * listHead); + +void list_insert_head (tListNode * listHead, tListNode * node); + +void list_insert_tail (tListNode * listHead, tListNode * node); + +void list_remove_node (tListNode * node); + +void list_remove_head (tListNode * listHead, tListNode ** node ); + +void list_remove_tail (tListNode * listHead, tListNode ** node ); + +void list_insert_node_after (tListNode * node, tListNode * ref_node); + +void list_insert_node_before (tListNode * node, tListNode * ref_node); + +int list_get_size (tListNode * listHead); + +void list_get_next_node (tListNode * ref_node, tListNode ** node); + +void list_get_prev_node (tListNode * ref_node, tListNode ** node); + +#endif /* _BLE_LIST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_osal.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_OSAL_H__ +#define __BLE_OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <ble_hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __BLE_OSAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_sm.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,158 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_sm.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's security manager. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLE_SM_H__ +#define __BLE_SM_H__ + +/****************************************************************************** +* Macros +*****************************************************************************/ + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/* IO capabilities */ +/** + * @anchor IO_capabilities + * @name IO capabilities + * @{ + */ +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define IO_CAP_KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) +/** + * @} + */ + +/** + * @anchor Auth_req + * @name Authentication requirements + * @{ + */ +#define BONDING (0x01) +#define NO_BONDING (0x00) +/** + * @} + */ + +/** + * @anchor MITM_req + * @name MITM protection requirements + * @{ + */ +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor OOB_Data + * @name Out-Of-Band data + * @{ + */ +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) +/** + * @} + */ + +/** + * @anchor Author_req + * @name Authorization requirements + * @{ + */ +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor Conn_authorization + * @name Connection authorization + * @{ + */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) +/** + * @} + */ + +/** + * @anchor Use_fixed_pin + * @name Use fixed pin + * @{ + */ +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +/** + * @} + */ + +/** + * @anchor link_security_status + * @name Link security status + * @{ + */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) +/** + * @} + */ + +/** + * @anchor SMP_pairing_failed_codes + * @name SMP pairing failed reason codes + * @{ + */ +#define PASSKEY_ENTRY_FAILED (0x01) +#define OOB_NOT_AVAILABLE (0x02) +#define AUTH_REQ_CANNOT_BE_MET (0x03) +#define CONFIRM_VALUE_FAILED (0x04) +#define PAIRING_NOT_SUPPORTED (0x05) +#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) +#define CMD_NOT_SUPPORTED (0x07) +#define UNSPECIFIED_REASON (0x08) +#define VERY_EARLY_NEXT_ATTEMPT (0x09) +#define SM_INVALID_PARAMS (0x0A) +/** + * @} + */ + +/** + * @anchor pairing_failed_codes + * @name Pairing failed error codes + * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event + * @{ + */ +#define SM_PAIRING_SUCCESS (0x00) +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/ble_status.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,188 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_status.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file with BLE Stack status codes. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BLE_STATUS_H__ +#define __BLE_STATUS_H__ + +#include <ble_hal_types.h> + +/** @addtogroup Middlewares + * @{ + */ + +/** @defgroup ST + * @{ + */ + +/** @defgroup SimpleBlueNRG_HCI + * @{ + */ + +/** @defgroup ble_status Bluetooth Status/Error Codes + * @{ + */ + +typedef uint8_t tBleStatus; + +/* Error Codes as specified by the specification + * according to the spec the error codes range + * from 0x00 to 0x3F + */ +/** + * @name Standard error codes + * @brief Standard error codes. See Core v 4.1, Vol. 2, part D. + * @{ + */ +#define ERR_CMD_SUCCESS (0x00) +#define BLE_STATUS_SUCCESS (0x00) +#define ERR_UNKNOWN_HCI_COMMAND (0x01) +#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) + +#define ERR_AUTH_FAILURE (0x05) +#define ERR_PIN_OR_KEY_MISSING (0x06) +#define ERR_MEM_CAPACITY_EXCEEDED (0x07) +#define ERR_CONNECTION_TIMEOUT (0x08) + +#define ERR_COMMAND_DISALLOWED (0x0C) + +#define ERR_UNSUPPORTED_FEATURE (0x11) +#define ERR_INVALID_HCI_CMD_PARAMS (0x12) +#define ERR_RMT_USR_TERM_CONN (0x13) +#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) +#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) +#define ERR_LOCAL_HOST_TERM_CONN (0x16) + +#define ERR_UNSUPP_RMT_FEATURE (0x1A) + +#define ERR_INVALID_LMP_PARAM (0x1E) +#define ERR_UNSPECIFIED_ERROR (0x1F) + +#define ERR_LL_RESP_TIMEOUT (0x22) +#define ERR_LMP_PDU_NOT_ALLOWED (0x24) + +#define ERR_INSTANT_PASSED (0x28) + +#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) +#define ERR_CONTROLLER_BUSY (0x3A) + +#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) + +#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) + +#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) + + +/** + * @} + */ +/** + * @name Vendor-specific error codes + * @brief Error codes defined by ST related to BlueNRG stack + * @{ + */ +/** + * The command cannot be executed due to the current state of the device. + */ +#define BLE_STATUS_FAILED (0x41) +/** + * Some parameters are invalid. + */ +#define BLE_STATUS_INVALID_PARAMS (0x42) +/** + * It is not allowed to start the procedure (e.g. another the procedure is ongoing + * or cannot be started on the given handle). + */ +#define BLE_STATUS_NOT_ALLOWED (0x46) +/** + * Unexpected error. + */ +#define BLE_STATUS_ERROR (0x47) +#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) + +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +#define BLE_STATUS_INVALID_CID (0x50) + +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) +#define BLE_STATUS_IRK_NOT_FOUND (0x5B) +#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) +#define BLE_STATUS_SEC_DB_FULL (0x5D) +#define BLE_STATUS_DEV_NOT_BONDED (0x5E) +#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) + +#define BLE_STATUS_INVALID_HANDLE (0x60) +#define BLE_STATUS_INVALID_PARAMETER (0x61) +#define BLE_STATUS_OUT_OF_HANDLE (0x62) +#define BLE_STATUS_INVALID_OPERATION (0x63) +#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) +#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) +#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) + +/** + * Returned when no valid slots are available (e.g. when there are no available state machines). + */ +#define BLE_STATUS_NO_VALID_SLOT (0x82) + +/** + * Returned when a scan window shorter than minimum allowed value has been requested (i.e. 2ms) + */ + +#define BLE_STATUS_SCAN_WINDOW_SHORT (0x83) +/** + * Returned when the maximum requested interval to be allocated is shorter then the current + * anchor period and a there is no submultiple for the current anchor period that is between + * the minimum and the maximum requested intervals. + */ + +#define BLE_STATUS_NEW_INTERVAL_FAILED (0x84) +/** + * Returned when the maximum requested interval to be allocated is greater than the current anchor + * period and there is no multiple of the anchor period that is between the minimum and the maximum + * requested intervals. + */ + +#define BLE_STATUS_INTERVAL_TOO_LARGE (0x85) +/** + * Returned when the current anchor period or a new one can be found that is compatible to the + * interval range requested by the new slot but the maximum available length that can be allocated is + * less than the minimum requested slot length. + */ + +#define BLE_STATUS_LENGTH_FAILED (0x86) +/** + * @} + */ + +/** + * @name Library Error Codes + * @brief Error codes defined by ST related to MCU library. + * @{ + */ +#define BLE_STATUS_TIMEOUT (0xFF) +#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) +#define BLE_STATUS_NULL_PARAM (0xF1) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_aci_const.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,813 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci_const.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with ACI definitions for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_CONST_H_ +#define __BLUENRG_ACI_CONST_H_ + +#include "ble_compiler.h" +#include "ble_link_layer.h" +#include "ble_hci_const.h" +#include "bluenrg_gatt_server.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define OCF_HAL_GET_FW_BUILD_NUMBER 0x0000 +typedef __packed struct _hal_get_fw_build_number_rp{ + uint8_t status; + uint16_t build_number; +} PACKED hal_get_fw_build_number_rp; +#define HAL_GET_FW_BUILD_NUMBER_RP_SIZE 3 +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +#define OCF_HAL_READ_CONFIG_DATA 0x000D +typedef __packed struct _hal_read_config_data_cp{ + uint8_t offset; +} PACKED hal_read_config_data_cp; +#define HAL_READ_CONFIG_DATA_RP_SIZE 1 +typedef __packed struct _hal_read_config_data_rp{ + uint8_t status; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE]; +} PACKED hal_read_config_data_rp; + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef __packed struct _hal_set_tx_power_level_cp{ + uint8_t en_high_power; + uint8_t pa_level; +} PACKED hal_set_tx_power_level_cp; +#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 + +#define OCF_HAL_DEVICE_STANDBY 0x0013 + +#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014 +typedef __packed struct _hal_le_tx_test_packet_number_rp{ + uint8_t status; + uint32_t number_of_packets; +} PACKED hal_le_tx_test_packet_number_rp; + +#define OCF_HAL_TONE_START 0x0015 +typedef __packed struct _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_HAL_TONE_STOP 0x0016 +#define OCF_HAL_GET_LINK_STATUS 0x0017 +typedef __packed struct _hal_get_link_status_rp{ + uint8_t status; + uint8_t link_status[8]; + uint16_t conn_handle[8]; +} PACKED hal_get_link_status_rp; + +#define OCF_HAL_GET_ANCHOR_PERIOD 0x0019 +typedef __packed struct _hal_get_anchor_period_rp{ + uint8_t status; + uint32_t anchor_period; + uint32_t max_free_slot; +} PACKED hal_get_anchor_period_rp; + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef __packed struct _get_updater_version_rp{ + uint8_t status; + uint8_t version; +} PACKED get_updater_version_rp; +#define GET_UPDATER_VERSION_RP_SIZE 2 + +#define OCF_GET_UPDATER_BUFSIZE 0x0023 +typedef __packed struct _get_updater_bufsize_rp{ + uint8_t status; + uint8_t buffer_size; +} PACKED get_updater_bufsize_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 + +#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 + +#define OCF_UPDATER_ERASE_SECTOR 0x0026 +typedef __packed struct _updater_erase_sector_cp{ + uint32_t address; +} PACKED updater_erase_sector_cp; +#define UPDATER_ERASE_SECTOR_CP_SIZE 4 + +#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 +#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_prog_data_block_cp{ + uint32_t address; + uint16_t data_len; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; +} PACKED updater_prog_data_block_cp; + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef __packed struct _updater_read_data_block_cp{ + uint32_t address; + uint16_t data_len; +} PACKED updater_read_data_block_cp; +#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[VARIABLE_SIZE]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef __packed struct _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef __packed struct _updater_calc_crc_rp{ + uint8_t status; + uint32_t crc; +} PACKED updater_calc_crc_rp; +#define UPDATER_CALC_CRC_RP_SIZE 5 + +#define OCF_UPDATER_HW_VERSION 0x002A +typedef __packed struct _updater_hw_version_rp{ + uint8_t status; + uint8_t version; +} PACKED updater_hw_version_rp; +#define UPDATER_HW_VERSION_RP_SIZE 2 + +#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 + +#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 + +#define OCF_GAP_SET_DISCOVERABLE 0x0083 + +#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 +typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ + uint8_t own_bdaddr_type; + uint8_t directed_adv_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint16_t adv_interv_min; + uint16_t adv_interv_max; +} PACKED gap_set_direct_conectable_cp_IDB05A1; + +typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB04A1; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef __packed struct _gap_set_io_capability_cp{ + uint8_t io_capability; +} PACKED gap_set_io_capability_cp; +#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 + +#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 +typedef __packed struct _gap_set_auth_requirement_cp{ + uint8_t mitm_mode; + uint8_t oob_enable; + uint8_t oob_data[16]; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t bonding_mode; +} PACKED gap_set_auth_requirement_cp; +#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 + +#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 +typedef __packed struct _gap_set_author_requirement_cp{ + uint16_t conn_handle; + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef __packed struct _gap_passkey_response_cp{ + uint16_t conn_handle; + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef __packed struct _gap_authorization_response_cp{ + uint16_t conn_handle; + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 + +#define OCF_GAP_INIT 0x008A +typedef __packed struct _gap_init_cp_IDB05A1{ + uint8_t role; + uint8_t privacy_enabled; + uint8_t device_name_char_len; +} PACKED gap_init_cp_IDB05A1; +#define GAP_INIT_CP_SIZE_IDB05A1 3 + +typedef __packed struct _gap_init_cp_IDB04A1{ + uint8_t role; +} PACKED gap_init_cp_IDB04A1; +#define GAP_INIT_CP_SIZE_IDB04A1 1 +typedef __packed struct _gap_init_rp{ + uint8_t status; + uint16_t service_handle; + uint16_t dev_name_char_handle; + uint16_t appearance_char_handle; +} PACKED gap_init_rp; +#define GAP_INIT_RP_SIZE 7 + +#define OCF_GAP_SET_NON_CONNECTABLE 0x008B +typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ + uint8_t advertising_event_type; + uint8_t own_address_type; +#endif +} PACKED gap_set_non_connectable_cp_IDB05A1; + +typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp_IDB04A1; + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef __packed struct _gap_set_undirected_connectable_cp{ + uint8_t adv_filter_policy; + uint8_t own_addr_type; +} PACKED gap_set_undirected_connectable_cp; +#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 + +#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D +typedef __packed struct _gap_slave_security_request_cp{ + uint16_t conn_handle; + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef __packed struct _gap_delete_ad_type_cp{ + uint8_t ad_type; +} PACKED gap_delete_ad_type_cp; +#define GAP_DELETE_AD_TYPE_CP_SIZE 1 + +#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 +typedef __packed struct _gap_get_security_level_rp{ + uint8_t status; + uint8_t mitm_protection; + uint8_t bonding; + uint8_t oob_data; + uint8_t passkey_required; +} PACKED gap_get_security_level_rp; +#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 + +#define OCF_GAP_SET_EVT_MASK 0x0091 +typedef __packed struct _gap_set_evt_mask_cp{ + uint16_t evt_mask; +} PACKED gap_set_evt_mask_cp; +#define GAP_SET_EVT_MASK_CP_SIZE 2 + +#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 + +#define OCF_GAP_TERMINATE 0x0093 +typedef __packed struct _gap_terminate_cp{ + uint16_t handle; + uint8_t reason; +} PACKED gap_terminate_cp; +#define GAP_TERMINATE_CP_SIZE 3 + +#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 + +#define OCF_GAP_ALLOW_REBOND_DB 0x0095 + +typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ + uint16_t conn_handle; +} PACKED gap_allow_rebond_cp_IDB05A1; + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef __packed struct _gap_start_limited_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_limited_discovery_proc_cp; +#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 +typedef __packed struct _gap_start_general_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_general_discovery_proc_cp; +#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 +typedef __packed struct _gap_start_name_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_name_discovery_proc_cp; +#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 + +#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 + +#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; + +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t use_reconn_addr; + tBDAddr reconn_addr; +} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; + +#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B +#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 +typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t num_whitelist_entries; + uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; +} PACKED gap_start_selective_conn_establish_proc_cp; + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef __packed struct _gap_create_connection_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_create_connection_cp; +#define GAP_CREATE_CONNECTION_CP_SIZE 24 + +#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D + +#define OCF_GAP_START_CONNECTION_UPDATE 0x009E +typedef __packed struct _gap_start_connection_update_cp{ + uint16_t conn_handle; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_connection_update_cp; +#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 + +#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F +typedef __packed struct _gap_send_pairing_request_cp{ + uint16_t conn_handle; + uint8_t force_rebond; +} PACKED gap_send_pairing_request_cp; +#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 + +#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 +typedef __packed struct _gap_resolve_private_address_cp{ + tBDAddr address; +} PACKED gap_resolve_private_address_cp; +#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 +typedef __packed struct _gap_resolve_private_address_rp{ + uint8_t status; + tBDAddr address; +} PACKED gap_resolve_private_address_rp; + +#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 +#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 +typedef __packed struct _gap_set_broadcast_mode_cp{ + uint16_t adv_interv_min; + uint16_t adv_interv_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; +} PACKED gap_set_broadcast_mode_cp; + +#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 +typedef __packed struct _gap_start_observation_proc_cp{ + uint16_t scan_interval; + uint16_t scan_window; + uint8_t scan_type; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_observation_proc_cp; + +#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 +typedef __packed struct _gap_get_bonded_devices_rp{ + uint8_t status; + uint8_t num_addr; + uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; +} PACKED gap_get_bonded_devices_rp; + +#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 +typedef __packed struct _gap_is_device_bonded_cp{ + uint8_t peer_address_type; + tBDAddr peer_address; +} PACKED gap_is_device_bonded_cp; + + +#define OCF_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef __packed struct _gatt_add_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_serv_rp; +#define GATT_ADD_SERV_RP_SIZE 3 + +#define OCF_GATT_INCLUDE_SERV 0x0103 +typedef __packed struct _gatt_include_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_include_serv_rp; +#define GATT_INCLUDE_SERV_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR 0x0104 +typedef __packed struct _gatt_add_char_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_rp; +#define GATT_ADD_CHAR_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR_DESC 0x0105 +typedef __packed struct _gatt_add_char_desc_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_desc_rp; +#define GATT_ADD_CHAR_DESC_RP_SIZE 3 + +#define OCF_GATT_UPD_CHAR_VAL 0x0106 + +#define OCF_GATT_DEL_CHAR 0x0107 +typedef __packed struct _gatt_del_char_cp{ + uint16_t service_handle; + uint16_t char_handle; +} PACKED gatt_del_char_cp; +#define GATT_DEL_CHAR_CP_SIZE 4 + +#define OCF_GATT_DEL_SERV 0x0108 +typedef __packed struct _gatt_del_serv_cp{ + uint16_t service_handle; +} PACKED gatt_del_serv_cp; +#define GATT_DEL_SERV_CP_SIZE 2 + +#define OCF_GATT_DEL_INC_SERV 0x0109 +typedef __packed struct _gatt_del_inc_serv_cp{ + uint16_t service_handle; + uint16_t inc_serv_handle; +} PACKED gatt_del_inc_serv_cp; +#define GATT_DEL_INC_SERV_CP_SIZE 4 + +#define OCF_GATT_SET_EVT_MASK 0x010A +typedef __packed struct _gatt_set_evt_mask_cp{ + uint32_t evt_mask; +} PACKED gatt_set_evt_mask_cp; +#define GATT_SET_EVT_MASK_CP_SIZE 4 + +#define OCF_GATT_EXCHANGE_CONFIG 0x010B +typedef __packed struct _gatt_exchange_config_cp{ + uint16_t conn_handle; +} PACKED gatt_exchange_config_cp; +#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 + +#define OCF_ATT_FIND_INFO_REQ 0x010C +typedef __packed struct _att_find_info_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED att_find_info_req_cp; +#define ATT_FIND_INFO_REQ_CP_SIZE 6 + +#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D +#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 +typedef __packed struct _att_find_by_type_value_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[2]; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU - 7]; +} PACKED att_find_by_type_value_req_cp; + +#define OCF_ATT_READ_BY_TYPE_REQ 0x010E +#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_type_req_cp; + +#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F +#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_group_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_group_type_req_cp; + +#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 +#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val +typedef __packed struct _att_prepare_write_req_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t value_offset; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU-5]; +} PACKED att_prepare_write_req_cp; + +#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 +typedef __packed struct _att_execute_write_req_cp{ + uint16_t conn_handle; + uint8_t execute; +} PACKED att_execute_write_req_cp; +#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 + +#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 +typedef __packed struct _gatt_disc_all_prim_serivces_cp{ + uint16_t conn_handle; +} PACKED gatt_disc_all_prim_services_cp; +#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 + +#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 +typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ + uint16_t conn_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_disc_prim_service_by_uuid_cp; +#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid + +#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 +typedef __packed struct _gatt_disc_find_included_services_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED gatt_find_included_services_cp; +#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 + +#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 +typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ + uint16_t conn_handle; + uint16_t start_attr_handle; + uint16_t end_attr_handle; +} PACKED gatt_disc_all_charac_of_serv_cp; +#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 + +#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 + +#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ + uint16_t conn_handle; + uint16_t char_val_handle; + uint16_t char_end_handle; +} PACKED gatt_disc_all_charac_descriptors_cp; +#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 + +#define OCF_GATT_READ_CHARAC_VAL 0x0118 +typedef __packed struct _gatt_read_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_val_cp; +#define GATT_READ_CHARAC_VAL_CP_SIZE 4 + +#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 +typedef __packed struct _gatt_read_using_charac_uuid_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_read_using_charac_uuid_cp; +#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID + +#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A +typedef __packed struct _gatt_read_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_val_cp; +#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 + +#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B +#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles +typedef __packed struct _gatt_read_multiple_charac_val_cp{ + uint16_t conn_handle; + uint8_t num_handles; + uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_read_multiple_charac_val_cp; + +#define OCF_GATT_WRITE_CHAR_VALUE 0x011C + +#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D +#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_write_long_charac_val_cp; + +#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E +#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_charac_reliable_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; +} PACKED gatt_write_charac_reliable_cp; + +#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F +#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; +} PACKED gatt_write_long_charac_desc_cp; + +#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 +typedef __packed struct _gatt_read_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_desc_cp; +#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 + +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 +typedef __packed struct _gatt_read_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_desc_cp; +#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 +#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 3]; +} PACKED gatt_write_without_resp_cp; + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 +#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_signed_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 13]; +} PACKED gatt_signed_write_without_resp_cp; + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 +typedef __packed struct _gatt_confirm_indication_cp{ + uint16_t conn_handle; +} PACKED gatt_confirm_indication_cp; +#define GATT_CONFIRM_INDICATION_CP_SIZE 2 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef __packed struct _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 +typedef __packed struct _gatt_set_security_permission_cp{ + uint16_t service_handle; + uint16_t attr_handle; + uint8_t security_permission; +} PACKED gatt_set_security_permission_cp; +#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_GATT_READ_HANDLE_VALUE 0x012A +typedef __packed struct _gatt_read_handle_val_cp{ + uint16_t attr_handle; +} PACKED gatt_read_handle_val_cp; +#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 +typedef __packed struct _gatt_read_handle_val_rp{ + uint8_t status; + uint16_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; +} PACKED gatt_read_handle_val_rp; + +#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B +typedef __packed struct _gatt_read_handle_val_offset_cp{ + uint16_t attr_handle; + uint8_t offset; +} PACKED gatt_read_handle_val_offset_cp; +#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 +typedef __packed struct _gatt_read_handle_val_offset_rp{ + uint8_t status; + uint8_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; +} PACKED gatt_read_handle_val_offset_rp; + +#define OCF_GATT_UPD_CHAR_VAL_EXT 0x012C +#define GATT_UPD_CHAR_VAL_EXT_CP_SIZE 10 // without value +typedef __packed struct _gatt_upd_char_val_ext_cp{ + uint16_t service_handle; + uint16_t char_handle; + uint8_t update_type; + uint16_t char_length; + uint16_t value_offset; + uint8_t value_length; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_UPD_CHAR_VAL_EXT_CP_SIZE]; +} PACKED gatt_upd_char_val_ext_cp; + +#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 +typedef __packed struct _l2cap_conn_param_update_req_cp{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_update_req_cp; +#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 + +#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint16_t min_ce_length; + uint16_t max_ce_length; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; + +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; + +/** + * @defgroup BlueNRG_Events BlueNRG events (vendor specific) + * @{ + */ + +/** + * Vendor specific event for BlueNRG. + */ +typedef __packed struct _evt_blue_aci{ + uint16_t ecode; /**< One of the BlueNRG event codes. */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_blue_aci; + + +/** + * @} + */ + +#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,230 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gap.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GAP layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +#ifndef __BNRG_GAP_H__ +#define __BNRG_GAP_H__ + +#include <ble_link_layer.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + * @name GAP UUIDs + * @{ + */ +#define GAP_SERVICE_UUID (0x1800) +#define DEVICE_NAME_UUID (0x2A00) +#define APPEARANCE_UUID (0x2A01) +#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) +#define RECONNECTION_ADDR_UUID (0x2A03) +#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) +/** + * @} + */ + +/** + * @name Characteristic value lengths + * @{ + */ +#define DEVICE_NAME_CHARACTERISTIC_LEN (8) +#define APPEARANCE_CHARACTERISTIC_LEN (2) +#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) +#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) +#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) +/** + * @} + */ + +/*------------- AD types for adv data and scan response data ----------------*/ + +/** + * @defgroup AD_Types AD Types + * @brief AD Types + * @{ + */ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +/** + * @anchor Flags_AD_Type_bits + * @name Flags AD Type bits + * @brief Bits in Flags AD Type + * @{ + */ +#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) +#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) +#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) +#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) +#define FLAG_BIT_LE_BR_EDR_HOST (0x10) +/** + * @} + */ + +/** + * @name Service UUID AD types + * @{ + */ +#define AD_TYPE_16_BIT_SERV_UUID (0x02) +#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) +#define AD_TYPE_32_BIT_SERV_UUID (0x04) +#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) +#define AD_TYPE_128_BIT_SERV_UUID (0x06) +#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) +/** + * @} + */ + +/* LOCAL NAME AD types */ +/** + * @name Local name AD types + * @{ + */ +#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) +#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) +/** + * @} + */ + +/* TX power level AD type*/ +#define AD_TYPE_TX_POWER_LEVEL (0x0A) + +/* Class of device */ +#define AD_TYPE_CLASS_OF_DEVICE (0x0D) + +/* security manager TK value AD type */ +#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) + +/* security manager OOB flags */ +#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) + +/* slave connection interval AD type */ +#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) + +/* service solicitation UUID list Ad types*/ +/** + * @name Service solicitation UUID list AD types + * @{ + */ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) +#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) +/** + * @} + */ + +/* service data AD type */ +#define AD_TYPE_SERVICE_DATA (0x16) + +/* manufaturer specific data AD type */ +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/* appearance AD type */ +#define AD_TYPE_APPEARANCE (0x19) + +/* advertising interval AD type */ +#define AD_TYPE_ADVERTISING_INTERVAL (0x1A) + +/** + * @} + */ + +#define MAX_ADV_DATA_LEN (31) + +#define DEVICE_NAME_LEN (7) +#define BD_ADDR_SIZE (6) + +/** + * @name Privacy flag values + * @{ + */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) +/** + * @} + */ + +/** + * @name Intervals + * Intervals in terms of 625 micro sec + * @{ + */ +#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ +#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ +#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ +#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ +#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ +#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ +#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ +#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ +/** + * @} + */ + +/** + * @name Timeout values + * @{ + */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ +/** + * @} + */ + +/** + * @anchor gap_roles + * @name GAP Roles + * @{ +*/ +#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) +#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) + +#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) +#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) +/** + * @} + */ + +/** + * @anchor gap_procedure_codes + * @name GAP procedure codes + * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event + * and aci_gap_terminate_gap_procedure() command. + * @{ + */ +#define GAP_LIMITED_DISCOVERY_PROC (0x01) +#define GAP_GENERAL_DISCOVERY_PROC (0x02) +#define GAP_NAME_DISCOVERY_PROC (0x04) +#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) +#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) +#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) +#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) +#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gap_aci.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,1231 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gap_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GAP_ACI_H__ +#define __BLUENRG_GAP_ACI_H__ + +/** + *@addtogroup GAP GAP + *@brief GAP layer. + *@{ + */ + +/** + *@defgroup GAP_Functions GAP functions + *@brief API for GAP layer. + *@{ + */ + +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". + * @param privacy_enabled Enable (1) or disable (0) privacy. + * @param device_name_char_len Length of the device name characteristic + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, + uint8_t device_name_char_len, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Privacy Flag (peripheral role only) + * @li Reconnection Address (peripheral role only) + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB04A1(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); + +/** + * @brief Set the Device in non-discoverable mode. + * @note This command will disable the LL advertising. + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_discoverable(void); + +/** + * @brief Put the device in limited discoverable mode + * (as defined in GAP specification volume 3, section 9.2.3). + * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. + * The advertising can be disabled at any time by issuing + * aci_gap_set_non_discoverable() command. + * The AdvIntervMin and AdvIntervMax parameters are optional. If both + * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). + * Host can set the Local Name, a Service UUID list and the Slave Connection + * Minimum and Maximum. If provided, these data will be inserted into the + * advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() + * separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following + * standard AD types: + * @li AD Flags + * @li TX Power Level + * + * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates + * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. + * + * Example: + * @code + * + * #define ADV_INTERVAL_MIN_MS 100 + * #define ADV_INTERVAL_MAX_MS 200 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, + * (ADV_INTERVAL_MAX_MS*1000)/0.625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * sizeof(serviceUUIDList), serviceUUIDList, + * 0, 0); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 250 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 500 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg NO_WHITE_LIST_USE + * @arg WHITE_LIST_FOR_ONLY_SCAN + * @arg WHITE_LIST_FOR_ONLY_CONN + * @arg WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +/** + * @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4). + * @note The device will be discoverable until the Host issue Aci_Gap_Set_Non_Discoverable command. + * The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses + * the default values for advertising intervals (1.28 s and 2.56 s respectively for IDB04A1). + * When using connectable undirected advertising events:\n + * @li Adv_Interval_Min = 30 ms + * @li Adv_Interval_Max = 60 ms + * \nWhen using non-connectable advertising events or scannable undirected advertising events:\n + * @li Adv_Interval_Min = 100 ms + * @li Adv_Interval_Max = 150 ms + * Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided, + * these data will be inserted into the advertising packet payload as AD data. These parameters are optional + * in this command. These values can be also set using aci_gap_update_adv_data() separately. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following standard AD types: + * @li AD Flags + * @li TX Power Level + * + * Usage example: + * + * @code + * + * #define ADV_INTERVAL_MIN_MS 800 + * #define ADV_INTERVAL_MAX_MS 900 + * #define CONN_INTERVAL_MIN_MS 100 + * #define CONN_INTERVAL_MAX_MS 300 + * + * tBleStatus ret; + * + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * + * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625, + * (ADV_INTERVAL_MAX_MS*1000)/625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * 0, NULL, + * (CONN_INTERVAL_MIN_MS*1000)/1250, + * (CONN_INTERVAL_MAX_MS*1000)/1250); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 1.28 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 2.56 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ONLY_SCAN + * @arg @ref WHITE_LIST_FOR_ONLY_CONN + * @arg @ref WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); + +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @param adv_interv_min Minimum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @param adv_interv_max Maximum advertising interval for low duty cycle directed advertising. + * Range: 0x0020 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max); +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param own_addr_type Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr_type Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param initiator_addr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); + +/** + * @brief Set the IO capabilities of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param io_capability One of the allowed codes for IO Capability: + * @arg @ref IO_CAP_DISPLAY_ONLY + * @arg @ref IO_CAP_DISPLAY_YES_NO + * @arg @ref IO_CAP_KEYBOARD_ONLY + * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT + * @arg @ref IO_CAP_KEYBOARD_DISPLAY + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_io_capability(uint8_t io_capability); + +/** + * @brief Set the authentication requirements for the device. + * @note If the oob_enable is set to 0, oob_data will be ignored. + * This command has to be given only when the device is not in a connected state. + * @param mitm_mode MITM mode: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @param oob_enable If OOB data are present or not: + * @arg @ref OOB_AUTH_DATA_ABSENT + * @arg @ref OOB_AUTH_DATA_PRESENT + * @param oob_data Out-Of-Band data + * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process + * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process + * @param use_fixed_pin If application wants to use a fixed pin or not: + * @arg @ref USE_FIXED_PIN_FOR_PAIRING + * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING + * If a fixed pin is not used, it has to be provided by the application with + * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will + * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is + * accepted. + * @param bonding_mode One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode); + /** + * @brief Set the authorization requirements of the device. + * @note This command has to be given when connected to a device if authorization is required to access services + * which require authorization. + * @param conn_handle Handle of the connection. + * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required + * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables + * the authorization requirement in the device and when a remote device + * tries to read/write a characeristic with authorization requirements, the stack will + * send back an error response with "Insufficient authorization" error code. + * After pairing is complete a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event + * will be sent to the Host. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); + +/** + * @brief Provide the pass key that will be used during pairing. + * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param conn_handle Connection handle + * @param passkey Pass key that will be used during the pairing process. Must be a number between + * 0 and 999999. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); + +/** + * @brief Authorize a device to access attributes. + * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. + * + * @param conn_handle Connection handle + * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) + * @arg @ref CONNECTION_REJECTED : Reject (reject connection) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); + +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @param own_address_type If Privacy is disabled, then the peripheral address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the peripheral address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); + +/** + * @brief Put the device into undirected connectable mode. + * @note If privacy is enabled in the device, a resolvable private address is generated and used + * as the advertiser's address. If not, the address of the type specified in own_addr_type + * is used for advertising. + * @param own_addr_type Type of our address used during advertising: + * if BLUENRG (IDB04A1) + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * else if BLUENRG_MS (IDB05A1) + * If Privacy is disabled: + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled: + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_filter_policy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ALL + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); + +/** + * @brief Send a slave security request to the master. + * @note This command has to be issued to notify the master of the security requirements of the slave. + * The master may encrypt the link, initiate the pairing procedure, or reject the request. + * @param conn_handle Connection handle + * @param bonding One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @param mitm_protection If MITM protection is required or not: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); + +/** + * @brief Update advertising data. + * @note This command can be used to update the advertising data for a particular AD type. + * If the AD type specified does not exist, then it is added to the advertising data. + * If the overall advertising data length is more than 31 octets after the update, then + * the command is rejected and the old data is retained. + * @param AdvLen Length of AdvData array + * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification + * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. + * Example + * @code + * tBleStatus ret; + * const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + * const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12}; + * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; + * + * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * 8, local_name, 3, serviceUUIDList, 0, 0); + * ret = aci_gap_update_adv_data(5, manuf_data); + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); + +/** + * @brief Delete an AD Type + * @note This command can be used to delete the specified AD type from the advertisement data if + * present. + * @param ad_type One of the allowed AD types (see @ref AD_Types) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); + +/** + * @brief Get the current security settings + * @note This command can be used to get the current security settings of the device. + * @param mitm_protection @arg 0: Not required + * @arg 1: Required + * @param bonding @arg 0: No bonding mode + * @arg 1: Bonding mode + * @param oob_data @arg 0: Data absent + * @arg 1: Data present + * @param passkey_required @arg 0: Not required + * @arg 1: Fixed pin is present which is being used + * @arg 2: Passkey required for pairing. An event will be generated + * when required. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required); + +/** + * @brief Add addresses of bonded devices into the controller's whitelist. + * @note The command will return an error if there are no devices in the database or if it was unable + * to add the device into the whitelist. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_configure_whitelist(void); + +/** + * @brief Terminate a connection. + * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. + * @param conn_handle Connection handle + * @param reason Reason for requesting disconnection. The error code can be any of ones as specified + * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); + +/** + * @brief Clear the security database. + * @note All the devices in the security database will be removed. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_clear_security_database(void); + +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @param conn_handle + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB04A1(void); + +/** + * @brief Start the limited discovery procedure. + * @note The controller is commanded to start active scanning. When this procedure is started, + * only the devices in limited discoverable mode are returned to the upper layers. + * The procedure is terminated when either the upper layers issue a command to terminate the + * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code + * set to @ref GAP_LIMITED_DISCOVERY_PROC or a timeout happens. When the procedure is terminated + * due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC. + * The device found when the procedure is ongoing is returned to the upper layers through the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the general discovery procedure. + * @note The controller is commanded to start active scanning. The procedure is terminated when + * either the upper layers issue a command to terminate the procedure by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC + * or a timeout happens. When the procedure is terminated due to any of the above reasons, + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to + * @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to + * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the name discovery procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. Once a connection is established, GATT procedure is started to read the + * device name characteristic. When the read is completed (successfully or unsuccessfully), + * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also + * contains the name of the device if the device name was read successfully. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Start the auto connection establishment procedure. + * @note The devices specified are added to the white list of the controller and a LE_Create_Connection + * call will be made to the controller by GAP with the initiator filter policy set to + * use whitelist to determine which advertiser to connect to. When a command is issued to + * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the + * controller by GAP. + * The procedure is terminated when either a connection is successfully established with one of + * the specified devices in the white list or the procedure is explicitly terminated by issuing + * the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start a general connection establishment procedure. + * @note The host enables scanning in the controller with the scanner filter policy set + * to accept all advertising packets and from the scanning results all the devices + * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). + * The upper layer then has to select one of the devices to which it wants to connect + * by issuing the command aci_gap_create_connection(). The procedure is terminated + * when a connection is established or the upper layer terminates the procedure by + * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates); +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); + +/** + * @brief Start a selective connection establishment procedure. + * @note The GAP adds the specified device addresses into white list and enables scanning in + * the controller with the scanner filter policy set to accept packets only from + * devices in whitelist. All the devices found are sent to the upper layer by the + * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) or @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the + * devices to which it wants to connect by issuing the command aci_gap_create_connection(). + * On completion of the procedure a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated + * with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * The procedure is terminated when a connection is established or the upper layer terminates + * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure + * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start the direct connection establishment procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. The procedure can be terminated explicitly by the upper layer by issuing + * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the + * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller + * by GAP. + * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can + * be explicitly terminated by the upper layer by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. + * @param scanInterval Time interval from when the Controller started its last LE scan until it begins + * the subsequent LE scan. The scan interval should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is + * returned with the procedure code set to the corresponding procedure. + * @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes"). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); + +/** + * @brief Start the connection parameter update procedure. + * @note Allowed by the Central to update the connection parameter of the specified connection. + * A Link Layer Connection Update procedure is started on the controller. + * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to + * the upper layer. + * @param conn_handle Handle of the connection for which the update procedure has to be started. + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Send a pairing request. + * @note Send the SM pairing request to start a pairing process from a Central. The authentication + * requirements and IO capabilities should be set before issuing this command using + * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). + * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. + * @param conn_handle Handle of the connection for which the pairing request has to be sent. + * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded + * @arg 0x01: Pairing request will be sent even if the device was previously bonded + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param[in] address Address to be resolved. + * @param[out] actual_address The public or static random address of the peer device, distributed during pairing phase. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); + +/** + * @brief This command gets the list of bonded devices. + * @note It returns the number of addresses and the corresponding address types and values. + * Example: + * @code + * tBleStatus ret; + * uint8_t num_devices = 0; + * uint8_t device_list[12*7]; + * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); + * for(int i = 0; i < num_devices; i+=7){ + * uint8_t addr_type = device_list[i]; + * uint8_t addr = device_list[i+1]; + * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); + * } + * @endcode + * + * @param[out] num_devices The number of bonded devices. + * @param[out] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address + * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. + * @param device_list_size Maximum size of the device_list buffer used to return the device list. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); + +/** + * @brief Puts the device into broadcast mode + * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address + * as specified in the own_addr_type parameter of the command. + * @param adv_interv_min Minimum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_interv_max Maximum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param own_addr_type If Privacy is disabled, the broadcaster address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the broadcaster address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_data_length Length of the advertising data in the advertising packet + * @param adv_data Advertising data used by the device while advertising + * @param num_whitelist_entries Number of devices to be added to whitelist + * @param addr_array It will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Starts an observation procedure, when the device is in Observer role. + * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer + * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth + * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. + * @param scan_interval Time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. + * The scan interval should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. + * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param own_address_type If Privacy is disabled, then the scanner address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the scanner address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates); + +/** + * @brief The command finds whether a device is bonded. + * @note If the device is using a resolvable private address and it has been bonded, then the command will return + * BLE_STATUS_SUCCESS. + * @param peer_address_type The address type of the peer device + * @arg @ref PUBLIC_ADDR. + * @arg @ref RANDOM_ADDR. + * @param peer_address Address used by the peer device while advertising. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address); + + +/** + * @} + */ + +/** + * @defgroup GAP_Events GAP events + * @{ + */ + +/** + * This event is generated by the controller when the limited discoverable + * mode ends due to timeout (180 seconds). No parameters in the event. + */ +#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) + + +/** + * This event is generated when the pairing process has completed successfully + * or a pairing procedure timeout has occurred or the pairing has failed. + * This is to notify the application that we have paired with a remote device + * so that it can take further actions or to notify that a timeout has occurred + * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. + */ +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +typedef __packed struct _evt_gap_pairing_cmplt{ + uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ + /** + * 0x00: Pairing Success. Pairing with a remote device was successful\n + * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n + * 0x02: Pairing Failed. The pairing failed with the remote device. + */ + uint8_t status; +} PACKED evt_gap_pairing_cmplt; + + +/** + * This event is generated by the Security manager to the application when a pass key is required for pairing. + * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. + * See @ref _evt_gap_pass_key_req. + */ +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +typedef __packed struct _evt_gap_pass_key_req{ + uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ +} PACKED evt_gap_pass_key_req; + + +/** + * This event is generated by the Security manager to the application when the application + * has set that authorization is required for reading/writing of attributes. This event will + * be generated as soon as the pairing is complete. When this event is received, + * aci_gap_authorization_response() command should be used by the application. + * See @ref _evt_gap_author_req. + */ +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +typedef __packed struct _evt_gap_author_req{ + uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ +} PACKED evt_gap_author_req; + +/** + * This event is generated when the slave security request is successfully sent to the master. + * No parameters for this event. + */ +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) + +/** + * This event is generated on the slave when a aci_gap_slave_security_request() is called to reestablish the bond + * with a master but the master has lost the bond. When this event is received, the upper layer has to issue the + * command aci_gap_allow_rebond() in order to allow the slave to continue the pairing process with the master. + * On the master this event is raised when aci_gap_send_pairing_request() is called to reestablish a bond with a slave + * but the slave has lost the bond. In order to create a new bond the master has to launch aci_gap_send_pairing_request() + * with force_rebond set to 1. + * No parameters for this event + */ +#define EVT_BLUE_GAP_BOND_LOST (0X0405) + +/** + * The event is given by the GAP layer to the upper layers when a device is discovered during scanning + * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. + */ +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef __packed struct _evt_gap_device_found{ + uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ + uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ + tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ + uint8_t data_length; /**< Length of advertising or scan response data. */ + uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ +} PACKED evt_gap_device_found; + +/** + * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated + * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. + */ +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef __packed struct _evt_gap_procedure_complete{ + uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ + /** + * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed + * due to authentication requirements). + */ + uint8_t status; + /** + * Procedure specific data.\n + * @li For Name Discovery Procedure:\n + * the name of the peer device if the procedure completed successfully. + * @li For General Connection Establishment Procedure:\n + * The reconnection address written to the peripheral device if the peripheral is privacy enabled + */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_gap_procedure_complete; + +/** + * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral + * is not able to resolve the private address of the peer device after connecting to it. + */ +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) +typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ + uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ +} PACKED evt_gap_addr_not_resolved_IDB05A1; +/** + * This event is raised when the reconnection address is generated during the general connection + * establishment procedure. The same address is set into the peer device also as a part of the general + * connection establishment procedure. In order to make use of the reconnection address the next time + * while connecting to the bonded peripheral, the application needs to use this reconnection address + * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() + * and aci_gap_start_auto_conn_establish_proc(). + */ +#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) +typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ + uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ +} PACKED evt_gap_reconnection_addr_IDB04A1; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_aci.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,1128 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_GATT_ACI_H__ +#define __BLUENRG_GATT_ACI_H__ + +#include "bluenrg_gatt_server.h" + +/** + *@addtogroup GATT GATT + *@brief GATT layer. + *@{ + */ + +/** + *@defgroup GATT_Functions GATT functions + *@brief API for GATT layer. + *@{ + */ + +/** + * @brief Initialize the GATT layer for server and client roles. + * @note It adds also the GATT service with Service Changed Characteristic. + * Until this command is issued the GATT channel will not process any commands + * even if the connection is opened. This command has to be given + * before using any of the GAP features. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_init(void); + +/** + * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs + * to reserve the handle ranges for this service using max_attr_records parameter. This + * parameter specifies the maximum number of attribute records that can be added to this + * service (including the service attribute, include attribute, characteristic attribute, + * characteristic value attribute and characteristic descriptor attribute). Handle of the + * created service is returned. + * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors + * are allocated from the attribute pool. + * @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field + * @param service_type Primary or secondary service. See @ref Service_type "Service Type". + * @param max_attr_records Maximum number of attribute records that can be added to this service + * (including the service declaration itself) + * @param[out] serviceHandle Handle of the Service. When this service is added to the service, + * a handle is allocated by the server to this service. Server also + * allocates a range of handles for this service from serviceHandle to + * <serviceHandle + max_attr_records>. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, + const uint8_t* service_uuid, + uint8_t service_type, + uint8_t max_attr_records, + uint16_t *serviceHandle); + +/** + * @brief Include a service given by included_start_handle and included_end_handle to another service + * given by service_handle. Attribute server creates an INCLUDE definition attribute and return + * the handle of this attribute in included_handle. + * @param service_handle Handle of the service to which another service has to be included + * @param included_start_handle Start Handle of the service which has to be included in service + * @param included_end_handle End Handle of the service which has to be included in service + * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". + * @param[in] included_uuid 16-bit or 128-bit UUID. + * @param[out] included_handle Handle of the include declaration. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle); + +/** + * @brief Add a characteristic to a service. + * @param serviceHandle Handle of the service to which the characteristic has to be added. + * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param charUuid 16-bit or 128-bit UUID. + * @param charValueLen Maximum length of the characteristic value. + * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, + * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". + * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @arg GATT_DONT_NOTIFY_EVENTS + * @arg GATT_NOTIFY_ATTRIBUTE_WRITE + * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP + * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. + * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client + * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE + * properties. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle); + +/** + * Add a characteristic descriptor to a service. + * @param serviceHandle Handle of the service to which the characteristic belongs + * @param charHandle Handle of the characteristic to which description has to be added. + * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG + * (Well_known_UUIDs) or a user-defined one. + * @param descValueMaxLen The maximum length of the descriptor value + * @param descValueLen Current Length of the characteristic descriptor value + * @param[in] descValue Value of the characteristic description + * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". + * @arg ATTR_NO_ACCESS + * @arg ATTR_ACCESS_READ_ONLY + * @arg ATTR_ACCESS_WRITE_REQ_ONLY + * @arg ATTR_ACCESS_READ_WRITE + * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE + * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param[out] descHandle Handle of the Characteristic Descriptor. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle); + +/** + * @brief Update a characteristic value in a service. + * @note If notifications (or indications) are enabled on that characteristic, a notification (or indication) + * will be sent to the client after sending this command to the BlueNRG. The command is queued into the + * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, + * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or + * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate + * than what is allowed by the link. Throughput on BLE link depends on connection interval and + * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() + * for more info on how to suggest new connection parameters from a slave). If the application does not + * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function + * returns @ref BLE_STATUS_SUCCESS or any other error code.\n + * Example:\n + * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some + * notifications will be lost. + * @code + * tBleStatus Free_Fall_Notify(void) + * { + * uint8_t val; + * tBleStatus ret; + * + * val = 0x01; + * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); + * + * if (ret != BLE_STATUS_SUCCESS){ + * PRINTF("Error while updating FFall characteristic.\n") ; + * return BLE_STATUS_ERROR ; + * } + * return BLE_STATUS_SUCCESS; + * } + * @endcode + * Here if BlueNRG buffer become full, the application try again to send the notification. + * @code + * struct timer t; + * Timer_Set(&t, CLOCK_SECOND*10); + * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ + * // Radio is busy (buffer full). + * if(Timer_Expired(&t)) + * break; + * } + * @endcode + * + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic + * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, + * and the attribute value is of variable length, then the length of the attribute will + * be set to the charValueLen. If the charValOffset is set to a value greater than 0, + * then the length of the attribute will be set to the maximum length as specified for + * the attribute while adding the characteristic. + * @param charValueLen Length of the characteristic value in octets + * @param[in] charValue Characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue); +/** + * @brief Delete the specified characteristic from the service. + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); + +/** + * @brief Delete the specified service from the GATT server database. + * @param servHandle Handle of the service to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_service(uint16_t servHandle); + +/** + * @brief Delete the Include definition from the service. + * @param servHandle Handle of the service to which Include definition belongs + * @param includeServHandle Handle of the Included definition to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); + +/** + * @brief Perform an ATT MTU exchange procedure. + * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP + * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated + * to indicate the end of the procedure. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); + +/** + * @brief Send a @a Find @a Information @a Request. + * @note This command is used to obtain the mapping of attribute handles with their associated + * types. The responses of the procedure are given through the + * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by + * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range of attributes to be discovered on the server + * @param end_handle Ending handle of the range of attributes to be discovered on the server + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send a @a Find @a By @a Type @a Value @a Request + * @note The Find By Type Value Request is used to obtain the handles of attributes that + * have a given 16-bit UUID attribute type and a given attribute value. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid 2 octet UUID to find (little-endian) + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). + * @param attr_val Attribute value to find + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send a @a Read @a By @a Type @a Request + * @note The Read By Type Request is used to obtain the values of attributes where the attribute type + * is known but the handle is not known. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Read @a By @a Group @a Type @a Request + * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute + * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping + * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Prepare @a Write @a Request + * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param attr_handle The handle of the attribute to be written + * @param value_offset The offset of the first octet to be written + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). + * @param attr_val The value of the attribute to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send an @a Execute @a Write @a Request + * @note The Execute Write Request is used to request the server to write or cancel the write of all the + * prepared values currently held in the prepare queue from this client. + * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param execute @arg 0x00 Cancel all prepared writes + * @arg 0x01 Immediately write all pending prepared values. + * @return Value indicating success or error code. + */ +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); + +/** + * @brief This command will start the GATT client procedure to discover all primary services on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +/** + * @brief Start the procedure to discover the primary services of the specified UUID on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to find all included services. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle Start handle of the service + * @param end_handle End handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Start the procedure to discover all the characteristics of a given service. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_attr_handle Start attribute handle of the service + * @param end_attr_handle End attribute handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +/** + * @brief Start the procedure to discover all the characteristics specified by a UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Start attribute handle of the service + * @param end_handle End attribute handle of the service + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); + +/** + * @brief Start the procedure to discover all characteristic descriptors on the server. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. + * @param conn_handle Connection handle for which the command is given. + * @param char_val_handle Starting handle of the characteristic + * @param char_end_handle End handle of the characteristic + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +/** + * @brief Start the procedure to read the attribute value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to read all the characteristics specified by the UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range to be searched + * @param end_handle End handle of the range to be searched + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start a procedure to read multiple characteristic values from a server. + * @note This sub-procedure is used to read multiple Characteristic Values from a server when the + * client knows the Characteristic Value Handles. + * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param num_handles The number of handles for which the value has to be read + * @param set_of_handles The handles for which the attribute value has to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles); + +/** + * @brief Start the procedure to write a characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to write a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start the procedure to write a characteristic reliably. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to write a long characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP + * event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic descriptor + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start the procedure to write a characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to read the descriptor specified. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the descriptor to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to write a characteristic value without waiting for any response from the server. + * @note No events are generated after this command is executed. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 3) + * @param[in] attr_val Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start a signed write without response from the server. + * @note The procedure i used to write a characteristic value with an authentication signature without waiting + * for any response from the server. It cannot be used when the link is encrypted. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 13). + * @param attr_val Value to be written + * @return Value indicating success or error code + */ +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Confirm an indication + * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); + +/** + * @brief Allow or reject a write request from a client. + * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, + * then the status has to be set to 1 and the error code has to be set to the error code that has to be + * passed to the client. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n + * 0x01: The value cannot be written to the attribute specified by the attr_handle. + * @param err_code The error code that has to be passed to the client in case the write has to be rejected. + * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val); + +/** + * @brief Allow the GATT server to send a response to a read request from a client. + * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ + * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response + * can be sent to the client. So if the application wishes to update any of the attributes before + * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value + * and then give this command. The application should perform the required operations within 30 seconds, + * otherwise the GATT procedure will go to timeout. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_allow_read(uint16_t conn_handle); + +/** + * @brief Set the security permission for the attribute handle specified. + * @note Currently the setting of security permission is allowed only for client configuration descriptor. + * @param service_handle Handle of the service which contains the attribute whose security + * permission has to be modified. + * @param attr_handle Handle of the attribute whose security permission has to be modified. + * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission); + +/** + * @brief This command sets the value of the descriptor specified by charDescHandle. + * @param servHandle Handle of the service which contains the descriptor. + * @param charHandle Handle of the characteristic which contains the descriptor. + * @param charDescHandle Handle of the descriptor whose value has to be set. + * @param charDescValOffset Offset from which the descriptor value has to be updated. + * @param charDescValueLen Length of the descriptor value + * @param[in] charDescValue descriptor value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue); + +/** + * @brief Reads the value of the attribute handle specified from the local GATT database. + * @param attr_handle Handle of the attribute to read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + + /** + * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. + * @param attr_handle Handle of the attribute to read + * @param offset Offset from which the value needs to be read + * @param data_len Length of the data buffer. + * @param[out] data_len_out_p Length of the read attribute. + * @param[out] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); +/** + * @brief Update the value of a characteristic and sends notifications or indications. + * @note This command is a more flexible version of ACI_GATT_UPDATE_CHAR_VALUE to support update of long attribute + * up to 512 bytes and indicate selectively the generation of indications and notifications. + * @param service_handle Handle of the service to which the characteristic belongs. + * @param char_handle Handle of the characteristic + * @param update_type Bitmask that controls generation of notifications and indications. It can be a combination + * @arg @ref NOTIFICATION (0x01): send notification, if enabled. + * @arg @ref INDICATION (0x02): send indication, if enabled. + * If set to 0 no notifications or indications are sent. + * @param char_length Total length of the characteristic value. In case of a variable size characteristic, + * this field specifies the new length of the characteristic value after the update; + * in case of fixed length characteristic this field is ignored. + * @param value_offset The offset from which the attribute value has to be updated + * @param value_length Length of the value to be updated + * @param[out] value Updated characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value); + +/** + * @} + */ + + +/** + * @defgroup GATT_Events GATT events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** + * This event (if enabled, see @ref Gatt_Event_Mask "Gatt Event Mask") is raised to the application + * by the GATT server when a client modifies any attribute on the server, as consequence of one of + * the following GATT procedures: + * @li write without response + * @li signed write without response + * @li write characteristic value + * @li write long characteristic value + * @li reliable write. + * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. + */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint16_t offset; /**< Offset from which the write has been performed by the peer device */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB05A1; + +typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB04A1; + +/** + * This event is generated by the client/server to the application on a GATT timeout (30 seconds). + * See @ref _evt_gatt_procedure_timeout. + */ +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +typedef __packed struct _evt_gatt_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ +} PACKED evt_gatt_procedure_timeout; + +/** + * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). + * See @ref _evt_att_exchange_mtu_resp. + */ +#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) +typedef __packed struct _evt_att_exchange_mtu_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data (always 1). */ + uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ +} PACKED evt_att_exchange_mtu_resp; + +/** + * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and + * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. + */ +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef __packed struct _evt_att_find_information_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ + /** + * A sequence of handle-uuid pairs.\n + * @li if format=1, each pair is:\n + * [2 octets for handle, 2 octets for UUIDs] \n + * @li if format=2, each pair is:\n + * [2 octets for handle, 16 octets for UUIDs] + */ + uint8_t handle_uuid_pair[VARIABLE_SIZE]; +} PACKED evt_att_find_information_resp; + +/** + * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See + * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. + */ +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +typedef __packed struct _evt_att_find_by_type_val_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + /** + * Handles Information List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] + */ + uint8_t handles_info_list[VARIABLE_SIZE]; +} PACKED evt_att_find_by_type_val_resp; + +/** + * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and + * aci_gatt_disc_all_charac_of_serv(). + * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. + */ +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef __packed struct _evt_att_read_by_type_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ + /** + * Attribute Data List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] + */ + uint8_t handle_value_pair[VARIABLE_SIZE]; +} PACKED evt_att_read_by_type_resp; + +/** + * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). + * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. + */ +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +typedef __packed struct _evt_att_read_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ +} PACKED evt_att_read_resp; + +/** + * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). + * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. + */ +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +typedef __packed struct _evt_att_read_blob_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ +} PACKED evt_att_read_blob_resp; + +/** + * This event is generated in response to a @a Read @a Multiple @a Request. + * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. + */ +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +typedef __packed struct _evt_att_read_mult_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ +} PACKED evt_att_read_mult_resp; + +/** + * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). + * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. + */ +#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) +typedef __packed struct _evt_att_read_by_group_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_data_length; /**< The size of each Attribute Data. */ + /** + * A list of Attribute Data where the attribute data is composed by: + * @li 2 octets for Attribute Handle + * @li 2 octets for End Group Handle + * @li (attribute_data_length - 4) octets for Attribute Value + */ + uint8_t attribute_data_list[VARIABLE_SIZE]; +} PACKED evt_att_read_by_group_resp; + +/** + * This event is generated in response to a @a Prepare @a Write @a Request. + * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. + */ +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +typedef __packed struct _evt_att_prepare_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attribute_handle; /**< The handle of the attribute to be written. */ + uint16_t offset; /**< The offset of the first octet to be written. */ + uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ +} PACKED evt_att_prepare_write_resp; + +/** + * This event is generated in response to an @a Execute @a Write @a Request. + * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. + */ +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +typedef __packed struct _evt_att_exec_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Always 0. */ +} PACKED evt_att_exec_write_resp; + +/** + * This event is generated when an indication is received from the server. + * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. + */ +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +typedef __packed struct _evt_gatt_indication{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_indication; + +/** + * This event is generated when a notification is received from the server. + * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. + */ +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef __packed struct _evt_gatt_notification{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_attr_notification; + +/** + * This event is generated when a GATT client procedure completes either with error or successfully. + * See @ref _evt_gatt_procedure_complete. + */ +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef __packed struct _evt_gatt_procedure_complete{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ + uint8_t data_length; /**< Length of error_code field (always 1). */ + /** + * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). + */ + uint8_t error_code; +} PACKED evt_gatt_procedure_complete; + +/** + * This event is generated when an Error Response is received from the server. The error response can be given + * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended + * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. + */ +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +typedef __packed struct _evt_gatt_error_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t req_opcode; /**< The request that generated this error response. */ + uint16_t attr_handle; /**< The attribute handle that generated this error response. */ + uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ +} PACKED evt_gatt_error_resp; + +/** + * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using + * Characteristic UUID" procedure. + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. + */ +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + /** + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. + */ + uint8_t attr_value[VARIABLE_SIZE]; +} PACKED evt_gatt_disc_read_char_by_uuid_resp; + +/** + * This event is given to the application when a write request, write command or signed write command + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * If the write is rejected by the application, then the value of the attribute will not be modified. + * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. + * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef __packed struct _evt_gatt_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_write_permit_req; + +/** + * This event is given to the application when a read request or read blob request is received by the server + * from the client. This event will be given to the application only if the event bit for this event generation + * is set when the characteristic was added. + * On receiving this event, the application can update the value of the handle if it desires and when done + * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef __packed struct _evt_gatt_read_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ + uint8_t data_length; /**< Length of offset field. */ + uint16_t offset; /**< Contains the offset from which the read has been requested */ +} PACKED evt_gatt_read_permit_req; + +/** + * This event is given to the application when a read multiple request or read by type request is received + * by the server from the client. This event will be given to the application only if the event bit for this + * event generation is set when the characteristic was added. + * On receiving this event, the application can update the values of the handles if it desires and when done + * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_multi_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) +typedef __packed struct _evt_gatt_read_multi_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ +} PACKED evt_gatt_read_multi_permit_req; + +/** + * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2). + * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES. + * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value(). + * See @ref evt_gatt_tx_pool_vailable. + * + */ +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE (0x0C16) +typedef __packed struct _evt_gatt_tx_pool_available{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t available_buffers; /**< Length of data field. */ +} PACKED evt_gatt_tx_pool_available; + +/** + * This event is raised on the server when the client confirms the reception of an indication. + */ +#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT (0x0C17) +typedef __packed struct _evt_gatt_server_confirmation{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ +} PACKED evt_gatt_server_confirmation; +/** + * This event is given to the application when a prepare write request + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * Based on the response from the application, the attribute value will be modified by the stack. + * If the write is rejected by the application, then the value of the attribute will not be modified + * and an error response will be sent to the client, with the error code as specified by the application. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ (0x0C18) +typedef __packed struct _evt_gatt_prepare_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint16_t offset; /**< The offset from which the prepare write has been requested */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_prepare_write_permit_req; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_gatt_server.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,229 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gatt_server.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GATT server layer. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BNRG_GATT_SERVER_H__ +#define __BNRG_GATT_SERVER_H__ + +#include "ble_compiler.h" +#include "ble_status.h" + +/** + *@addtogroup GATT GATT + *@{ + */ + +/** + * @anchor Well-Known_UUIDs + * @name Well-Known UUIDs + * @{ + */ +#define PRIMARY_SERVICE_UUID (0x2800) +#define SECONDARY_SERVICE_UUID (0x2801) +#define INCLUDE_SERVICE_UUID (0x2802) +#define CHARACTERISTIC_UUID (0x2803) +#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) +#define CHAR_USER_DESC_UUID (0x2901) +#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) +#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) +#define CHAR_FORMAT_DESC_UUID (0x2904) +#define CHAR_AGGR_FMT_DESC_UUID (0x2905) +#define GATT_SERVICE_UUID (0x1801) +#define GAP_SERVICE_UUID (0x1800) +#define SERVICE_CHANGED_UUID (0x2A05) +/** + * @} + */ + +/** + * @anchor Access_permissions + * @name Access permissions + * Access permissions for an attribute + * @{ + */ +#define ATTR_NO_ACCESS (0x00) +#define ATTR_ACCESS_READ_ONLY (0x01) +#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) +#define ATTR_ACCESS_READ_WRITE (0x03) +#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) +#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) +/** + * Allows all write procedures + */ +#define ATTR_ACCESS_WRITE_ANY (0x0E) +/** + * @} + */ + +/** + * @anchor Char_properties + * @name Characteristic properties. + * @{ + */ +#define CHAR_PROP_BROADCAST (0x01) +#define CHAR_PROP_READ (0x02) +#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) +#define CHAR_PROP_WRITE (0x08) +#define CHAR_PROP_NOTIFY (0x10) +#define CHAR_PROP_INDICATE (0x20) +#define CHAR_PROP_SIGNED_WRITE (0x40) +#define CHAR_PROP_EXT (0x80) +/** + * @} + */ + + +/** + * @anchor Security_permissions + * @name Security permissions for an attribute. + * @{ + */ +#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ +#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ +#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ +#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ +/** + * @} + */ + +/** + * @anchor UUID_Types + * @name Type of UUID (16 bit or 128 bit). + * @{ + */ +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) +/** + * @} + */ + +/** + * @anchor Service_type + * @name Type of service (primary or secondary) + * @{ + */ +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) +/** + * @} + */ + +/** + * @anchor Gatt_Event_Mask + * @name Gatt Event Mask + * Type of event generated by GATT server + * @{ + */ +#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ +#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. + An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ +#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd + or a signed write cmd are received by the server for this attribute. + An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ +#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is + received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ +/** + * @} + */ + +/** + * @name Type of characteristic length + * See aci_gatt_add_char() + * @{ + */ +#define CHAR_VALUE_LEN_CONSTANT (0x00) +#define CHAR_VALUE_LEN_VARIABLE (0x01) +/** + * @} + */ + + +/** + * @name Encryption key size + * @{ + */ +/** + * Minimum encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Maximum encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) +/** + * @} + */ + +/** + * @name Characteristic Presentation Format + * @{ + */ +typedef __packed struct _charactFormat { + uint8_t format; + int8_t exp; + uint16_t unit; + uint8_t name_space; + uint16_t desc; +} PACKED charactFormat; + +/** + * @} + */ + +/** + * @name Format + * @{ + */ +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F +/** + * @} + */ + +/** + * @name Unit + * @{ + */ +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 +/** + * @} + */ + + +/** + * ATT MTU size + */ +#define ATT_MTU (23) + +/** + * @} + */ + + /** + * @name Update type of aci_gatt_upd_char_val_ext(). + * @{ + */ + +#define NOTIFICATION 1 +#define INDICATION 2 + +#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_hal_aci.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,385 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hal_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with HCI commands for BlueNRG +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_HAL_ACI_H__ +#define __BLUENRG_HAL_ACI_H__ + +/** + *@addtogroup HAL HAL + *@brief Hardware Abstraction Layer. + *@{ + */ + +/** + * @defgroup HAL_Functions HAL functions + * @brief API for BlueNRG HAL layer. + * @{ + */ + +/** + * @brief This command retrieves the buid number of the firmware. + * @param[out] build_number Build number identifying the firmware release. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number); + +/** + * @brief This command writes a value to a low level configure data structure. + * @note It is useful to setup directly some low level parameters for the system at runtime. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * + * @param len Length of data to be written + * @param[out] val Data to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val); + +/** + * @brief This command requests the value in the low level configure data structure. + * The number of read bytes changes for different Offset. + * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n + * See @ref Config_vals. + * @param data_len Length of the data buffer + * @param[out] data_len_out_p length of the data returned by the read. + * @param[out] data Read data + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data); + +/** + * @brief This command sets the TX power level of the BlueNRG. + * @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines + * the output power level (dBm). + * When the system starts up or reboots, the default TX power level will be used, which is + * the maximum value of 8dBm. Once this command is given, the output power will be changed + * instantly, regardless if there is Bluetooth communication going on or not. For example, + * for debugging purpose, the BlueNRG can be set to advertise all the time and use this + * command to observe the signal strength changing. The system will keep the last received + * TX power level from the command, i.e. the 2nd command overwrites the previous TX power + * level. The new TX power level remains until another Set TX Power command, or the system + * reboots.\n + * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the + * right value, depending on the selected hardware configuration for the RF network: + * normal mode or high power mode. + * @param pa_level Can be from 0 to 7. Set the PA level value. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +/** + * @brief This command returns the number of packets sent in Direct Test Mode. + * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets + * have been transmitted. This command can be used to check how many packets have been sent + * during the Direct TX test.\n + * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again. + * The counter is not cleared until the next Direct TX test starts. + * @param[out] number_of_packets Number of packets sent during the last Direct TX test. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets); + +/** + * @brief Put the device in standby mode. + * @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the + * device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode, + * the device can still wake up itself with the internal timer. But in standby mode, this timer is + * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command + * sent via SPI bus. + * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code + * ERR_COMMAND_DISALLOWED will be returned. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_device_standby(void); + +/** + * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. + * @note The frequency sine wave at the specific channel may be used for test purpose only. + * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. + * This command shouldn't be used when normal Bluetooth activities are ongoing. + * The tone should be stopped by aci_hal_tone_stop() command. + * + * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the + * channel central frequency minus 250 kHz. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +/** + * This command is used to stop the previously started aci_hal_tone_start() command. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_stop(void); + +/** + * @brief This command returns the status of all the connections. + * @note This command returns the status of the 8 Bluetooth low energy links managed by the device. + * @param[out] link_status Array of link status (8 links). See @ref Link_Status. + * @param[out] conn_handle Array of connection handles for each link. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]); + +/** + * @brief This command returns the anchor period and the largest available slot. + * @note This command returns information about the anchor period to help application in selecting + * slot timings when operating in multi-link scenarios. + * @param anchor_period Current anchor period (multiple of 0.625 ms). + * @param max_free_slot Maximum available time (multiple of 0.625 ms) that can be allocated for a new slot. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot); + +/** + * @} + */ + +/** + * @defgroup HAL_Events HAL events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_HAL_INITIALIZED (0x0001) +typedef __packed struct _evt_hal_initialized{ + uint8_t reason_code; /**< Reset reason. See @ref Reset_Reasons */ +} PACKED evt_hal_initialized; + +/** + * This event is generated when an overflow occurs in the event queue read by the external microcontroller. + * This is normally caused when the external microcontroller does not read pending events. + * The returned bitmap indicates which event has been lost. Please note that one bit set to 1 indicates one or + * more occurrences of the particular events. The event EVT_BLUE_HAL_EVENTS_LOST cannot be lost and it will + * be inserted in the event queue as soon as a position is freed in the event queue. This event should not + * happen under normal operating condition where external microcontroller promptly reads events signaled by + * IRQ pin. It is provided to detected unexpected behavior of the external microcontroller or to allow + * application to recover situations where critical events are lost. + */ +#define EVT_BLUE_HAL_EVENTS_LOST_IDB05A1 (0x0002) +typedef __packed struct _evt_hal_events_lost{ + uint8_t lost_events[8]; /**< Bitmap of lost events. Each bit indicates one or more occurrences of the specific event. See @ref Lost_Events */ +} PACKED evt_hal_events_lost_IDB05A1; + + +/** + * This event is given to the application after the @ref ACI_BLUE_INITIALIZED_EVENT + * when a system crash is detected. This events returns system crash information for debugging purposes. + * Information reported are useful to understand the root cause of the crash. + */ +#define EVT_BLUE_HAL_CRASH_INFO_IDB05A1 (0x0003) +typedef __packed struct _evt_hal_crash_info{ + uint8_t crash_type; /**< Type of crash: Assert failed (0), NMI Fault (1), Hard Fault (2) */ + uint32_t sp; /**< SP register */ + uint32_t r0; /**< R0 register */ + uint32_t r1; /**< R1 register */ + uint32_t r2; /**< R2 register */ + uint32_t r3; /**< R3 register */ + uint32_t r12; /**< R12 register */ + uint32_t lr; /**< LR register */ + uint32_t pc; /**< PC register */ + uint32_t xpsr; /**< xPSR register */ + uint8_t debug_data_len; /**< length of debug_data field */ + uint8_t debug_data[VARIABLE_SIZE]; /**< Debug data */ +} PACKED evt_hal_crash_info_IDB05A1; + + +/** + * @} + */ + + +/** + * @anchor Reset_Reasons + * @name Reset Reasons + * See @ref EVT_BLUE_HAL_INITIALIZED. + * @{ + */ +#define RESET_NORMAL 1 /**< Normal startup. */ +#define RESET_UPDATER_ACI 2 /**< Updater mode entered with ACI command */ +#define RESET_UPDATER_BAD_FLAG 3 /**< Updater mode entered due to a bad BLUE flag */ +#define RESET_UPDATER_PIN 4 /**< Updater mode entered with IRQ pin */ +#define RESET_WATCHDOG 5 /**< Reset caused by watchdog */ +#define RESET_LOCKUP 6 /**< Reset due to lockup */ +#define RESET_BROWNOUT 7 /**< Brownout reset */ +#define RESET_CRASH 8 /**< Reset caused by a crash (NMI or Hard Fault) */ +#define RESET_ECC_ERR 9 /**< Reset caused by an ECC error */ +/** + * @} + */ + + +/** + * @defgroup Config_vals Offsets and lengths for configuration values. + * @brief Offsets and lengths for configuration values. + * See aci_hal_write_config_data(). + * @{ + */ + +/** + * @name Configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ +#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ +#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ +#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ +#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. + It can be written only if aci_hal_write_config_data() is the first command after reset. */ +#define CONFIG_DATA_RANDOM_ADDRESS (0x80) /**< Stored static random address. Read-only. */ + +/** + * Select the BlueNRG mode configurations.\n + * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) + * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) + * @li Mode 3: master/slave, 8 connections, RAM1 and RAM2. + * @li Mode 4: master/slave, 4 connections, RAM1 and RAM2 simultaneous scanning and advertising. + */ +#define CONFIG_DATA_MODE_OFFSET (0x2D) + +#define CONFIG_DATA_WATCHDOG_DISABLE (0x2F) /**< Set to 1 to disable watchdog. It is enabled by default. */ +/** + * @} + */ + +/** + * @name Length for configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_LEN (6) +#define CONFIG_DATA_DIV_LEN (2) +#define CONFIG_DATA_ER_LEN (16) +#define CONFIG_DATA_IR_LEN (16) +#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) +#define CONFIG_DATA_MODE_LEN (1) +#define CONFIG_DATA_WATCHDOG_DISABLE_LEN (1) +/** + * @} + */ + +/** + * @anchor Link_Status + * @name Status of the link + * See @ref aci_hal_get_link_status(). + * @{ + */ +#define STATUS_IDLE 0 +#define STATUS_ADVERTISING 1 +#define STATUS_CONNECTED_AS_SLAVE 2 +#define STATUS_SCANNING 3 +#define STATUS_CONNECTED_AS_MASTER 5 +#define STATUS_TX_TEST 6 +#define STATUS_RX_TEST 7 +/** + * @} + */ + +/** + * @} + */ + + /** + * @anchor Lost_Events + * @name Lost events bitmap + * See @ref EVT_BLUE_HAL_EVENTS_LOST. + * @{ + */ +#define EVT_DISCONN_COMPLETE_BIT 0 +#define EVT_ENCRYPT_CHANGE_BIT 1 +#define EVT_READ_REMOTE_VERSION_COMPLETE_BIT 2 +#define EVT_CMD_COMPLETE_BIT 3 +#define EVT_CMD_STATUS_BIT 4 +#define EVT_HARDWARE_ERROR_BIT 5 +#define EVT_NUM_COMP_PKTS_BIT 6 +#define EVT_ENCRYPTION_KEY_REFRESH_BIT 7 +#define EVT_BLUE_HAL_INITIALIZED_BIT 8 +#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE_BIT 9 +#define EVT_BLUE_GAP_PAIRING_CMPLT_BIT 10 +#define EVT_BLUE_GAP_PASS_KEY_REQUEST_BIT 11 +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST_BIT 12 +#define EVT_BLUE_GAP_SECURITY_REQ_INITIATED_BIT 13 +#define EVT_BLUE_GAP_BOND_LOST_BIT 14 +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE_BIT 15 +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_BIT 16 +#define EVT_BLUE_L2CAP_CONN_UPDATE_RESP_BIT 17 +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT_BIT 18 +#define EVT_BLUE_L2CAP_CONN_UPDATE_REQ_BIT 19 +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_BIT 20 +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT_BIT 21 +#define EVT_BLUE_EXCHANGE_MTU_RESP_BIT 22 +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP_BIT 23 +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP_BIT 24 +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP_BIT 25 +#define EVT_BLUE_ATT_READ_RESP_BIT 26 +#define EVT_BLUE_ATT_READ_BLOB_RESP_BIT 27 +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP_BIT 28 +#define EVT_BLUE_ATT_READ_BY_GROUP_RESP_BIT 29 +#define EVT_BLUE_ATT_WRITE_RESP_BIT 30 +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP_BIT 31 +#define EVT_BLUE_ATT_EXEC_WRITE_RESP_BIT 32 +#define EVT_BLUE_GATT_INDICATION_BIT 33 +#define EVT_BLUE_GATT_NOTIFICATION_BIT 34 +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE_BIT 35 +#define EVT_BLUE_GATT_ERROR_RESP_BIT 36 +#define EVT_BLUE_GATT_DISC_READ_CHARAC_BY_UUID_RESP_BIT 37 +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ_BIT 38 +#define EVT_BLUE_GATT_READ_PERMIT_REQ_BIT 39 +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ_BIT 40 +#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_BIT 41 +#define EVT_BLUE_GATT_SERVER_RX_CONFIRMATION_BIT 42 +#define EVT_BLUE_GATT_PREPARE_WRITE_PERMIT_REQ_BIT 43 +#define EVT_LL_CONNECTION_COMPLETE_BIT 44 +#define EVT_LL_ADVERTISING_REPORT_BIT 45 +#define EVT_LL_CONNECTION_UPDATE_COMPLETE_BIT 46 +#define EVT_LL_READ_REMOTE_USED_FEATURES_BIT 47 +#define EVT_LL_LTK_REQUEST_BIT 48 +/** + * @} + */ + +/** + * @name Hardware error event codes + * See @ref EVT_HARDWARE_ERROR. + * @{ + */ +/** + * Error on the SPI bus has been detected, most likely caused by incorrect SPI configuration on the external micro-controller. + */ +#define SPI_FRAMING_ERROR 0 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define RADIO_STATE_ERROR 1 +/** + * Caused by a slow crystal startup and they are an indication that the HS_STARTUP_TIME + * in the device configuration needs to be tuned. After this event is recommended to hardware reset the device. + */ +#define TIMER_OVERRUN_ERROR 2 + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_l2cap_aci.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,166 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_l2cap_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with L2CAP commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_L2CAP_ACI_H__ +#define __BLUENRG_L2CAP_ACI_H__ + +/** + *@addtogroup L2CAP L2CAP + *@brief L2CAP layer. + *@{ + */ + +/** + *@defgroup L2CAP_Functions L2CAP functions + *@brief API for L2CAP layer. + *@{ + */ + +/** + * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. + * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request + * (accepts or rejects). + * @param conn_handle Connection handle on which the connection parameter update request has to be sent. + * @param interval_min Defines minimum value for the connection event interval in the following manner: + * connIntervalMin = interval_min x 1.25ms + * @param interval_max Defines maximum value for the connection event interval in the following manner: + * connIntervalMax = interval_max x 1.25ms + * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). + * @param timeout_multiplier Defines connection timeout parameter in the following manner: + * timeout_multiplier x 10ms. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier); +/** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param min_ce_length Minimum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_ce_length Maximum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept); + /** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept); + +/** + * @} + */ + +/** + * @defgroup L2CAP_Events L2CAP events + * @{ + */ + +/** + * This event is generated when the master responds to the L2CAP connection update request packet. + * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. + */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef __packed struct _evt_l2cap_conn_upd_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ +/** + * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. + * @li 0x01 in case of Command Reject. + */ + uint8_t code; + uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ + uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ +/** + * Result code (parameters accepted or rejected) in case of Connection Parameter Update + * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). + */ + uint16_t result; +} PACKED evt_l2cap_conn_upd_resp; + +/** + * This event is generated when the master does not respond to the connection update request + * within 30 seconds. + */ +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) +typedef __packed struct _evt_l2cap_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */ +} PACKED evt_l2cap_procedure_timeout; + +/** + * The event is given by the L2CAP layer when a connection update request is received from the slave. + * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). + */ +#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) +typedef __packed struct _evt_l2cap_conn_upd_req{ +/** + * Handle of the connection for which the connection update request has been received. + * The same handle has to be returned while responding to the event with the command + * aci_l2cap_connection_parameter_update_response(). + */ + uint16_t conn_handle; + uint8_t event_data_length; /**< Length of following data. */ +/** + * This is the identifier which associates the request to the + * response. The same identifier has to be returned by the upper + * layer in the command aci_l2cap_connection_parameter_update_response(). + */ + uint8_t identifier; + uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ + uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ +} PACKED evt_l2cap_conn_upd_req; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_updater_aci.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_updater_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with updater commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#ifndef __BLUENRG_UPDATER_ACI_H__ +#define __BLUENRG_UPDATER_ACI_H__ + +#include <ble_compiler.h> + +/** + * @defgroup Updater Updater + * @brief Updater. + * @{ + */ + +/** + * @defgroup Updater_Functions Updater functions + * @brief API for BlueNRG Updater. + * @{ + */ + +tBleStatus aci_updater_start(void); + +tBleStatus aci_updater_reboot(void); + +tBleStatus aci_get_updater_version(uint8_t *version); + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); + +tBleStatus aci_erase_blue_flag(void); + +tBleStatus aci_reset_blue_flag(void); + +tBleStatus aci_updater_erase_sector(uint32_t address); + +tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); + +tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); + +tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); + +tBleStatus aci_updater_hw_version(uint8_t *version); + +/** + * @} + */ + +/** + * @defgroup Updater_Events Updater events + * @{ + */ +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_INITIALIZED (0x0001) +typedef __packed struct _evt_blue_initialized{ + uint8_t reason_code; +} PACKED evt_blue_initialized; +/** + * @} + */ + +/** + * @} + */ + + + +#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg-hci/bluenrg_utils.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,204 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_utils.h +* Author : AMS - VMA, RF Application Team +* Version : V1.0.1 +* Date : 03-October-2014 +* Description : Header file for BlueNRG utility functions +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ +/** + * @file bluenrg_utils.h + * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description + * + * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> +**/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLUENRG_UTILS_H +#define __BLUENRG_UTILS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "ble_hal_types.h" +#include "ble_compiler.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct{ + uint8_t stack_mode; + uint8_t day; + uint8_t month; + uint8_t year; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint16_t hs_startup_time; /* In system time units*/ +} IFR_config2_TypeDef; + +/** + * Structure inside IFR for configuration options. + */ +typedef __packed struct{ + uint8_t cold_ana_act_config_table[64]; + uint8_t hot_ana_config_table[64]; + uint8_t stack_mode; + uint8_t gpio_config; + uint8_t rsrvd1[2]; + uint32_t rsrvd2[3]; + uint32_t max_conn_event_time; + uint32_t ls_crystal_period; + uint32_t ls_crystal_freq; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint8_t rsrvd3; + uint16_t hs_startup_time; /* In system time units*/ + uint8_t rsrvd4[2]; + uint32_t uid; + uint8_t rsrvd5; + uint8_t year; + uint8_t month; + uint8_t day; + uint32_t unused[5]; +} PACKED IFR_config_TypeDef; + +/* Exported constants --------------------------------------------------------*/ +extern const IFR_config_TypeDef IFR_config; + +/* Exported macros -----------------------------------------------------------*/ +#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)+1) +#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) + +/* Convert 2 digit BCD number to an integer */ +#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) + +/* Convert 2 digit number to a BCD number */ +#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) + +/** + * Return values + */ +#define BLE_UTIL_SUCCESS 0 +#define BLE_UTIL_UNSUPPORTED_VERSION 1 +#define BLE_UTIL_WRONG_IMAGE_SIZE 2 +#define BLE_UTIL_ACI_ERROR 3 +#define BLE_UTIL_CRC_ERROR 4 +#define BLE_UTIL_PARSE_ERROR 5 +#define BLE_UTIL_WRONG_VERIFY 6 + +/* Exported functions ------------------------------------------------------- */ +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int program_device(const uint8_t *fw_image, uint32_t fw_size); + +/** + * @brief Read raw data from IFR (3 64-bytes blocks). + * @param data Pointer to the buffer that will contain the read data. + * Its size must be 192 bytes. This data can be parsed by + * parse_IFR_data_config(). + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION) + */ +int read_IFR(uint8_t data[192]); + +/** + * @brief Verify raw data from IFR (3 64-bytes blocks). + * @param ifr_data Pointer to the buffer that will contain the data to verify. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) + */ +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); + +/** + * @brief Program raw data to IFR (3 64-bytes blocks). + * @param ifr_image Pointer to the buffer that will contain the data to program. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful + */ +int program_IFR(const IFR_config_TypeDef *ifr_image); + +/** + * @brief Parse IFR raw data. + * @param data Pointer to the raw data: last 64 bytes read from IFR sector. + * @param IFR_config Data structure that will be filled with parsed data. + * @retval None + */ +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); + +/** + * @brief Check for the correctness of parsed data. + * @param IFR_config Data structure filled with parsed data. + * @retval int It returns 0 if successful, or PARSE_ERROR in case data is + * not correct. + */ +int IFR_validate(IFR_config2_TypeDef *IFR_config); + +/** + * @brief Modify IFR data. (Last 64-bytes block). + * @param IFR_config Structure that contains the new parameters inside the + * IFR configuration data. + * @note It is highly recommended to parse the IFR configuration from + * a working IFR block (this should be done with parse_IFR_data_config()). + * Then it is possible to write the new parameters inside the IFR_config + * structure. + * @param data Pointer to the buffer that contains the original data. It + * will be modified according to the new data in the IFR_config + * structure. Then this data must be written in the last + * 64-byte block in the IFR. + * Its size must be 64 bytes. + * @retval None + */ +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); + +/** + * @brief Get BlueNRG hardware and firmware version + * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). + * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN + * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. + * @retval Status of the call + */ +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); + +/** + * @brief Get BlueNRG updater version + * @param version This parameter returns the updater version. If the updadter version is 0x03 + * the chip has the updater old, needs to update the bootloader. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterVersion(uint8_t *version); + +/** + * @brief Get BlueNRG HW version in bootloader mode + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version); + +/** + * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on + * the HW bootloader related to the 32 MHz external crystal oscillator. + * @retval TRUE if the HW bootloader is already patched, FALSE otherwise + */ +uint8_t isHWBootloader_Patched(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__BLUENRG_UTILS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/bluenrg_targets.h Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/bluenrg/platform/btle.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef _BTLE_H_ +#define _BTLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "bluenrg_aci.h" +#include "ble_hci_const.h" +#include "bluenrg_hal_aci.h" +#include "stm32_bluenrg_ble.h" +#include "bluenrg_gap.h" +#include "bluenrg_gatt_server.h" + +extern uint16_t g_gap_service_handle; +extern uint16_t g_appearance_char_handle; +extern uint16_t g_device_name_char_handle; +extern uint16_t g_preferred_connection_parameters_char_handle; + +void btleInit(void); +void SPI_Poll(void); +void User_Process(void); +void setConnectable(void); +void setVersionString(uint8_t hwVersion, uint16_t fwVersion); +const char* getVersionString(void); +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type); + + +extern int btle_handler_pending; +extern void btle_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/platform/stm32_bluenrg_ble.h Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_payload.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/mbed.h" +#else + #include "mbed.h" +#endif +#include "ble_debug.h" + +#ifndef __PAYLOAD_H__ +#define __PAYLOAD_H__ + +class UnitPayload +{ +public: + uint8_t length; + uint8_t id; + uint8_t *data; + uint8_t *idptr; + + + + void set_length(uint8_t l) { + length=l; + } + + void set_id(uint8_t i) { + id=i; + } + + void set_data(uint8_t* data1) { + for(int j=0;j<length;j++) + { + data[j]=data1[j]; + } + } + + uint8_t get_length() { + return length; + } + + uint8_t get_id() { + return id; + } + + uint8_t* get_data() { + return data; + } + +}; + +class Payload { + UnitPayload *payload; + int stringLength; + int payloadUnitCount; + +public: + Payload(const uint8_t *tokenString, uint8_t string_ength); + Payload(); + ~Payload(); + uint8_t getPayloadUnitCount(); + + uint8_t getIDAtIndex(int index); + uint8_t getLengthAtIndex(int index); + uint8_t* getDataAtIndex(int index); + int8_t getInt8AtIndex(int index); + uint16_t getUint16AtIndex(int index); + uint8_t* getSerializedAdDataAtIndex(int index); +}; + + +class PayloadUnit { +private: + uint8_t* lenPtr; + uint8_t* adTypePtr; + uint8_t* dataPtr; + +public: + PayloadUnit() { + lenPtr = NULL; + adTypePtr = NULL; + dataPtr = NULL; + } + + PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { + lenPtr = len; + adTypePtr = adType; + dataPtr = data; + } + + void setLenPtr(uint8_t *len) { + lenPtr = len; + } + + void setAdTypePtr(uint8_t *adType) { + adTypePtr = adType; + } + + void setDataPtr(uint8_t *data) { + dataPtr = data; + } + + uint8_t* getLenPtr() { + return lenPtr; + } + + uint8_t* getAdTypePtr() { + return adTypePtr; + } + + uint8_t* getDataPtr() { + return dataPtr; + } + + void printDataAsHex() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("0x%x ", dataPtr[i]); + } + PRINTF("\n"); + } + + void printDataAsString() { + int i = 0; + PRINTF("AdData="); + for(i=0; i<*lenPtr-1; i++) { + PRINTF("%c", dataPtr[i]); + } + PRINTF("\n"); + } + +}; + +class PayloadPtr { +private: + PayloadUnit *unit; + int payloadUnitCount; +public: + PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + int stringLength = string_ength; + payloadUnitCount = 0; + + int index = 0; + while(index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + // allocate memory to unit + unit = new PayloadUnit[payloadUnitCount]; + int i = 0; + int nextUnitOffset = 0; + + while(i<payloadUnitCount) { + unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); + unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); + unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); + + nextUnitOffset += *unit[i].getLenPtr()+1; + i++; + + } + } + + PayloadUnit getUnitAtIndex(int index) { + return unit[index]; + } + + int getPayloadUnitCount() { return payloadUnitCount; } + + ~PayloadPtr() { + if(unit) delete[] unit; + + unit = NULL; + } +}; + +#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/bluenrg/utils/ble_utils.h Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include "ble_status.h" +#include "ble_hal_types.h" + +#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do {\ + uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ + }while(0) + + +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); + +#endif // __UTIL_H__ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/mbed_lib.json Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,16 @@ +{ + "name": "bluenrg", + "target_overrides": { + "K64F": { + "target.macros_add": ["BLUENRG_PIN_SPI_SCK=D13"] + }, + "DISCO_L475VG_IOT01A": { + "target.macros_add": ["BLUENRG_PIN_SPI_MOSI=PC_12", + "BLUENRG_PIN_SPI_MISO=PC_11", + "BLUENRG_PIN_SPI_nCS=PD_13", + "BLUENRG_PIN_SPI_RESET=PA_8", + "BLUENRG_PIN_SPI_IRQ=PE_6", + "BLUENRG_PIN_SPI_SCK=PC_10"] + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/module.json Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,37 @@ +{ + "name": "x-nucleo-idb0xa1", + "version": "2.2.0", + "description": "ST driver for the mbed BLE API.", + "keywords": [ + "expansion", + "board", + "x-nucleo", + "nucleo", + "ST", + "STM", + "Bluetooth", + "BLE" + ], + "author": "Andrea Palmieri", + "repository": { + "url": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1.git", + "type": "git" + }, + "homepage": "https://github.com/ARMmbed/ble-x-nucleo-idb0xa1", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "extraIncludes": [ + "x-nucleo-idb0xa1", + "x-nucleo-idb0xa1/utils", + "x-nucleo-idb0xa1/platform", + "x-nucleo-idb0xa1/bluenrg-hci" + ], + "dependencies": { + "mbed-drivers": ">=0.11.3", + "ble": "^2.7.0" + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGDevice.cpp Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/source/BlueNRGDiscoveredCharacteristic.cpp Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,68 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BlueNRGDiscoveredCharacteristic.h" +#include "BlueNRGGattClient.h" + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + +void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn, + Gap::Handle_t connectionHandleIn, + UUID uuidIn, + DiscoveredCharacteristic::Properties_t propsIn, + GattAttribute::Handle_t declHandleIn, + GattAttribute::Handle_t valueHandleIn, + GattAttribute::Handle_t lastHandleIn) +{ + gattc = gattcIn; + connHandle = connectionHandleIn; + uuid = uuidIn; + declHandle = declHandleIn; + valueHandle = valueHandleIn; + lastHandle = lastHandleIn; + + props._broadcast = propsIn.broadcast(); + props._read = propsIn.read(); + props._writeWoResp = propsIn.writeWoResp(); + props._write = propsIn.write(); + props._notify = propsIn.notify(); + props._indicate = propsIn.indicate(); + props._authSignedWrite = propsIn.authSignedWrite(); +} + + void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) { + lastHandle = lastHandleIn; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/source/BlueNRGGap.cpp Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/source/BlueNRGGattClient.cpp Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/source/BlueNRGGattConnectionClient.cpp Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/source/BlueNRGGattServer.cpp Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci.c Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/ble_hci_le.c Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,1309 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB05A1 cp; + gap_init_rp resp; + + cp.role = role; + cp.privacy_enabled = privacy_enabled; + cp.device_name_char_len = device_name_char_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} +tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB04A1 cp; + gap_init_rp resp; + + cp.role = role; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + SlaveConnIntervMin = htobs(SlaveConnIntervMin); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + SlaveConnIntervMax = htobs(SlaveConnIntervMax); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, + const uint8_t *initiator_addr, uint16_t adv_interv_min, uint16_t adv_interv_max) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB05A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.directed_adv_type = directed_adv_type; + cp.adv_interv_min = adv_interv_min; + cp.adv_interv_max = adv_interv_max; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB04A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_io_capability(uint8_t io_capability) +{ + struct hci_request rq; + uint8_t status; + gap_set_io_capability_cp cp; + + cp.io_capability = io_capability; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_IO_CAPABILITY; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode) +{ + struct hci_request rq; + gap_set_auth_requirement_cp cp; + uint8_t status; + + cp.mitm_mode = mitm_mode; + cp.oob_enable = oob_enable; + Osal_MemCpy(cp.oob_data, oob_data, 16); + cp.min_encryption_key_size = min_encryption_key_size; + cp.max_encryption_key_size = max_encryption_key_size; + cp.use_fixed_pin = use_fixed_pin; + cp.fixed_pin = htobl(fixed_pin); + cp.bonding_mode = bonding_mode; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) +{ + struct hci_request rq; + gap_set_author_requirement_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorization_enable = authorization_enable; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) +{ + struct hci_request rq; + gap_passkey_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.passkey = htobl(passkey); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_PASSKEY_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) +{ + struct hci_request rq; + gap_authorization_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorize = authorize; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB05A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + cp.own_address_type = own_address_type; + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB04A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) +{ + struct hci_request rq; + gap_set_undirected_connectable_cp cp; + uint8_t status; + + cp.own_addr_type = own_addr_type; + cp.adv_filter_policy = adv_filter_policy; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) +{ + struct hci_request rq; + gap_slave_security_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.bonding = bonding; + cp.mitm_protection = mitm_protection; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[32]; + uint8_t indx = 0; + + if (AdvLen > (sizeof(buffer)-1)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvLen; + indx++; + + Osal_MemCpy(buffer + indx, AdvData, AdvLen); + indx += AdvLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_UPDATE_ADV_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) +{ + struct hci_request rq; + gap_delete_ad_type_cp cp; + uint8_t status; + + cp.ad_type = ad_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_DELETE_AD_TYPE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required) +{ + struct hci_request rq; + gap_get_security_level_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; + rq.rparam = &resp; + rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *mitm_protection = resp.mitm_protection; + *bonding = resp.bonding; + *oob_data = resp.oob_data; + *passkey_required = resp.passkey_required; + + return resp.status; +} + +tBleStatus aci_gap_configure_whitelist(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) +{ + struct hci_request rq; + gap_terminate_cp cp; + uint8_t status; + + cp.handle = htobs(conn_handle); + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_clear_security_database(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) +{ + struct hci_request rq; + gap_allow_rebond_cp_IDB05A1 cp; + uint8_t status; + + cp.conn_handle = conn_handle; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_allow_rebond_IDB04A1(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_limited_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_general_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_name_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = use_reconn_addr; + indx++; + + Osal_MemCpy(buffer + indx, reconn_addr, 6); + indx += 6; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB05A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB04A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.use_reconn_addr = use_reconn_addr; + Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_start_selective_conn_establish_proc_cp cp; + uint8_t status; + + if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.num_whitelist_entries = num_whitelist_entries; + + Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_create_connection_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CREATE_CONNECTION; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; + rq.cparam = &procedure_code; + rq.clen = 1; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_connection_update_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) +{ + struct hci_request rq; + gap_send_pairing_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.force_rebond = force_rebond; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + gap_resolve_private_address_rp rp; + + Osal_MemCpy(cp.address, private_address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); + + return 0; +} +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + uint8_t status; + + Osal_MemCpy(cp.address, address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_set_broadcast_mode_cp cp; + uint8_t status; + uint8_t indx = 0; + uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; + + if (variable_size > sizeof(cp.var_len_data) ) + return BLE_STATUS_INVALID_PARAMS; + + cp.adv_interv_min = htobs(adv_interv_min); + cp.adv_interv_max = htobs(adv_interv_max); + cp.adv_type = adv_type; + cp.own_addr_type = own_addr_type; + + cp.var_len_data[indx] = adv_data_length; + indx++; + Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); + indx += adv_data_length; + cp.var_len_data[indx] = num_whitelist_entries; + indx ++; + Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_BROADCAST_MODE; + rq.cparam = &cp; + rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_observation_proc_cp cp; + uint8_t status; + + cp.scan_interval = scan_interval; + cp.scan_window = scan_window; + cp.scan_type = scan_type; + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_OBSERVATION_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) +{ + struct hci_request rq; + gap_is_device_bonded_cp cp; + uint8_t status; + + cp.peer_address_type = peer_address_type; + Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_IS_DEVICE_BONDED; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) +{ + struct hci_request rq; + gap_get_bonded_devices_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_BONDED_DEVICES; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (rp.status) { + return rp.status; + } + + *num_devices = rp.num_addr; + if(device_list != NULL) + Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,1505 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.c +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : File with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_gatt_init(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INIT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[19]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, service_uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = service_type; + indx++; + + buffer[indx] = max_attr_records; + indx++; + + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle) +{ + struct hci_request rq; + gatt_include_serv_rp resp; + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + service_handle = htobs(service_handle); + Osal_MemCpy(buffer, &service_handle, 2); + indx += 2; + + included_start_handle = htobs(included_start_handle); + Osal_MemCpy(buffer+indx, &included_start_handle, 2); + indx += 2; + + included_end_handle = htobs(included_end_handle); + Osal_MemCpy(buffer+indx, &included_end_handle, 2); + indx += 2; + + if(included_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } else { + uuid_len = 16; + } + + buffer[indx] = included_uuid_type; + indx++; + + Osal_MemCpy(buffer + indx, included_uuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INCLUDE_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *included_handle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[25]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + buffer[indx] = charValueLen; + indx++; + + buffer[indx] = charProperties; + indx++; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *charHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle) +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = descValueMaxLen; + indx++; + + buffer[indx] = descValueLen; + indx++; + + if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + Osal_MemCpy(buffer + indx, descValue, descValueLen); + indx += descValueLen; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = accPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR_DESC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *descHandle = btohs(resp.handle); + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const void *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = charValOffset; + indx++; + + buffer[indx] = charValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charValue, charValueLen); + indx += charValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_char_cp cp; + + cp.service_handle = htobs(servHandle); + cp.char_handle = htobs(charHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_CHAR; + rq.cparam = &cp; + rq.clen = GATT_DEL_CHAR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_service(uint16_t servHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_serv_cp cp; + + cp.service_handle = htobs(servHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_inc_serv_cp cp; + + cp.service_handle = htobs(servHandle); + cp.inc_serv_handle = htobs(includeServHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_INC_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_INC_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) +{ + struct hci_request rq; + uint8_t status; + gatt_set_evt_mask_cp cp; + + cp.evt_mask = htobs(event_mask); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_EVT_MASK; + rq.cparam = &cp; + rq.clen = GATT_SET_EVT_MASK_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_exchange_config_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_EXCHANGE_CONFIG; + rq.cparam = &cp; + rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) +{ + struct hci_request rq; + uint8_t status; + att_find_info_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_INFO_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_find_by_type_value_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + Osal_MemCpy(cp.uuid, uuid, 2); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_group_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_prepare_write_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.value_offset = htobs(value_offset); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) +{ + struct hci_request rq; + uint8_t status; + att_execute_write_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.execute = execute; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_prim_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_prim_service_by_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; + rq.cparam = &cp; + rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, + uint16_t end_service_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_find_included_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_service_handle); + cp.end_handle = htobs(end_service_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_of_serv_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_attr_handle = htobs(start_attr_handle); + cp.end_attr_handle = htobs(end_attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t charUuidType, + const uint8_t* charUuid) +{ + struct hci_request rq; + uint8_t status; + + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + start_handle = htobs(start_handle); + Osal_MemCpy(buffer + indx, &start_handle, 2); + indx += 2; + + end_handle = htobs(end_handle); + Osal_MemCpy(buffer + indx, &end_handle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == 0x01){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_descriptors_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.char_val_handle = htobs(char_val_handle); + cp.char_end_handle = htobs(char_end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_read_using_charac_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; + rq.cparam = &cp; + rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles) +{ + struct hci_request rq; + uint8_t status; + gatt_read_multiple_charac_val_cp cp; + + if(num_handles*2 > sizeof(cp.set_of_handles)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.num_handles = htobs(num_handles); + Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_long_charac_val_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; + rq.cparam = &cp; + rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_signed_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_confirm_indication_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_CONFIRM_INDICATION; + rq.cparam = &cp; + rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = write_status; + indx += 1; + + buffer[indx] = err_code; + indx += 1; + + buffer[indx] = att_val_len; + indx += 1; + + Osal_MemCpy(buffer + indx, att_val, att_val_len); + indx += att_val_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(uint16_t conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ALLOW_READ; + rq.cparam = &cp; + rq.clen = GATT_ALLOW_READ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission) +{ + struct hci_request rq; + gatt_set_security_permission_cp cp; + uint8_t status; + + cp.service_handle = htobs(service_handle); + cp.attr_handle = htobs(attr_handle); + cp.security_permission = security_permission; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; + rq.cparam = &cp; + rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const void *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + charDescHandle = htobs(charDescHandle); + Osal_MemCpy(buffer + indx, &charDescHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charDescValOffset, 2); + indx += 2; + + buffer[indx] = charDescValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); + indx += charDescValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_DESC_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_cp cp; + gatt_read_handle_val_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = btohs(rp.value_len); + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_offset_cp cp; + gatt_read_handle_val_offset_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rp.value_len; + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_update_char_value_ext_IDB05A1(uint16_t service_handle, uint16_t char_handle, + uint8_t update_type, uint16_t char_length, + uint16_t value_offset, uint8_t value_length, + const uint8_t* value) +{ + struct hci_request rq; + uint8_t status; + gatt_upd_char_val_ext_cp cp; + + if(value_length > sizeof(cp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.service_handle = htobs(service_handle); + cp.char_handle = htobs(char_handle); + cp.update_type = update_type; + cp.char_length = htobs(char_length); + cp.value_offset = htobs(value_offset); + cp.value_length = value_length; + Osal_MemCpy(cp.value, value, value_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL_EXT; + rq.cparam = &cp; + rq.clen = GATT_UPD_CHAR_VAL_EXT_CP_SIZE + value_length; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,266 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_osal.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_hal_get_fw_build_number(uint16_t *build_number) +{ + struct hci_request rq; + hal_get_fw_build_number_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_FW_BUILD_NUMBER; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *build_number = rp.build_number; + + return 0; +} + +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((len+2) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = offset; + indx++; + + buffer[indx] = len; + indx++; + + Osal_MemCpy(buffer + indx, val, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + hal_read_config_data_cp cp; + hal_read_config_data_rp rp; + + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_READ_CONFIG_DATA; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *data_len_out_p = rq.rlen-1; + + Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) +{ + struct hci_request rq; + hal_set_tx_power_level_cp cp; + uint8_t status; + + cp.en_high_power = en_high_power; + cp.pa_level = pa_level; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets) +{ + struct hci_request rq; + hal_le_tx_test_packet_number_rp resp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_LE_TX_TEST_PACKET_NUMBER; + rq.rparam = &resp; + rq.rlen = sizeof(resp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *number_of_packets = btohl(resp.number_of_packets); + + return 0; +} + +tBleStatus aci_hal_device_standby(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_DEVICE_STANDBY; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_start(uint8_t rf_channel) +{ + struct hci_request rq; + hal_tone_start_cp cp; + uint8_t status; + + cp.rf_channel = rf_channel; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_START; + rq.cparam = &cp; + rq.clen = HAL_TONE_START_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_stop(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_STOP; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_get_link_status(uint8_t link_status[8], uint16_t conn_handle[8]) +{ + struct hci_request rq; + hal_get_link_status_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_LINK_STATUS; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + Osal_MemCpy(link_status,rp.link_status,sizeof(link_status)); + for(int i = 0; i < 8; i++) + conn_handle[i] = btohs(rp.conn_handle[i]); + + return 0; +} + +tBleStatus aci_hal_get_anchor_period(uint32_t *anchor_period, uint32_t *max_free_slot) +{ + struct hci_request rq; + hal_get_anchor_period_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_GET_ANCHOR_PERIOD; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if(rp.status) + return rp.status; + + *anchor_period = btohl(rp.anchor_period); + *max_free_slot = btohl(rp.max_free_slot); + + return 0; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,117 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB05A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.min_ce_length = htobs(min_ce_length); + cp.max_ce_length = htobs(max_ce_length); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB04A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,269 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +#include "ble_hal_types.h" +#include "ble_status.h" +#include "ble_hal.h" +#include "ble_osal.h" +#include "ble_hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_updater_aci.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_updater_reboot(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_get_updater_version(uint8_t *version) +{ + struct hci_request rq; + get_updater_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_VERSION; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) +{ + struct hci_request rq; + get_updater_bufsize_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_BUFSIZE; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_reset_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = htobl(address); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_SECTOR; + rq.cparam = &cp; + rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_program_data_block(uint32_t address, + uint16_t len, + const uint8_t *data) +{ + struct hci_request rq; + uint8_t status; + updater_prog_data_block_cp cp; + + if( len > sizeof(cp.data)) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(len); + Osal_MemCpy(cp.data, data, len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_read_data_block(uint32_t address, + uint16_t data_len, + uint8_t *data) +{ + struct hci_request rq; + updater_read_data_block_cp cp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + + if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(data_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; + rq.rparam = buffer; + rq.rlen = data_len + 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + // First byte is status + Osal_MemCpy(data, buffer+1, data_len); + + return buffer[0]; +} + +tBleStatus aci_updater_calc_crc(uint32_t address, + uint8_t num_sectors, + uint32_t *crc) +{ + struct hci_request rq; + updater_calc_crc_cp cp; + updater_calc_crc_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + cp.address = htobl(address); + cp.num_sectors = num_sectors; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_CALC_CRC; + rq.cparam = &cp; + rq.clen = UPDATER_CALC_CRC_CP_SIZE; + rq.rparam = &resp; + rq.rlen = UPDATER_CALC_CRC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *crc = btohl(resp.crc); + + return resp.status; +} + +tBleStatus aci_updater_hw_version(uint8_t *version) +{ + struct hci_request rq; + updater_hw_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_HW_VERSION; + rq.rparam = &resp; + rq.rlen = UPDATER_HW_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/hci/controller/bluenrg_utils.c Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,423 @@ + +#include "ble_hal.h" +#include "ble_hal_types.h" +#include "ble_status.h" +#include "bluenrg_aci.h" +#include "bluenrg_utils.h" +#include "ble_hci.h" +#include "ble_hci_le.h" +#include "ble_osal.h" +#include "string.h" +#include "stm32_bluenrg_ble.h" + +#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 +#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 + +#define BASE_ADDRESS 0x10010000 + +#define FW_OFFSET (2*1024) // 2 KB +#define FW_OFFSET_MS 0 +#define FULL_STACK_SIZE (66*1024) // 66 KB +#define BOOTLOADER_SIZE (2*1024) // 2 kB +#define SECTOR_SIZE (2*1024) // 2 KB + +// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + +// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 +#define CRC_POLY 0x04C11DB7 // the poly without the x**32 + +#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC + +#define IFR_SIZE 192 +#define IFR_BASE_ADDRESS 0x10020000 +#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data + +#if BLUENRG_MS +#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET +#else +#define IFR_WRITE_OFFSET_BEGIN 0 +#endif + + +#define BLUE_FLAG_OFFSET 0x8C0 +#define MAX_ERASE_RETRIES 2 +#define MAX_WRITE_RETRIES 2 +#define MIN_WRITE_BLOCK_SIZE 4 +#define MAX_WRITE_BLOCK_SIZE 64 // 64 bytes +#define READ_BLOCK_SIZE 64 // 64 bytes + +#define RETRY_COMMAND(func, num_ret, error) \ +{ \ + uint8_t num_retries; \ + num_retries = 0; \ + error = 0; \ + while (num_retries++ < num_ret) { \ + if (func == BLE_STATUS_SUCCESS) \ + break; \ + if (num_retries == num_ret) \ + error = BLE_UTIL_ACI_ERROR; \ + } \ +} + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, + they are extended with 0xFF until sector size is reached +*/ +static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) +{ + uint32_t i, j, a1; + uint32_t crc, value; + + crc = 0; + for (i = 0; i < SECTOR_SIZE; i += 4) { + uint8_t *dataw = (uint8_t *) &value; + + dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; + dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; + dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; + dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; + + crc = crc ^ value; + for (j = 0; j < 32; j ++) { + a1 = (crc >> 31) & 0x1; + crc = (crc << 1) ^ (a1 * CRC_POLY); + } + } + + return crc; +} + +int program_device(const uint8_t *fw_image, uint32_t fw_size) +{ + uint8_t version, num_erase_retries, status, write_block_size; + uint32_t address; + uint32_t crc, crc2, crc_size; + uint32_t fw_offset = FW_OFFSET; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + if(aci_updater_hw_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version==0x31){ + // It does not contain bootloader inside first sector. It may contain code. + fw_offset = FW_OFFSET_MS; + } + + if (fw_size != FULL_STACK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + if (fw_size % MIN_WRITE_BLOCK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + + /*********************************************************************** + * Erase BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + /*********************************************************************** + * Erase and Program sectors + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE) { + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(BASE_ADDRESS + i); + for (int j=i; ((j<i+SECTOR_SIZE)&&(j<fw_size)); j += write_block_size) { + + write_block_size = MIN(fw_size-j, MAX_WRITE_BLOCK_SIZE); + + RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, write_block_size, fw_image+j), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + break; + } + if (status == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + } + + /*********************************************************************** + * Verify firmware + ************************************************************************/ + for(int i = fw_offset; i < fw_size; i += SECTOR_SIZE){ + address = BASE_ADDRESS + i; + if(aci_updater_calc_crc(address, 1, &crc)) + return BLE_UTIL_ACI_ERROR; + + crc_size = MIN(fw_size-i,SECTOR_SIZE); + + crc2 = updater_calc_crc(fw_image+i,crc_size); + if(crc!=crc2) + return BLE_UTIL_CRC_ERROR; + } + + /*********************************************************************** + * Write BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +int read_IFR(uint8_t *data) +{ + uint8_t version, offset; + tBleStatus ret; + + offset = 0; + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + /*********************************************************************** + * Reading last 3 IFR 64-byte blocks + ************************************************************************/ + for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(BASE_ADDRESS+i, READ_BLOCK_SIZE, (data+offset)); + offset += READ_BLOCK_SIZE; + if(ret) return BLE_UTIL_ACI_ERROR; + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; + +} + +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) +{ + IFR_config->stack_mode = data[0]; + IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); + IFR_config->master_sca = data[30]; + IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); + IFR_config->year = BCD_TO_INT(data[41]); + IFR_config->month = BCD_TO_INT(data[42]); + IFR_config->day = BCD_TO_INT(data[43]); +} + +int IFR_validate(IFR_config2_TypeDef *IFR_config) +{ +#if BLUENRG_MS + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) +#else + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) +#endif + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode + if(IFR_config->master_sca > 7) + return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->day > 31 || IFR_config->day < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + + return BLE_STATUS_SUCCESS; +} + +/* TODO: Function to generate data from given options. */ + +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) +{ + data[0] = IFR_config->stack_mode; + HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); + data[30] = IFR_config->master_sca; + HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); + data[41] = INT_TO_BCD(IFR_config->year); + data[42] = INT_TO_BCD(IFR_config->month); + data[43] = INT_TO_BCD(IFR_config->day); +} + + +int program_IFR(const IFR_config_TypeDef *ifr_image) +{ + uint8_t version, num_erase_retries; + tBleStatus ret; +#if BLUENRG_MS + const uint8_t *ifr_data = (uint8_t *)ifr_image; +#else + uint8_t ifr_data[SECTOR_SIZE]; +#endif + uint8_t hwVersion; + uint16_t fwVersion; + + if(getBlueNRGVersion(&hwVersion, &fwVersion)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + +#ifndef BLUENRG_MS + /*********************************************************************** + * READ IFR data + ************************************************************************/ + for(int i = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_data+i); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + } +#endif + + /*********************************************************************** + * Erase & Flashing IFR sectors + ************************************************************************/ +#ifndef BLUENRG_MS + Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); +#endif + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(IFR_BASE_ADDRESS); + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += MAX_WRITE_BLOCK_SIZE, j += MAX_WRITE_BLOCK_SIZE) { + RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, MAX_WRITE_BLOCK_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); + if (ret != BLE_STATUS_SUCCESS) + break; + } + if (ret == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + + /*********************************************************************** + * Verify IFR + ************************************************************************/ + { + uint8_t ifr_updated[READ_BLOCK_SIZE]; + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += READ_BLOCK_SIZE, j += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ifr_data+j, READ_BLOCK_SIZE) != 0) + return BLE_UTIL_WRONG_VERIFY; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) +{ + uint8_t ifr_updated[READ_BLOCK_SIZE]; + uint8_t version, ret = BLE_STATUS_SUCCESS; + + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + for(int i = 0; i < IFR_SIZE; i += READ_BLOCK_SIZE){ + ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, READ_BLOCK_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, READ_BLOCK_SIZE) != 0) + { + ret = BLE_UTIL_WRONG_VERIFY; + break; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return ret; +} + +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) +{ + uint8_t status; + uint8_t hci_version, lmp_pal_version; + uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; + + status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, + &manufacturer_name, &lmp_pal_subversion); + + if (status == BLE_STATUS_SUCCESS) { + *hwVersion = hci_revision >> 8; + *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number + *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number + *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number + } + + return status; +} + +uint8_t getBlueNRGUpdaterVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(version)) + return BLE_UTIL_ACI_ERROR; + + if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_updater_hw_version(version)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t isHWBootloader_Patched(void) +{ + uint8_t status, version; + uint32_t crc, address = 0x10010000; + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); + if (status != BLE_STATUS_SUCCESS) + return 0; + + if (crc == BOOTLOADER_CRC_NOT_PATCHED) + return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_gp_timer.c Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +#include "ble_gp_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function sets a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * @param[in] t A pointer to the timer + * @param[in] interval The interval before the timer expires. + * + */ +void +Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +Timer_Expired(struct timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + tClockTime diff = (Clock_Time() - t->start) + 1; + return t->interval < diff; + +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +tClockTime +Timer_Remaining(struct timer *t) +{ + return t->start + t->interval - Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +#ifdef __DMA_LP__ + +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID) +{ + TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, + (pf_TIMER_TimerCallBack_t) timercb); + TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); + + return (BLE_STATUS_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) +{ + TIMER_Delete(timerID); + + return (BLE_STATUS_SUCCESS); +} + +#endif /* __DMA_LP__ */ +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_list.c Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,119 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_list.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Circular Linked List Implementation. +******************************************************************************** +* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +*******************************************************************************/ + +/****************************************************************************** + * Include Files +******************************************************************************/ +#include <ble_hal_types.h> +#include "ble_list.h" + +/****************************************************************************** + * Function Definitions +******************************************************************************/ +void list_init_head (tListNode * listHead) +{ + listHead->next = listHead; + listHead->prev = listHead; +} + +uint8_t list_is_empty (tListNode * listHead) +{ + return ((listHead->next == listHead)? TRUE:FALSE); +} + +void list_insert_head (tListNode * listHead, tListNode * node) +{ + node->next = listHead->next; + node->prev = listHead; + listHead->next = node; + (node->next)->prev = node; +} + + +void list_insert_tail (tListNode * listHead, tListNode * node) +{ + node->next = listHead; + node->prev = listHead->prev; + listHead->prev = node; + (node->prev)->next = node; +} + + +void list_remove_node (tListNode * node) +{ + (node->prev)->next = node->next; + (node->next)->prev = node->prev; +} + + +void list_remove_head (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->next; + list_remove_node (listHead->next); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_remove_tail (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->prev; + list_remove_node (listHead->prev); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_insert_node_after (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node->next; + node->prev = ref_node; + ref_node->next = node; + (node->next)->prev = node; +} + + +void list_insert_node_before (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node; + node->prev = ref_node->prev; + ref_node->prev = node; + (node->prev)->next = node; +} + + +int list_get_size (tListNode * listHead) +{ + int size = 0; + tListNode * temp = listHead->next; + while (temp != listHead) + { + size++; + temp = temp->next; + } + return (size); +} + +void list_get_next_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->next; +} + + +void list_get_prev_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->prev; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/source/bluenrg-hci/utils/ble_osal.c Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/source/platform/ble_clock.c Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,36 @@ + +#include "ble_clock.h" +#ifdef YOTTA_CFG_MBED_OS + #include "mbed-drivers/wait_api.h" + #include "mbed-drivers/rtc_time.h" +#else + #include "wait_api.h" + #include "rtc_time.h" +#endif + +const uint32_t CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + //Not Used +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return clock(); +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/source/platform/btle.cpp Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/source/platform/stm32_bluenrg_ble.cpp Fri Jun 05 10:49:10 2020 +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/shields/TARGET_ST_BLUENRG/source/utils/ble_payload.cpp Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <ble_payload.h> + +Payload::Payload() { + stringLength = 0; + payloadUnitCount = 0; + payload = NULL; +} + +Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + stringLength = string_ength; + payloadUnitCount = 0; + payload = NULL; + + int index = 0; + while( index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + UnitPayload *obj = new UnitPayload[payloadUnitCount]; + int i=0; + int c=0; + int j,k; + + while(i<payloadUnitCount) + { + obj[i].length=tokenString[c]; + obj[i].id=tokenString[c+1]; + + obj[i].data = new uint8_t[obj[i].length]; + for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) + { + obj[i].data[k]=tokenString[j]; + + } + + c=c+obj[i].length+1; + i++; + + } + payload = obj; +} + +uint8_t Payload::getPayloadUnitCount() { + return payloadUnitCount; +} + +uint8_t Payload::getIDAtIndex(int index) { + return payload[index].get_id(); +} + +uint8_t Payload::getLengthAtIndex(int index) { + return payload[index].get_length(); +} + +uint8_t* Payload::getDataAtIndex(int index) { + return payload[index].get_data(); +} + +int8_t Payload::getInt8AtIndex(int index) { + uint8_t* str = payload[index].get_data(); + int8_t value = (int8_t)str[0]; + return value; +} + +uint16_t Payload::getUint16AtIndex(int index) { + uint16_t* str = (uint16_t*)payload[index].get_data(); + uint16_t value = str[0]; + return value; +} + +uint8_t* Payload::getSerializedAdDataAtIndex(int index) { + uint8_t length = payload[index].get_length(); + uint8_t* data = payload[index].get_data(); + uint8_t id = payload[index].get_id(); + uint8_t *serializedAdData = new uint8_t[length]; + + serializedAdData[0] = id; + for(int i=0; i<length-1; i++) { + serializedAdData[i+1] = data[i]; + } + return serializedAdData; +} + +Payload::~Payload() { + int i = 0; + + if(payload) { + while(i<payloadUnitCount) { + if(payload->data) { + delete[] payload->data; + payload->data = NULL; + } + } + delete[] payload; + payload = NULL; + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shields/TARGET_ST_BLUENRG/source/utils/ble_utils.cpp Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,93 @@ +/* mbed Microcontroller Library +* Copyright (c) 2006-2013 ARM Limited +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "ble_utils.h" + +/**************************************************************************/ +/*! + @brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power + +*/ +/**************************************************************************/ +tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) { + tBleStatus ret = BLE_STATUS_SUCCESS; + + if(dBMLevel==-18) { + EN_HIGH_POWER = 0; + PA_LEVEL = 0; + } + else if(dBMLevel==-15) { + EN_HIGH_POWER = 0; + PA_LEVEL = 1; + } + else if(dBMLevel==-14) { + EN_HIGH_POWER = 1; + PA_LEVEL = 0; + } + else if(dBMLevel==-12) { + EN_HIGH_POWER = 0; + PA_LEVEL = 2; + } + else if(dBMLevel==-11) { + EN_HIGH_POWER = 1; + PA_LEVEL = 1; + } + else if(dBMLevel==-9) { + EN_HIGH_POWER = 0; + PA_LEVEL = 3; + } + else if(dBMLevel==-8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 2; + } + else if(dBMLevel==-6) { + EN_HIGH_POWER = 0; + PA_LEVEL = 4; + } + else if(dBMLevel==-5) { + EN_HIGH_POWER = 1; + PA_LEVEL = 3; + } + else if(dBMLevel==-2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 4; + } + else if(dBMLevel==0) { + EN_HIGH_POWER = 0; + PA_LEVEL = 6; + } + else if(dBMLevel==2) { + EN_HIGH_POWER = 1; + PA_LEVEL = 5; + } + else if(dBMLevel==4) { + EN_HIGH_POWER = 1; + PA_LEVEL = 6; + } + else if(dBMLevel==5) { + EN_HIGH_POWER = 0; + PA_LEVEL = 7; + } + else if(dBMLevel==8) { + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + else { + ret = ERR_INVALID_HCI_CMD_PARAMS; + } + + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/LEDService.h Fri Jun 05 10:49:10 2020 +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/source/main.cpp Fri Jun 05 10:49:10 2020 +0000 @@ -0,0 +1,127 @@ +/* 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(P0_23, 0); +DigitalOut actuatedLED(P0_22, 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() +{ + 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; +}